数据模型:将字段单独 table 与将其作为主 table 中的列
Data model: Having separate table for a field vs having it as a column in the main table
我们有一个场景,我们想要存储 'status'(比如 'user')
我们想对 'user' 状态的允许值施加限制。
所以我们考虑了两种选择:
- 在 'user' table
中将 'status' 作为枚举类型的列
- 为 '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', |
我们有一个场景,我们想要存储 'status'(比如 'user')
我们想对 'user' 状态的允许值施加限制。
所以我们考虑了两种选择:
- 在 'user' table 中将 'status' 作为枚举类型的列
- 为 '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', |