首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >数据库表,一个表引用多个无关表。

数据库表,一个表引用多个无关表。
EN

Stack Overflow用户
提问于 2010-10-22 17:15:45
回答 4查看 2.7K关注 0票数 5

在我的搜索中,这个问题在各种论坛上已经出现过几次,但没有一个问题提供了一个简明的解决办法。

如果我有以下表格:

代码语言:javascript
运行
复制
User
+- id
+- username
+- password

Article
+- id
+- title
+- content

为了确定是谁创建了哪些文章,我想加入它们,我只需将user_id一栏添加到中作为参考。或者,我添加了一个中间表来显示谁/何时/什么,例如:

代码语言:javascript
运行
复制
User
+- ...

Article
+- ...

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

这很好,但是我正在开发的系统需要更加动态,因为新的模块可以很容易地被引入和集成。因此,如果现在添加一个Media表,则需要将ChangeHistory拆分为文章和Media,具有:

代码语言:javascript
运行
复制
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”的东西来引用来自它的表。这样,当/如果添加或删除模块时,模型就不会崩溃。

有什么想法吗?提前谢了。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-10-22 18:28:25

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

在我所见过的每一种情况下(还是反模式?)试着做一个通用的“做任何事”的桌子RDBMS最适合处理定义良好的问题区域。如果模块需要保留历史记录,那么该模块应该添加一个历史记录表,以便与表本身保持一致。这也有一个巨大的优势,在未来的道路上,您很可能希望保留不同类型的信息在历史上,这取决于表或模块的历史要保存。如果您有一个泛型历史表,那么这个表就会变得更加困难。

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

代码语言:javascript
运行
复制
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)
)
票数 4
EN

Stack Overflow用户

发布于 2010-10-22 17:25:57

在我看来,你是在找一个向导带你走一条曲折而又荆棘的道路。

我不知道为什么每次得到新的“模块”(我不清楚模块是什么)时都需要添加一个新表,前提是所有模块都可以用相同的列布局来描述。您可以添加一个模块表,然后在文章表中包含一个ModuleId列。

此外,文章可以有多个作者,所以如果您的文章有,您需要一个ArticleAuthors表。在某些圈子里,文章作者的顺序是很重要的。这是他们的贡献的重要性或他们在这个领域的重要性的排名。如果是这样的话,您需要有一个“序号”列来反映作者的立场。

票数 2
EN

Stack Overflow用户

发布于 2010-10-22 18:09:59

好呀

代码语言:javascript
运行
复制
ChangeHistory
+- id
+- content_id
+- content_type
+- user_id
+- action [enum(added, updated, deleted)]
+- datetime
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3999268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档