我一直在尝试对特定网站进行网页抓取并将结果存储在数据库中。我对数据的原始假设允许一个模式,我可以使用相当合理的复合主键(通常只包含2或3个字段),但随着时间的推移,我意识到我对数据的原始假设是错误的,而我的主键不是就像我想的那样独特,所以我慢慢地扩展它们以包含越来越多的领域。事实上,我最近开始相信他们的数据库没有任何限制。
就在今天,我终于扩展了我的一个表的主键,以包含该表中的每个字段,我认为现在是一个好时机问:添加自动递增列是否更好?只是一个唯一的ID或只是在整个表上留下一个复合主键?
答案 0 :(得分:4)
使用一个主键比使用所有字段作为主键更好。
首先,您的工具将更容易识别它。我敢肯定有六个左右的其他原因,但这对我来说似乎不费吹灰之力。
答案 1 :(得分:3)
一直是代理键 - 它们更容易使用。
然后,我一直在玩Entity Framework,我的观点可能会因此蒙上阴影。
答案 2 :(得分:2)
我唯一使用复合键的时候是链接表中的两个整数字段,用于多对多关系。使用代理键,然后在您放入复合键的字段中放置一个唯一索引。这样可以节省子表的空间,提高整数连接的速度(除非我实际上要使用复制,否则我不会使用GUID)并且保留了自然键的唯一性。
答案 3 :(得分:1)
@Jack - 如果您从未知道或发现自己添加太多复合材料来制作主键只发现每个列使实际行唯一,那么您对数据库的创建方式知之甚少。我同意你的意见,只是添加一个递增的自动PK作为解决方案。
答案 4 :(得分:0)
获得大型复合键的唯一性和合成键的便利性的一种方法是使用所有字段的值的安全散列。我个人将SHA1所有字段的内容,然后BASE64或HEX编码,并将其用作我的密钥。您可以获得使用单个列进行处理的好处,以及通过散列所有字段来判断数据是否已存在于数据库中的功能,并且只需对主键执行简单的SELECT以查看它是否已存在。 / p>
答案 5 :(得分:0)
拥有大型复合键的原因是确保唯一性。当您需要外键时,使用单个代理键可以提供更多便利,但是您可能会无意中在不同行中使用不同的序列号查找相同的数据。
您可以通过使用串行自动递增代理键来获得两者的好处(无需自己散列所有属性),并对将包含在大型复合键中的属性单独强加唯一性约束。
CREATE TABLE example (
surrogate_key SERIAL PRIMARY KEY,
this VARCHAR(5) NOT NULL,
should INT NOT NULL,
all BOOLEAN NOT NULL,
be VARCHAR(2) NOT NULL,
different VARCHAR(3) NOT NULL,
UNIQUE (this, should, all, be, different)
);