跟踪行的状态时,哪个更快,更优选?

时间:2019-05-14 07:26:55

标签: php mysql performance optimization

例如,假设您有一个包含订单的表,并且该表的一列会跟踪该订单是否待处理/已发货/已拒绝/已批准。保持记录状态的更好方法是哪种?

选项一。在索引列中将状态保留为字符串。

-------------------------------------------------------
| 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| . . .      | . . .      |
-------------------------------------------------------

我认为,第一个比较简单,但是如果表变大,它将变慢,而在这种情况下,第二个将变快。

3 个答案:

答案 0 :(得分:3)

第二种方法更好,因为:

  1. 它将消耗更少的空间
  2. 使用数字搜索也比使用字符串搜索更快
  3. 万一您以后想要将“已批准”更改为“临时批准”,则需要在一个地方进行更改,而整个数据都不能更改
  4. 您还可以执行类似WHERE status > 2的操作,而这对于字符串来说是不可能的

可能还有更多原因,这只是我第一次想到。而且我认为没有理由使用第一个选项。

答案 1 :(得分:0)

对我来说,答案是:这取决于。

如前所述,由于空间消耗,完整性和可扩展性,选项2看起来更好。

但是我坚信YAGNI原则:如果还不需要(例如,如果您不打算添加更多状态,使它们可配置或在未来几年拥有大量数据),可能不需要它,并且完全可以构建选项1。

如果需要,可以在几年内更改数据结构。也许以另一种方式,满足您现在无法预见的需求。

答案 2 :(得分:0)

“更好”在很大程度上取决于意见。您可以定义“更好”的含义-您要针对哪些属性进行优化?

就“更快”而言-关系数据库(包括MySQL)非常擅长联接。如此出色,以至于在大多数情况下,当您使用外键联接时,即使有成千上万的记录,也没有可衡量的性能影响。因此,除非达到Amazon规模,否则我认为选项1不会“更快”。

您可能认为的其他属性“易于维护”。选项1对错误开放,因为您必须确保要知道订单是否“挂起”的每一位代码在查询中都包含正确的文本。一个简单的错字可能意味着您停止向客户发货。您可能需要针对状态之间的转换创建一些适度复杂的业务规则-“不允许订单从拒绝状态转换为已发货状态”,并且您会有很多个输入错误的机会。如果您担心“易于维护”,则选择2或使用枚举可能会更好。

另一个属性可能是“易于扩展”。目前,您的状态没有其他属性,但情况可能并非如此。例如,您可能决定存储订单可能停留在给定状态中的时间量,或者允许角色覆盖状态更改的时间。同样,在这种情况下,选项2可能更易于使用。