我想知道对于多对多关系的交叉表有什么更好的设计。
我正在考虑的两种方法是:
CREATE TABLE SomeIntersection
(
IntersectionId UNIQUEIDENTIFIER PRIMARY KEY,
TableAId UNIQUEIDENTIFIER REFERENCES TableA NOT NULL,
TableBId UNIQUEIDENTIFIER REFERENCES TableB NOT NULL,
CONSTRAINT IX_Intersection UNIQUE(TableAId, TableBId )
)
或
CREATE TABLE SomeIntersection
(
TableAId UNIQUEIDENTIFIER REFERENCES TableA NOT NULL,
TableBId UNIQUEIDENTIFIER REFERENCES TableB NOT NULL,
PRIMARY KEY(TableAId, TableBId )
)
一个人对另一个人有好处吗? 编辑2:****请注意:我计划使用Entity Framework为数据库提供API。考虑到这一点,一个解决方案在EF中的效果是否优于另一个?
编辑:在相关的说明中,对于两列引用同一个表的交集表(例如下面的例子),有没有办法让两个字段在记录上不同?
CREATE TABLE SomeIntersection
(
ParentRecord INT REFERENCES TableA NOT NULL,
ChildRecord INT REFERENCES TableA NOT NULL,
PRIMARY KEY(TableAId, TableBId )
)
我想阻止以下
ParentRecord ChildRecord
=================================
1 1 --Cyclical reference!
答案 0 :(得分:13)
这是一个有争议的话题。我更喜欢第一种形式,因为我认为能够通过单个值查找映射行更好,并且喜欢强制执行一个可能 - 愚蠢的一致性,即在每个表中都可以使用单列主键。其他人则认为拥有该专栏是对空间的愚蠢浪费。
我们每隔几个月在新泽西州的一家酒吧见面几轮裸肩拳击。
答案 1 :(得分:10)
如果您的“交叉点”实际上是一个实体,则使用版本-1 ,这意味着:
用户版本-2 如果它是纯粹的N-M关系表。在这种情况下还要确保:
您仍然可以使用另一个单列UNIQUE标识符,但只需:
在这两种情况下,您可能想要创建另一个覆盖2列的INDEX,但是在另一个顺序中,如果您经常从关系的另一侧进行搜索。
答案 2 :(得分:9)
第二个版本对我来说是最好的,它可以避免创建额外的索引。
答案 3 :(得分:4)
您正在构建的内容称为“交叉点”。
我非常清楚地记得我在学校的数据库教授说,交叉关系本身几乎总是一个实体,所以通常值得为它分配空间。这表明前者更“正确”。
那就是说,我个人倾向于选择后者。这真的取决于你是否会直接检索其中一个记录,或者你是否只在加入其中一个原始表时使用该表。
答案 4 :(得分:4)
如果你选择第一个,只需在PK上使用IDENTITY,就不需要浪费空间(磁盘和内存缓存)和UNIQUEIDENTIFIER。
答案 5 :(得分:3)
从开发人员的角度来看,我更喜欢前者。 处理它时更容易编写和测试。
我不需要检查两个密钥来检索唯一记录。
答案 6 :(得分:3)
如果交叉表中没有任何其他字段,它实际上不需要自己的ID,添加一个不会增加任何好处。但是,如果您要将其他字段放入该表中,并且在许多情况下,您应该将其自己的ID作为主键。
当然,经验法则,但你去了。
答案 7 :(得分:3)
回答你的第二个问题......
您只需要添加一个检查约束,如下所示:
CREATE TABLE SomeIntersection
(
ParentRecord INT REFERENCES TableA NOT NULL,
ChildRecord INT REFERENCES TableA NOT NULL,
PRIMARY KEY(TableAId, TableBId),
CHECK (ParentRecord <> ChildRecord)
)
答案 8 :(得分:1)
第一个的好处:
通过单个值查找连接表的功能。这使得一些查找操作在客户端更简单。
一些ORM(NHibernate)还需要每个实体中的id才能使持久性正常工作。
第二个的好处:
更简单的数据模型,无需创建其他索引。
需要更少的内存。
答案 9 :(得分:1)
第二个更好。它将接线盒(交叉盒)限制为不具有同一对的多个外观。如果接线盒中没有其他列,则无论如何都不会查找此表,除非是通过两个外键。
答案 10 :(得分:0)
鉴于TableAId-TableBId组合是唯一的,并且该表仅用于实现多对多关系,我将使用第二个选项。从纯逻辑的角度来看,第一个实现减少到第二个。从结构的角度来看,您的数据库需要维护主键/索引以及对第一个实现的约束,而第二个实例只需要保留主键/索引。