sql - 数据库表,一张表引用多个不相关的表

标签 sql mysql database-design foreign-key-relationship

这个问题在我搜索的各种论坛中出现过几次,但没有一个提供简洁的解决方案。

如果我有下表:

User
+- id
+- username
+- password

Article
+- id
+- title
+- content

我想加入他们以确定谁创建了哪些文章,我可以简单地将列 user_id 添加到 Article 以用作引用。或者,我添加了一个中间表来显示谁/何时/什么,例如:

User
+- ...

Article
+- ...

ChangeHistory
+- id
+- article_id
+- user_id
+- type [enum(insert, update, delete)]
+- datetime

现在这很好,但我正在处理的系统需要更加动态,因为新模块可以很容易地引入和集成。所以现在如果我添加一个 Media 表,我需要在 ArticleMedia 之间拆分 ChangeHistory 具有:

User
+- ...

Article
+- ...

Media
+- id
+- title
+- path

ArticleChangeHistory
+- id
+- article_id
+- user_id
+- type [enum(insert, update, delete)]
+- datetime

MediaChangeHistory
+- id
+- media_id
+- user_id
+- type [enum(insert, update, delete)]
+- datetime

随着许多模块的引入,这很快就会失控。每个模块都需要负责创建和管理它自己的 ChangeHistory 表。

TL;DR:我可以探索哪些实践来创建可以接收对多个其他不相关表的引用的中间表?我可以添加一个 *record_type* 字段,保存记录所属表的名称,但这很丑陋。我需要类似“表 ID”的东西来引用它来自的表。这样,当/如果添加或删除模块,模型就不会崩溃。

有什么想法吗?非常感谢。

最佳答案

根据我的经验,当开发人员试图让他们的系统真正“动态”时,他们实际上是在尝试为他们尚未想到的问题编写代码。这通常是一条糟糕的道路。一个模块包含两个表而不是一个表真的有这么多额外的工作吗?

在我所见过的试图制作一个通用的“做所有事情”的表格的模式(或反模式?)的每一个案例中,它都失败了。 RDBMS 最适用于明确定义的问题领域。如果模块需要保留历史,那么模块应该添加一个历史表来与表本身一起使用。这也有一个巨大的优势,因为您可能希望在历史记录中保留不同类型的信息,具体取决于保留历史记录的表或模块。如果您有一个通用的历史表,那将变得更加困难。

现在,如果您只想捕获最后一个用户更新或插入特定项目(表行)并且可能在多个表中,那么您可以使用继承模式,其中您有一个父表和多个子表.例如:

CREATE TABLE Audited_Items
(
    id    INT    NOT NULL    IDENTITY,
    CONSTRAINT PK_Audited_Items PRIMARY KEY CLUSTERED (id)
)
CREATE TABLE Articles
(
    id    INT            NOT NULL,
    [Article specific columns]
    CONSTRAINT PK_Articles PRIMARY KEY CLUSTERED (id),
    CONSTRAINT FK_Articles_Audited_Items FOREIGN KEY (id) REFERENCES Audited_Items (id)
)
CREATE TABLE Media
(
    id    INT            NOT NULL,
    [Media specific columns]
    CONSTRAINT PK_Media PRIMARY KEY CLUSTERED (id),
    CONSTRAINT FK_Media_Audited_Items FOREIGN KEY (id) REFERENCES Audited_Items (id)
)
CREATE TABLE Audit_Trail
(
    audited_item_id    INT         NOT NULL,
    audit_datetime     DATETIME    NOT NULL,
    user_id            INT         NOT NULL,
    [audit columns]
    CONSTRAINT PK_Audit_Trail PRIMARY KEY CLUSTERED (audited_item_id, audit_datetime),
    CONSTRAINT FK_Audit_Trail_Audited_Items FOREIGN KEY (audited_item_id) REFERENCES Audited_Items (id)
)

关于sql - 数据库表,一张表引用多个不相关的表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3999268/

相关文章:

mysql - 计算mysql列中的行数

ASP.NET Web 应用程序

php - 如何在laravel 5.4中仅获取created_at日期而不是时间

mysql - 如何搭建SQL测试环境?

c# - 如何从数据库重新加载相同的值

mysql - 如何在同一查询中将 group by 与左连接和内连接一起使用?

MySQL:几位家长从一张表中识别出他们的 child

MySQL:A列和B列累计和到B列

SQL - 选择在给定日期之前找到的第一条记录

mysql - 我没有得到以下 sql 批处理文件的输出文件