SQL 个表的规范化

Normalization of SQL tables

我正在为一个项目创建一些 table,我刚刚意识到许多 table 具有相同的结构(Id、名称),但用于不同的事物。我应该在标准化方面走多远?我应该将它们全部构建成一个 table 还是将它们分开以便更好地理解?它如何影响性能?

示例 1:

TableObjectType(用于日志中的对象类型)

Id  Name
1   User
2   MobileDevice
3   SIMcard

TableAction(用于日志中的操作类型)

Id  Name
1   Create
2   Edit
3   Delete

TableStatus(用于设备可能具有的状态)

Id  Name
1   Stock
2   Lost
3   Repair
4   Locked

示例 2:

表常量

Id  Name
1   User
2   MobileDevice
3   SIMcard
4   Create
5   Edit
6   Delete
7   Stock
8   Lost
9   Repair
10  Locked

忽略命名,因为我的 table 有其他名字,但我使用这些是为了澄清。

对所有常量使用一个 table 的缺点是,如果我想稍后添加更多,它们不会真正进入 "groups",但另一方面 SQL 我在使用数据时不应该依赖特定的顺序。

我认为通常最好将 table 分开(这也有助于文档)。在某些特定情况下(您的选择...)您可以 "merge" 所有相似的 table 合并为一个(当然添加其他列,如 TAB_TYPE 以区分它们):这可能在开发应用程序和减少 table 的总数方面给你一些优势(这对你来说是个问题)。
如果都比较小table(记录不多),应该没有性能问题。

仅仅因为 table 具有与另一个相似的结构并不意味着它存储描述相同实体的数据。

有一些明显的原因不符合示例 2。

首先,您可能希望将 ObjectTypeID 列中的值限制为有效对象类型的值。执行此操作的明显方法是创建与 ObjectType table 的外键关系。在 TableConstants 上创建类似的检查会困难得多(在大多数数据库引擎中,您不能以这种方式使用外键约束)。

其次,它使数据库能够自描述 - 检查模式的人会明白 "object type" 在您的业务领域中是一个有意义的概念。这对于长期存在的应用程序或具有大型开发团队的应用程序很重要。

第三,您通常会通过这些引用获得特定的业务逻辑 - 例如,"status" 通常需要一些逻辑来表示 "you can't modify a record in status LOCKED"。这种业务逻辑通常需要存储额外的数据属性——这对于 "Constants" table.

来说是不可能的

第四 - "constants" 必须进行管理。如果你有一个大模式,人们很快就会开始重新使用常量来反映略有不同的概念。您的 "create" 常量可能会应用于 table 存储业务请求以及您的日志事件。这变得几乎难以理解 - 如果业务决定日志事件不参考 "create" 而参考 "write",您的业务交易开始看起来都是错误的。

可以做的是使用 ENUM(许多数据库引擎支持此)来模拟除了存储名称之外没有太多逻辑的属性。这消除了风险 1、2 和 4,但确实意味着您的逻辑在数据库架构中编码 - 添加新对象类型是架构更改,而不是数据插入。