问题
当我设计数据库结构时,我经常使用可以分配状态的表。例如,对报价的响应 - 例如,此响应表可以具有以下状态:
- 等待 - 响应已创建并等待优惠所有者批准
- 已取消 - 回复已被作者取消
- 已批准 - 响应已获得优惠作者的批准
- 已拒绝 - 响应被要约作者拒绝
- 已过期 - 响应与关联的优惠一起过期
我正在考虑这两种解决方案
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/