【问题标题】:database design pattern: many to many relationship across tables?数据库设计模式:跨表的多对多关系?
【发布时间】:2010-09-15 02:50:34
【问题描述】:

我有以下表格:

部分内容

我想把它们联系起来。


我目前的做法如下表:

我要存放的地方

  • 部分部分
  • 部分内容
  • 内容部分
  • 内容内容


现在,虽然我显然可以通过添加一对字段来指示源是部分还是内容,以及目标是 section 还是 content ,我想知道是否有更清洁的方法可以做到这一点。如果可能的话,只使用一张表来建立关系,我认为这将是最干净的。我还希望该表以某种方式与 SectionContent 表相关,这样我就可以避免手动添加约束,或者在 时删除关系的触发器部分内容被删除...

一如既往地感谢您的输入!

【问题讨论】:

  • 你想做什么?部分和内容有什么区别?我们无法从关系中分辨出来。很有可能,部分和内容(以及另一条评论中提到的“新闻”)都是更一般实体的实例......
  • 它们将是网络内容的类型,例如,一个部分可以是一个类别,如“玩具”,并且一些“内容”取决于每个部分,因此“玩具”部分将具有“ “儿童”部分,“成人”部分......其中“娃娃”是依赖于“儿童”的内容,而“扑克筹码”是依赖于“成人”的内容......这只是网站管理的层次结构

标签: sql sql-server sql-server-2008 database-design relational-database


【解决方案1】:

我会这样设计它:

CREATE TABLE Pairables (
  PairableID INT IDENTITY PRIMARY KEY,
  ...other columns common to both Section and Content...
);

CREATE TABLE Sections (
  SectionID INT PRIMARY KEY,
  ...other columns specific to sections...
  FOREIGN KEY (SectionID) REFERENCES Pairables(PairableID)
);

CREATE TABLE Contents (
  ContentID INT PRIMARY KEY,
  ...other columns specific to contents...
  FOREIGN KEY (ContentID) REFERENCES Pairables(PairableID)
);

CREATE TABLE Pairs (
  PairID     INT NOT NULL,
  PairableId INT NOT NULL,
  IsSource   BIT NOT NULL,
  PRIMARY KEY (PairID, PairableID),
  FOREIGN KEY (PairableID) REFERENCES Pairables(PairableID)
);

您将在Pairs 中为每一对插入两行

现在搜索任一类型的可配对实体都很容易,您可以在同一列中搜索源或目标,您仍然只需要一个多对多交集表。

【讨论】:

  • 这或多或少是我所建议的,只是我认为有一个遗漏。 Pairs 表不应该有两个不同的 FK 列,每个都映射到 PairableId 的吗?
  • @RMorrisey:也许,因为一个是源,另一个是目标。当配对是互惠的“朋友”,没有禁止的顺序时,我使用上面的模式。
【解决方案2】:

是的,有一种更简洁的方法可以做到这一点:

  • 一个表跟踪各节之间的关系并将它们作为外键约束强制执行
  • 一个表跟踪从 Section 到 Content 的关系,并将它们作为外键约束强制执行
  • 一个表跟踪从 Content 到 Section 的关系,并将它们作为外键约束强制执行
  • 一个表跟踪从内容到内容的关系并将它们作为外键约束强制执行

这比具有无法通过外键约束强制执行的重载 ID 的单个表要干净得多。数据建模和领域建模模式从未提及您所描述的模式这一事实应该是您的第一个警钟。第二个警报应该是引擎无法强制执行您设想的约束,您必须专注于触发器。

在一张表中建模四个不同的关系不会给模型带来优雅,它只会增加混淆。关系模型不是 C++:它没有继承,没有多态,没有重载。试图在数据建模中强制实施 OO 思维方式已导致许多优秀的开发人员陷入了无法维护的触发器网格中,这些触发器网格由磁盘上类似于“数据”的位组成。

【讨论】:

  • 你是绝对正确的,但我遇到的问题是,如果我曾经(上帝保佑)想添加第三个表与第三种类型的关系数据(比如“新闻”,那也例如,与网站中的一般部分和内容相关),我将不得不添加 5 个额外的表...... 9 个表来关联三种类型的数据似乎很多,而且呈指数级增长。感谢您的意见!
  • 您添加到模型中的每个表是否都将与所有其他现有表相关联?仅两个表之间有 4 个多对多关系这一事实已经是一个令人担忧的迹象,如果添加新实体类型(新表)会以指数方式增加关系数量(与这些关系是否在一个中强制执行无关)表或两个或 9)让我严重怀疑您的数据模型设计的有效性。
  • 例如,考虑到如果您的模型实际上是 2 种(或 3 种或更多)类型的片段(内容、部分和现在的新闻),那么您实际上只有一个多对多关系表Snippets 和 Snippets 之间的关系,Snippets 和 Content/Section/News 之间的关系可以建模为表继承模式之一,例如martinfowler.com/eaaCatalog/classTableInheritance.html
猜你喜欢
  • 2012-09-30
  • 1970-01-01
  • 1970-01-01
  • 2011-05-01
  • 1970-01-01
  • 2019-09-25
  • 2011-04-13
  • 1970-01-01
相关资源
最近更新 更多