数据模型:将字段单独 table 与将其作为主 table 中的列

Data model: Having separate table for a field vs having it as a column in the main table

我们有一个场景,我们想要存储 'status'(比如 'user')

我们想对 'user' 状态的允许值施加限制。

所以我们考虑了两种选择:

  1. 在 'user' table
  2. 中将 'status' 作为枚举类型的列
  3. 为 'status' 设置一个单独的 table 并在数据库初始化期间填充允许的值,并将其作为 'user' table.[=23 中的外键=]

你能建议哪种方法更好吗?为什么 赞赏是否共享有关最佳实践的参考

枚举不太受欢迎。为状态做一个单独的 table。使用单独的 table 可以轻松更改或添加状态,添加相关数据(如果您将来需要它,只需在您的状态中添加一个新字段 table),轻松获得列表不同的状态。您还可以选择将主 table 中的状态字段设置为 NULL 或默认设置为其他一些值。您可以在其他 table.

中重复使用状态

如果您只有 2 个状态,比如 'active' 和 'inactive',只需在主 table.

中使用 BOOL(或 TINYINT)字段类型

(有很多问答讨论 ENUM vs TINYINT UNSIGNED vs VARCHAR(..)。)

如果选项集不太可能经常更改,那么我投票给 ENUM

  • 行为和感觉就像一个人类可读的字符串。
  • 1 个字节。 (我不会制作一个包含 256 个以上选项的枚举;甚至不会超过一打。)
  • 我会考虑从选项 "unknown" 开始,而不是使该列可为空。这是处理输入拼写错误的粗略方法。

BOOL:

  • 可能会有一些问题;我避开了。
  • 在宏伟的计划中,它通常不会节省足够的 space 重要。
  • 我会考虑使用 SET*INT 来表示大量的布尔标志。

任何基数较差的列 (enum/tinyint/bool) 在 INDEX(status) 等索引中单独使用是没有用的。 OTOH,复合索引可能有用,例如 INDEX(status, create_date).

枚举示例

遇到的一些枚举有两个以上的选项;你判断他们是好是坏:

  Database             Column            ENUM
| mysql              | sql_data_access | enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') |
| mysql              | interval_field  | enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND |
| mysql              | ssl_type        | enum('','ANY','X509','SPECIFIED')                                  |
| performance_schema | TIMER_NAME      | enum('CYCLE','NANOSECOND','MICROSECOND','MILLISECOND','TICK')      |
| common_schema      | hint_type       | enum('step_into','step_over','step_out','run')                     |
| common_schema      | statement_type  | enum('sql','script','script,sql','unknown')                        |

| mworld             | Continent       | enum('Asia','Europe','North America','Africa','Oceania','Antarctic |
| try                | priority        | enum('LOW','NORMAL','HIGH','UBER')                                 |
| alerts             | Stage           | enum('DISCOVER','NOTIFY','ACK','CLEAR')                            |
| todo               | stage           | enum('unk','load','priming','running','stopping')                  |
| zip                | z_type          | enum('STANDARD','UNIQUE','','PO BOX ONLY','Community Post Office', |