如何使用 SQL 管理数据库中的 FIFO 队列?
Posted
技术标签:
【中文标题】如何使用 SQL 管理数据库中的 FIFO 队列?【英文标题】:How can I manage a FIFO-queue in an database with SQL? 【发布时间】:2011-03-01 14:59:15 【问题描述】:我的数据库中有两张表,一张用于In
,一张用于Out
。它们有两列,Quantity
和 Price
。如何编写选择正确价格的 SQL 查询?
例如:如果我有 3 项 in 用于 75,然后 3 项 in 用于 80。那么我有两个 out 用于 75 ,第三个 out 应该是 75 (X),第四个 out 应该是 80 (Y)。
如何编写 X 和 Y 的价格查询?他们应该使用第三行和第四行的价格。例如,有没有办法选择In
-table 中的第三行?我不能使用 auto_increment 作为标识符,即“第三”行,因为这些表也将包含其他项目的帖子。这些行不会被删除,出于责任原因,它们将被保存。
SELECT Price FROM In WHERE ...?
新数据库设计:
+----+
| In |
+----+------+-------+
| Supply_ID | Price |
+-----------+-------+
| 1 | 75 |
| 1 | 75 |
| 1 | 75 |
| 2 | 80 |
| 2 | 80 |
+-----------+-------+
+-----+
| Out |
+-----+-------+-------+
| Delivery_ID | Price |
+-------------+-------+
| 1 | 75 |
| 1 | 75 |
| 2 | X | <- ?
| 3 | Y | <- ?
+-------------+-------+
OLD数据库设计:
+----+
| In |
+----+------+----------+-------+
| Supply_ID | Quantity | Price |
+-----------+----------+-------+
| 1 | 3 | 75 |
| 2 | 3 | 80 |
+-----------+----------+-------+
+-----+
| Out |
+-----+-------+----------+-------+
| Delivery_ID | Quantity | Price |
+-------------+----------+-------+
| 1 | 2 | 75 |
| 2 | 1 | X | <- ?
| 3 | 1 | Y | <- ?
+-------------+----------+-------+
【问题讨论】:
如果 Out 中的第二行 Quantity = 2,您希望返回什么? 我认为这在 SQL 中不容易做到。如果在 2 的第一个“出”之后,有人想要再 2 会发生什么?您必须以某种方式将其拆分为 75 和 80 之一,不是吗? @David M:好点。应该是 75+80= 155。 你怎么知道前2个不是80? @Paul Tomblin:你是对的。也许我必须再考虑一下。也许我必须像问题的底部那样设计它。 【参考方案1】:阅读您说您愿意添加自动增量或日期字段以了解每行的正确位置的 cmets。添加后,我建议在 In 表中再添加一行,称为已处理,当该行添加到表中时,该行会自动设置为 false。任何已复制到 OUT 的行都已将其已处理文件设置为 true。
+----+
| In |
+-----------+-----------+-------+-----------+
| AUtoId | Supply_ID | Price | Processed |
+-----------+-----------+-------+-----------+
| 1 | 1 | 75 | 1 |
| 2 | 1 | 75 | 1 |
| 3 | 1 | 75 | 0 |
| 4 | 2 | 80 | 0 |
| 5 | 2 | 80 | 0 |
+-----------+-----------+-------+---------- +
然后找到下一个要移动到 OUT 的项目,你可以这样做
SELECT TOP 1 Supply_ID, Price
FROM In WHERE Processed = 0
ORDER BY [Your Auto Increment Field or Date]
一旦该行被移至 OUT,那么您只需将该行的已处理字段更新为 true。
【讨论】:
我认为这将是一个很好的设计。我可以使用 Delivery_ID 列代替已处理的列,以获得更好的问责制。谢谢!【参考方案2】:我看不到一个简单的查询对这里有帮助。为了在 SQL 中模拟 FIFO,我会查看三个表,OPERATION、OUT 和 FIFO。 OPERATION 实际上是事务的日志,FIFO 表是 FIFO 状态,OUT 是 FIFO 的响应。
当操作(添加和删除项目)进入 OPERATION 表时,您将使用操作(添加和删除项目)更新 CURRENT,并将对项目“输出”的请求处理到 OUT 表中,从而减少 FIFO 中的值,并在必要时从 FIFO 表中删除记录.
即使这样,我也看不到一个简单的查询来处理整个事情,因为需要查询第一条记录以查看每个操作是否有足够的数量,适当地更新该记录并查询其他记录操作无法完成。我的 SQL 能力水平并没有让我找到一个简单的解决方案,它构成了我的业务逻辑并被提升到那个层次。
【讨论】:
以上是关于如何使用 SQL 管理数据库中的 FIFO 队列?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 DISPATCH_QUEUE_CONCURRENT 和屏障块复制 FIFO 队列?