最佳解决方案:保持实体状态在数据库中

时间:2014-09-18 19:16:05

标签: mysql sql database-design

问题

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

  1. 等待 - 创建响应并等待要约所有者的批准
  2. 已取消 - 其作者已取消回复
  3. 已批准 - 回复已获得 offer
  4. 的作者批准
  5. 被拒绝 - offer
  6. 的作者拒绝了回复
  7. 已过期 - 响应已过期以及相关的商品
  8. 我正在考虑这两个解决方案

    1。溶液

    创建表 response_state 并将其密钥作为外键保存在响应表中

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

    2。溶液

    将已批准/已拒绝/已取消的逻辑值列放入响应并创建视图 view_response_state ,其中包含根据这些列中的值和过期日期的州名称列。

    例如,如果approved为false,则拒绝为false,取消为false,expiration_date<今天,然后国家正在“等待”等。

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

    问题

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

1 个答案:

答案 0 :(得分:2)

在我看来,你需要三张桌子。

一个叫做#34; response_state"。它包含五行,每个响应名称对应一行。如果您需要添加新的响应名称,只需将其插入此表即可。它有列" 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的解决方案,如果有很多响应相互叠加,它对各种竞争条件都具有内在的稳健性。