【问题标题】:How to store status of rows in MySQL according formalization rules?如何根据形式化规则在 MySQL 中存储行的状态?
【发布时间】:2022-01-08 16:00:52
【问题描述】:

我有一张桌子order_executors

id | order_id | user_id | status

其中order_iduser_id 是外部键。

status 列表示行的状态。它接受0, 1, 2:

0 - default
1 - accepted
2 - canceled

所以,我在以下情况下发现了违反一致性:

id | order_id | user_id | status
1    1          1         1
2    1          1         2

在上述情况下,我看到第一个用户接受了一行status = 1,然后取消了这个status = 2

因此,当业务逻辑通过查询:SELECT * from order_executors WHERE order_id = 1 AND status = 1 检索数据时,尽管用户已取消此订单,但它仍然有效。

我可以使用SELECT * from order_executors WHERE order_id = 1 AND status = 1 AND status !== 2 解决这个问题。

没错,我可以使用UPDATE 而不是INSERT 来存储status 的当前状态。 但在这种情况下,我丢失了order_executors.status 的历史记录。

如何解决这个设计问题?

我的想法是创建一个新表order_executors_history来存储状态变化:

id | user_id | order_id | status

order_executors 内部使用 UPDATE 命令存储当前状态。

【问题讨论】:

  • 所以您是说您想继续插入更改以便正确跟踪它们?
  • 是的,因为我现在应该知道为什么用户首先接受了订单然后取消了它
  • 不得不说,我会把订单的状态放到订单里面。因为它在任何时候只能有一种状态。如果你想创建一个变更历史,那很好,但要分开
  • 最好将状态存储在order 表中。那么,也许可以在状态附近的order 表中添加executor_id 以了解谁接受了订单?如果订单有一些位置并且它们可以被一些执行者接受怎么办?
  • 就像我说的,订单在任何时候只能有一个状态。如果您想保留订单更改历史记录,请以 id | order_id | user_id | status | created_at (datetime) 为例

标签: mysql mariadb mariadb-10.4


【解决方案1】:

你已经给出了解决方案。

只需更新表 order_executors 上的状态(或删除并插入新行),每个 order_id | 只保留一行user_id 键;

创建另一个表 order_executors_history,当您在表 order_executors 上插入/更新时,您应该插入 order_executors_history

两个表具有相同的结构。 您将在 order_executors_history 表中拥有已按您的 ID 排序的状态。

【讨论】:

    【解决方案2】:

    我更喜欢将历史记录保存在另一个表中,其中有一列指示更改的日期和时间。

    但如果您想将它们保存在同一个表中,我认为您可以添加一个类型为 int(11) 且默认值为“unix_timestamp(current_timestamp())”的列。则可以通过选择timestamp_field的最大值或“where子句”后的查询结果降序排列查询最后的订单状态,限制为一行。

    【讨论】:

      猜你喜欢
      • 2012-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-19
      • 1970-01-01
      • 2019-11-19
      相关资源
      最近更新 更多