【问题标题】:Which is faster and more preferred when keeping track of a row's status? [closed]在跟踪一行的状态时,哪个更快、更受欢迎? [关闭]
【发布时间】:2019-05-14 07:26:54
【问题描述】:

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

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

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

在我看来,第一个更简单,但如果表变得很大,它会变慢,而在这种情况下,第二个会更快。

【问题讨论】:

  • 还有枚举。但是,什么更快,什么操作并没有那么明确。
  • 考虑到表的大小会随着时间的推移而增长。使用连接获取数据将花费更多时间。对我来说,这是第一个选择。
  • 如果您对脏数据感到满意,请选择选项 1,如果您更愿意为选项 2 保持紧张状态。(无论如何,外键检查并不那么昂贵)而且我会保留订单和订单详情的所有更改...
  • 我不会将其发布为答案,因为不可避免的大量反对票,但 MySQL ENUM 类型实际上非常适合这个特定的应用程序,并且会节省空间和时间损失JOIN.
  • 就性能而言,它的内容不多,但我们这些珍视数据完整性的人会选择 2(甚至超过 ENUM)。

标签: php mysql performance optimization


【解决方案1】:

选项二更好,因为:

  1. 它将占用更少的空间
  2. 使用数字搜索也比使用字符串更快
  3. 如果您稍后想要将“已批准”更改为“临时批准”,则需要在一处进行更改,而不是在整个数据中进行更改
  4. 您还可以执行WHERE status > 2 之类的操作,这对于字符串是不可能的

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

【讨论】:

    【解决方案2】:

    对我来说,答案是:视情况而定。

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

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

    如果需要,几年后改变数据结构是可以的。也许以不同的方式来满足您现在无法预见的需求。

    【讨论】:

      【解决方案3】:

      “更好”高度依赖于意见。您可以定义“更好”的含义——您想要优化哪些属性?

      就“更快”而言——关系数据库(包括 MySQL)非常非常擅长连接。太好了,在大多数情况下,当您加入外键时,即使有数千万或数亿条记录,也不会产生可衡量的性能影响。因此,除非您达到亚马逊规模,否则我认为选项 1 不会“更快”。

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

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

      【讨论】:

        猜你喜欢
        • 2011-09-18
        • 2011-03-08
        • 1970-01-01
        • 2023-03-29
        • 2018-02-25
        • 2015-10-31
        • 2011-07-10
        • 2023-03-13
        • 2010-11-25
        相关资源
        最近更新 更多