mysql - : Keeping state of entity in database的最优解

标签 mysql sql database-design

问题

当我设计数据库结构时,我经常使用可以分配状态的表。例如,对报价响应 - 例如,此响应表可以具有以下状态:

  1. 等待 - 响应已创建并等待优惠所有者批准
  2. 已取消 - 回复已被作者取消
  3. 已批准 - 响应已获得优惠作者的批准
  4. 已拒绝 - 响应被要约作者拒绝
  5. 已过期 - 响应与关联的优惠一起过期

我正在考虑这两种解决方案

1。解决方案

创建表response_state并将其键作为外键保留在response表中

  • 优点:
    • 所有状态都集中在一张表中
    • 可以轻松添加新状态
  • 缺点:
    • response_state 外键值与其他响应列的同步是必要的。例如,对于过期 - 当到达过期日时,状态必须更改为“过期”。

2。解决方案

将批准/拒绝/取消的逻辑值列放入响应中,并创建 View view_response_state,该 View 将包含一个列,该列的状态名称取决于这些列中的值和到期日期。

例如,如果批准为假,拒绝为假,取消为假,并且expiration_date <今天,则状态为“等待”等。

  • 优点:
    • 无需同步,所有数据都在数据库中保存一次
  • 缺点:
    • 当我想添加新状态时,我必须更改表response并为view_response_state提供识别此类状态的逻辑

问题

我的问题是,您会选择哪种方法?或者有更好的方法吗?

最佳答案

我认为您需要三个表。

其中一个称为“response_state”。它包含五行,每一行代表您的每个响应名称。如果您需要添加新的响应名称,只需将其 INSERT 到此表中即可。它具有“response_state_id”列。像这样的小表通常称为代码列表表。

还有一个叫“offer”。它将包含一个 Offer_id 以及有关优惠所需的其他信息。

第三个是“回应”。它包含以下列。

response_id          pk, autoincrement
offer_id             fk to offer table
response_state_id    fk to response_state table
response_timestamp
(other columns relating to the response as needed)

该表的工作原理如下:只要响应的状态发生变化,您就可以向该表插入一行以显示新状态。你永远不会更新这些行。您可以在已完成交易的清除过程中删除旧交易。

当您需要查找报价的当前状态时,您可以发出这样的查询。它仅从表中提取对每个优惠的最新响应

SELECT r.offer_id, r.response_state_id, rs.response_state_name
  FROM response AS r
  JOIN response_state AS rs ON r.response_state_id = rs.response_state_id
  JOIN (
          SELECT MAX(response_id) as latest_id,
                 offer_id
            FROM resp
           GROUP BY offer_id
        ) AS recent ON r.response_id = resp.latest_id

这是处理此问题的一种非常酷的方法,因为它保留了对每个报价的响应历史记录。因为它是一个仅限 INSERT 的解决方案,所以如果大量响应相互重叠,它本质上对各种竞争条件都具有鲁棒性。

关于mysql - : Keeping state of entity in database的最优解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25920667/

相关文章:

mysql - NodeJS、MySQL - JSON Stringify - 高级查询

MySQL 错误代码 : 1205. 内部连接更新期间锁定等待超时

php - 如何在不删除行或记录的情况下重命名和删除 mysql 列名?

c# - 如何使用 SqlDataAdapter 从数据集中存储的 sql 过程中获取数据?

php - 我如何修复子查询返回多于 1 行的错误

php - 使用特定搜索条件将内容插入 MYSQL 表列

php - Mysql当前id

objective-c - 什么时候应该将 CoreData 中的 transient 属性包含在对象模型中?

entity-framework - 具有各种用户角色的数据库设计和 EF 模型

database-design - Firebird 中主键的最大大小是多少?