2011-04-26 76 views

回答

2

由于您使用的是Doctrine,请尽量不要在RDBMS级别上考虑太多(至少在大多数情况下)。

如果您有两个具有ManyToMany关系的实体,则应该忘记代理键。事实上,你几乎应该忽略关系表存在的事实。你只需要有两个相关的实体类型。

现在,如果您需要存储有关关系本身的元数据(例如徽章颁发给用户的日期),那么您将超越一个简单的ManyToMany,并且您需要自己为该关系建模 - 通过创建一种新的实体(例如UserBadge)。那个实体当然会有一个id。

您正在使用ORM,请考虑实体,而不是关于表(大部分时间)!

3

我更喜欢在每个表上使用单列自动更新密钥。它使删除和更新更简单。

+0

是吗?如果你想删除或更新记录,说明作者A写了书B,代理人将如何提供帮助?如果没有首先使用author_id和book_id选择代理,您甚至会知道代理的价值是什么? – 2011-04-27 11:42:32

+0

而不是从表中删除where column1 ='abc'AND column2 ='xyz'你从表中删除id = 123. – 2011-04-27 14:03:59

+0

是的,我知道。我的问题是,你怎么知道你想要删除的ID是123,而不是通过你知道的东西 - 作者和书籍来查找该行? – 2011-04-27 14:06:58

5

大部分时间在这样的一个joinn表中,只是将它们设置为一个组合PK就没有问题。

3

您不需要添加代理键。我不会。

1

您严格不需要需要它,但它在SQL控制台上播放时可能非常方便,特别是如果两个标识符都很长并且很难打字。

另一方面,它打破3NF。如果您不小心,最终可能会得到两个包含不同代理键和(book_id, author_id)值的记录。您将有两个索引来确保两个唯一性约束;这会减慢插入和更新。

另外你可能想避免额外的列来提高效率。如果你的表有很多记录,有一个额外的列会使它在内存中的缓存效率降低,并且使用它的连接会更频繁地被磁盘I/O放慢。

+0

嗨,谢谢你的准确答案,我使用Doctrine 2,我不确定我能够使用这些键,但我可能需要添加一个auto-inc键,但是,我已经很多记录(超过2,000,000) – JohnT 2011-04-26 18:02:01

+0

你应该在你的问题中更加突出地提及Doctrine2的使用(也就是说,不仅在标签中),否则你会继续接收错过这个点的答案,就像这样。 – 9000 2011-04-26 18:09:24

+1

添加代理键不违反3NF。无法在(book_id,author_id)上强制执行复合键。 – sqlvogel 2011-04-26 18:34:27

2

这里有两个问题。

您需要对书籍/列组合进行唯一约束以避免重复。即使您使用auto-inc代理键,也必须这样做。第二,现在很多框架不知道如何处理除整数键之外的任何东西,所以你可能还想把它放在整数列上。但在这种情况下,你会需要两者。

4

你从来没有需要一个代理键,因为你总是可以原则上总是使用一些其他的键代替。

在你的问题中,我不认为你的意思是“关系表”,更不用说“关系”。我认为你的意思是“一张带有多个外键的桌子”。具有多个外键的表与其他表并不不同,并且它们的设计原则也不需要不同。选择与其他表格相同的密钥。

相关问题