如何使用 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。它们有两列,QuantityPrice。如何编写选择正确价格的 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 队列?

如何在多线程环境下实现FIFO队列?

如何调试并查看随着时间的推移存储到线程间通信插件的 FIFO 队列中的内容?

Java 实现 FIFO 缓存算法

linux中的pipe和fifo的区别

什么是FIFO