我在看一个视频,作者说在连接表上有主键是不好的,但没有解释原因.

示例中的连接表在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

EDIT: As I mentioned to Cletus, I can understand the potential usefulness of an auto number field as a primary key even for a join table. However in the example I listed above, the author explicitly avoids creating an auto number field with the syntax ":id => false" in the "create table" statement. Normally Rails would automatically add an auto-number id field to a table created in a migration like this and this would become the primary key. But for this join table, the author specifically prevented it. I wasn't sure why he decided to follow this approach.

推荐答案

一些注意事项:

  1. CATEGORY_ID和POST_ID的组合本身是唯一的,因此额外的ID列是冗余和浪费的
  2. "主键不好用"这句话在屏幕上是不正确的.您仍然有一个主键——它只是由两列组成(例如,CREATE TABLE foo(cid,pid,Primary Key(cid,pid)).对于习惯于在任何地方附加ID值的人来说,这可能看起来很奇怪,但在关系理论中,这是非常正确和自然的;screencast作者最好说"把一个名为'ID'的隐式整数属性作为主键不好".
  3. 拥有额外的列是多余的,因为无论如何您都会将唯一索引放在CATEGORY_ID和POST_ID的组合上,以确保不会插入重复行
  4. 最后,尽管常见的命名方法是将其称为"组合键",但这也是多余的.关系理论中的术语"键"实际上是唯一标识行的零个或多个属性的集合,因此可以说主键是ategory_id,post_id
  5. 将 Select 性最强的列放在主键声明的第一位.关于b(+/*)树的构造的讨论超出了本答案的范围(对于一些较低级别的讨论,请参阅:http://www.akadia.com/services/ora_index_selectivity.html),但是在您的示例中,您可能希望它位于post_id、ategory_id上,因为post_id在表中出现的频率会更低,从而使索引更有用.当然,由于表很小,而索引本质上是数据行,所以这并不是很重要.这将是在更广泛的情况下,表是更宽的.

Database相关问答推荐

包含接受Cassandra中多个数据的语句

我应该使用哪种数据库模型在运行时动态修改实体/属性?

sql-dump 有什么用?

PostgreSQL 嵌套 INSERTs / WITHs 用于外键插入

如何以编程方式在 C# 中创建 Microsoft Access 数据库?

如何使用 SELECT WHERE IN() 保持订单?

SQL查询7天前的数据

Oracle在哪些情况下会自动创建索引?

JavaScript 布尔搜索查询生成器接口库?

customer客户表的数据库 struct ,每个客户有很多订单,每个订单有很多商品

使用 typeORM 搜索早于日期的数据

触发器、断言和判断之间有什么区别?

如何在磁盘上布局 B-Tree 数据?

JPA:处理 OptimisticLockException 的模式

存储并仍然索引加密客户数据的最佳方式是什么?

从 postgresql 转储文件填充 MySQL 数据库

数据完整性和数据一致性之间有什么区别吗?

对于 N:M 关系,在 MongoDB 中推荐的级联删除等效项是什么?

Guice、JDBC 和管理数据库连接

为什么 Rails 迁移在应用程序中定义外键而不在数据库中定义外键?