我正在观看一个截屏视频,作者说在连接表上有一个主键是不好的,但没有解释原因。
示例中的连接表在Rails迁移中定义了两个列,并且作者为每个列添加了索引但没有主键。
为什么在这个例子中有一个主键是不好的?
create_table :categories_posts, :id => false do |t|
t.column :category_id, :integer, :null => false
t.column :post_id, :integer, :null => false
end
add_index :categories_posts, :category_id
add_index :categories_posts, :post_id
编辑:正如我在Cletus中所提到的,即使对于连接表,我也能理解自动编号字段作为主键的潜在用途。但是,在上面列出的示例中,作者明确避免在“create table”语句中使用语法“:id => false”创建自动编号字段。通常,Rails会自动将一个auto-number id字段添加到像这样的迁移中创建的表中,这将成为主键。但是对于这个连接表,作者专门阻止了它。我不确定他为什么决定采用这种方法。
答案 0 :(得分:46)
一些注意事项:
答案 1 :(得分:3)
DBA会告诉您,在这种情况下,主键实际上是两个FK列的组合。由于Rails / ActiveRecord与复合PK不兼容(默认情况下,至少),这可能是原因。
答案 2 :(得分:3)
外键的组合可以是主键(称为复合主键)。我个人赞成使用技术主键而不是(自动编号字段,序列等)。为什么?好吧,它使 更容易识别记录,如果您要删除它,可能需要这样做。
考虑一下:如果你要展示一个包含所有链接的网页,那么拥有一个识别记录的主键可以更容易。
答案 3 :(得分:3)
基本上因为没有必要。两个外键字段的组合足以唯一地标识任何行。
但这仅仅说明为什么它不是一个好主意......但为什么它会是一个坏主意呢?
考虑添加标识列的开销。该表占用的磁盘空间增加了50%。指数情况更糟糕。使用标识字段,您必须保持标识计数以及第二个索引。您将使磁盘空间增加三倍,并使每个插件上需要执行的工作增加三倍。唯一的优点是DELETE命令中的WHERE子句略短。
另一方面,如果复合键字段是整个表,则索引可以是表。
答案 4 :(得分:3)
不要在任何表上使用主键,这是一个坏主意(如果DBMS是关系DBMS - 或SQL DBMS)。主键是数据库完整性的关键部分。
我想如果你不介意你的数据库不准确并且经常提供不正确的答案,那么你可以没有......但是大多数人都希望从他们的DBMS得到准确的答案,对于这些人来说,主键是至关重要的。
答案 5 :(得分:2)
首先放置最具选择性的列只应与INDEX声明相关。在KEY声明中,它应该无关紧要(因为正如已经正确指出的那样,KEY是一个SET,并且在一个集合中,顺序无关紧要 - 集合{a1,a2}与{a2的集合相同中,a1})。
如果DBMS产品使得KEY声明中的属性排序有所不同,那么该DBMS产品无法正确区分数据库的逻辑设计(您进行KEY声明的部分)和数据库的物理设计(您进行INDEX声明的部分)。
答案 6 :(得分:2)
我想评论以下评论:“说零或更多是不正确的。”
我想说的是,添加此评论的文本根本不包含“零或更多”的文本,因此我想评论的评论的作者批评其他人没有做过的事情。说。
我还想评论说不正确说“零或更多”是不正确的。今天在少数仍然懒得研究该理论细节的人中众所周知的关系理论实际上需要一个没有属性的密钥的可能性。
但是,当我按下“评论”按钮时,系统回应我评论需要50分(或某些此类)的声誉评分。
一个悲惨的例子说明世界似乎忘记了科学不是民主,而在科学中,真理不是由碰巧成为大多数的人决定的,也不是由碰巧拥有“足够声誉”的人决定的。 / p>
答案 7 :(得分:1)
拥有单一PK的优点
有一个PK的缺点
备注强>