我是数据库的新手,也是来自 Java 的数据抽象的新手。为了自学,我正在开发一个在线应用程序,除其他外,该应用程序允许用户加入多个组。
勾勒出数据库,看来我必须要有类似“成员(member)”表的东西:
UserID|GroupID
------|-------
1 | 1
1 | 2
2 | 1
2 | 3
2 | 5
我对此有点担心,因为它只有两个外键,而且只用于链接两个对象。这是这种关系的标准做法吗?如果不是,首选方法是什么?
同样,我对数据库还很陌生。我的书中没有提到这种情况,所以如果有一些关键字反射(reflect)了我忽略的这个功能......
谢谢。
最佳答案
这是表示多对多关系的标准方式,被称为“联结表”(或“链接表”)。
您已经注意到 UserID 和 GroupID 都是引用其他表的外键。但是当涉及到键(不是外键)时,您有几种选择:
- 在
{UserID, GroupID}
上创建一个复合(主)键。除了确保同一用户不能多次连接到同一组之外,它还有助于高效搜索给定用户的组。由于 UserID 位于索引的前沿(DBMS 在键下自动创建),因此与同一 UserID 关联的所有 GroupID 值都在索引内的连续范围内 B-tree ,因此 DBMS 可以通过简单的索引范围扫描来获取给定用户的组。 - 在
{GroupID, UserID}
上创建一个复合(主)键。相同的字段,相反的顺序。这有助于快速获取给定组的用户(即与 (1) 相比在相反的“方向”查询)。 - 在
{UserID, GroupID}
上创建键 和 在{GroupID, UserID}
上建立(唯一)索引(反之亦然) .如果您需要双向查询,这将很有用:分别获取给定用户的组和给定组的用户。 - 执行上述 (1) 或 (2) 或 (3),但还创建代理键(例如
{UserGroupID}
)。如果您有引用联结表的“子”表,并且您希望简化通过外键迁移到它们的键的大小,这可能很有用。如果您的 ORM 工具不能很好地处理复合键,它也可能有用。
如果您决定选择 (1) 或 (2),cluster表(如果您的 DBMS 支持的话)。由于无论如何您只是在进行索引范围扫描,因此根本不需要表堆存在。您甚至应该考虑对 (3) 进行聚类,因为两个索引都是 covering所以没有双重查找的危险。
关于sql - 表纯粹由外键组成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23476623/