例如,假设您有一个包含订单的表,并且该表的一列会跟踪该订单是否待处理/已发货/已拒绝/已批准。保持记录状态的更好方法是哪种?
选项一。在索引列中将状态保留为字符串。
-------------------------------------------------------
| id | customer_id | status | created_at | shipped_at |
-------------------------------------------------------
| 1 | 1| pending| . . . | . . . |
-------------------------------------------------------
或 选项二。有一个单独的表,其中包含可能的状态,并且状态列是一个外键,该外键指向包含状态的该表。
Table: Statuses
----------------
| id | name |
----------------
| 1 | pending |
----------------
| 2 | approved|
----------------
| 3 | denied |
----------------
| 4 | shipped |
----------------
Table: Orders
-------------------------------------------------------
| id | customer_id | status | created_at | shipped_at |
-------------------------------------------------------
| 1 | 1| 1| . . . | . . . |
-------------------------------------------------------
我认为,第一个比较简单,但是如果表变大,它将变慢,而在这种情况下,第二个将变快。
答案 0 :(得分:3)
第二种方法更好,因为:
WHERE status > 2
的操作,而这对于字符串来说是不可能的可能还有更多原因,这只是我第一次想到。而且我认为没有理由使用第一个选项。
答案 1 :(得分:0)
对我来说,答案是:这取决于。
如前所述,由于空间消耗,完整性和可扩展性,选项2看起来更好。
但是我坚信YAGNI原则:如果还不需要(例如,如果您不打算添加更多状态,使它们可配置或在未来几年拥有大量数据),可能不需要它,并且完全可以构建选项1。
如果需要,可以在几年内更改数据结构。也许以另一种方式,满足您现在无法预见的需求。
答案 2 :(得分:0)
“更好”在很大程度上取决于意见。您可以定义“更好”的含义-您要针对哪些属性进行优化?
就“更快”而言-关系数据库(包括MySQL)非常擅长联接。如此出色,以至于在大多数情况下,当您使用外键联接时,即使有成千上万的记录,也没有可衡量的性能影响。因此,除非达到Amazon规模,否则我认为选项1不会“更快”。
您可能认为的其他属性“易于维护”。选项1对错误开放,因为您必须确保要知道订单是否“挂起”的每一位代码在查询中都包含正确的文本。一个简单的错字可能意味着您停止向客户发货。您可能需要针对状态之间的转换创建一些适度复杂的业务规则-“不允许订单从拒绝状态转换为已发货状态”,并且您会有很多个输入错误的机会。如果您担心“易于维护”,则选择2或使用枚举可能会更好。
另一个属性可能是“易于扩展”。目前,您的状态没有其他属性,但情况可能并非如此。例如,您可能决定存储订单可能停留在给定状态中的时间量,或者允许角色覆盖状态更改的时间。同样,在这种情况下,选项2可能更易于使用。