1

products我正在开发一个库存控制数据库,并希望知道在stocks实体之间建立关系的最佳方式是什么。

下面哪个是合适的?如果没有,请让我知道为什么以及您的建议是什么。

提前致谢

产品 - 股票

基于以上实体:

  • 如果我有1:1关系,看起来我必须通过用UPDATE语句更新行来减少同一行的库存量。

  • 如果我有1:n关系,看起来我必须在INSERT声明中添加一个更新了库存数量的新行。

要点

  • 将有并发用户来操纵库存,例如增加和/或减少,因此[ACID][1]很重要。

  • Stock amount是非负值。

4

2 回答 2

2

取决于您要完成的工作。

如果您需要一个简单的数字来描述产品的可用数量,只需将其作为字段存储在产品表中即可。在单个语句中更新它是原子的:

UPDATE PRODUCT
SET AMOUNT = AMOUNT + <change>
WHERE PRODUCT_ID = <whatever>

或者,您可以执行以下操作:

START TRANSACTION;

SELECT AMOUNT
FROM PRODUCT
WHERE PRODUCT_ID = <whatever>
FOR UPDATE;

(Calculate new amount.)

UPDATE PRODUCT
SET AMOUNT = <new amount>
WHERE PRODUCT_ID = <whatever>;

COMMIT;

请注意 FOR UPDATE 锁定行直到 COMMIT 并防止在并发环境中可能出现的异常。

如果没有 FOR UPDATE,仅仅常规的 ACID 保证是不够的。例如:

  • 事务A选择当前的 AMOUNT,假设它是 5。
  • 事务B选择当前的 AMOUNT,它仍然是 5,因为还没有其他事务提交任何更改。
  • 交易A将金额加 2,结果为 7。
  • 交易B将金额加 3,结果为 8。
  • 事务A将该行更新为 7 并提交。
  • 事务B将该行更新为 8 并提交。

突然,表格中的结果 AMOUNT 为 5 + 3 = 8,即使它本应为 5 + 2 + 3 = 10。其中一个更改丢失了 - 最后提交的人获胜。


如果您需要产品数量的历史记录,或者需要跟踪产品的单个“实例”,那么是的,您需要一个 1:N 关系中的单独表,这在并发环境中可能有自己的锁定挑战。


库存量为非负值。

不幸的是,MySQL 不强制执行 CHECK 约束,但对于这种特定情况,您可以简单地使用一种UNSIGNED数据类型。

于 2013-01-29T11:47:22.047 回答
1

depends针对no. of users updating/inserting rows特定产品,depends on以及您的系统可以承受的内存开销或性能

在更新
mysql - update needs write lock
因此,性能消耗:对于许多用户而言,系统

在插入
内存消耗方面会比较慢 :例如,对于 100 个用户,100 行可能需要更多更新 100 行。

我想1:1 relation ship is better是因为
如果你要给1:n关系,那么,

增加库存:

-you 'll add new row .
-so for total stock 
       - you have to add all the subsequent rows,if new value you are inserting 
         is only the incremented amt 
       - or if it is the total increased amt the previous rows would not have
         any significance.

对于减少库存,相同,

-if the total decrement amt you are inserting then the previous data has 
 no significance,
-but if only decrement value is there , so for every user you have to put 
 a check over the total stock which you would get from many rows.
于 2013-01-29T11:45:05.473 回答