php - 为 'item' 表创建一个(复合)主键,其中增量 'item_id' 根据 'order_id' 外键重置

标签 php mysql sql database-design

<分区>

老师要我们讨论如何实现全局业务收据数据库的'line_item'表。 他希望我们讨论这种“行项目”表的主要(复合?)键。如果我们的全局业务每分钟打印数千张收据(包含数百件元素),那么我们需要考虑多少达到 line_item_id 的 INT 上限的可能性?有没有更有效的方法来处理 line_item id?

“注意:编号中的间隙(通常由删除引起)是可以的。还要寻找可能的竞争条件。”

考虑一下:您添加了 3 张收据,每张收据包含 3 件商品。您删除了第三张收据的第二项。然后在第三张收据中添加一个新项目。

所以我想象这样的事情开始:(收据 #1 和 #3 在添加/删除练习之前最初是相同的。注意 #3 上的编号。)

|  receipt_id (FK)  |     line_id (INT)    |  line_text (TINYTEXT)  |
---------------------------------------------------------------------
|         1         |           1          |  'Apple'               |
|         1         |           2          |  'Banana'              |
|         1         |           3          |  'Coconut'             |
---------------------------------------------------------------------
|         2         |           1          |  'Apple'               |
|         2         |           2          |  'Apple'               |
|         2         |           3          |  'Apple'               |
---------------------------------------------------------------------
|         3         |           1          |  'Apple'               |
|         3         |           3          |  'Coconut'             |
|         3         |           4          |  'Dates'               |
---------------------------------------------------------------------

我们一直在学习 SQL 和 PHP(如果这很重要,innoDB 中的 mySQLi。) 不过我觉得这可能仅用 SQL 就可以完成,对吧?

看来我应该使用第二列中的 MAX() 函数来制作复合主键,以避免担心达到上限 INT 阈值。

我正在尝试编造一个 MySQL INSERT,它将对收据行的编号进行动态处理,例如:

INSERT INTO line_item (3, VALUES MAX(receipt_line)+1, 'Dates')

最后他有其他想法,例如:“如果您现在在第二张收据的末尾删除并添加一个项目怎么办?”

我想这些是他正在寻找的操作:

-- Delete the last line of the second receipt
DELETE FROM line_item WHERE receipt_id=2 AND line_id=MAX(line_id)

-- Add a new line to the second receipt.
INSERT INTO line_item VALUES ( 2, MAX(line_id)+1, 'Watermelon')

我期望这样的结果:

|  receipt_id (FK)  |     line_id (INT)    |  line_text (TINYTEXT)  |
---------------------------------------------------------------------
|         1         |           1          |  'Apple'               |
|         1         |           2          |  'Banana'              |
|         1         |           3          |  'Coconut'             |
---------------------------------------------------------------------
|         2         |           1          |  'Apple'               |
|         2         |           2          |  'Apple'               |
|         2         |           3          |  'Watermelon'          |
---------------------------------------------------------------------
|         3         |           1          |  'Apple'               |
|         3         |           3          |  'Coconut'             |
|         3         |           4          |  'Dates'               |
---------------------------------------------------------------------

但是我得到了一堆错误和奇怪的结果。

我是否需要使用 PHP 来计算 line_id?我错过了什么?

最佳答案

您不能只使用 MAX(line_id),因为它会在所有收据中获得 line_id 的最大值。您想要的是一张特定收据中的最大 line_id。类似于 SELECT MAX(line_id) FROM line_item WHERE receipt_id = 3

您可以使用子选择将其构建到单个 SQL 查询中以获取新的 line_id 值。但我认为用 PHP 会更好。首先确定新的 line_id,然后插入新的订单项。在两个单独的查询中。

还要考虑您的收据应用程序将如何删除订单项。如果我想删除收据 2 中的第二个 Apple 行项目,我需要知道它是 line_id。因此,您的应用程序需要知道它添加的新项目的 line_id

关于php - 为 'item' 表创建一个(复合)主键,其中增量 'item_id' 根据 'order_id' 外键重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54189814/

相关文章:

php - 在 Laravel 中检索数据格式

javascript - 如何保存已编码为javascript变量的php数据

mysql - 需要有关 MySql 查询的帮助

sql - SQL Server 中的文本/字符串分析

sql - 计算查询中的行数作为列

php - 如何知道网址是音频还是视频?

php - 关于 curl 的小问题?

php - 更改 php.ini 中的 max_upload_filesize 但在 phpMyAdmin 中保持不变

python - Django MySQL 按时区分组

php - mySQL 连接 3 个没有关系的表并从中获取最后的数据