我如何在关系数据库中的一对多关系上定义一对一关系?

How do I define a one-to-one relationship over a one-to-many relationship in a relational database?

我正在使用以下 table 创建一个数据库模式(抱歉伪代码不好):

User
====
user_id, PK

Collection
==========
collection_id, PK
user_id, FK(User->user_id)

Issue
=====
issue_id, PK
collection_id, FK(Collection->collection_id)

从User到Collection,从Collection到Issue,都是一对多的关系。因此,一个用户可能会维护多个集合,每个集合都有很多问题。

问题:我想指定一个"default"集合在用户首次登录应用程序时显示。作为记录,我是在 Django 框架中这样做的,但我对优雅的独立于平台的解决方案更感兴趣。当我尝试在 User 中创建一个作为 Collection 外键的列时,它会抱怨 Collection 尚不存在(我想是因为 User 是先创建的)。我 可以 添加一个 "default" 布尔列到 Collection 并通过我的应用程序强制每个用户只有一个记录是 "true",但这似乎不雅。我也可以有一个单独的 table,比如说 User_Default_Collection,它有一个 user_id 作为唯一外键,还有一个 collection_id 列,它是集合的外键。但我敢肯定这也低于第三范式。有什么建议吗?

我认为最合理的解决方案是:

  1. 将可为空的 "default" 字段添加到集合 table
  2. 为 used_id 和默认
  3. 创建 UNIQUE 约束

在 "default" 列中保留 "true"-s 和 NULL(无假)。

这将不允许与同一个 user_id 关联的多个集合具有除 null 之外的相同 "default" 值。您不需要开发任何应用程序逻辑。但是,此设计不会强制您始终为用户提供默认集合。

如果你想强制每个用户必须并且将始终拥有他的 "default" collection,那么由于包含依赖项中明显的循环,你被迫进行延迟约束检查(如果您的 DBMS 允许首先声明 FK 循环)或 application-enforced 完整性。

如果您可以容忍用户根本没有任何默认值 collection,则创建一个单独的 table DFT_COLL(userid, dft_coll_id),其中包含密钥 userid 和 FK给 USER 和 COLLECTION.

如果在用户没有默认值 collection 的情况下给您带来麻烦,也许仍然可以通过让系统只选择一个(例如具有最低 [或最高] ID 的那个)来解决这个问题并使用 UNION 视图实现它(这样,如果您需要默认值,那么您可以阅读 UNION 视图,并且可以保证 (*) 获得 some 结果)。

(*) 如果用户根本没有 collection,那就是。请注意,要求默认值 collection 并要求它存在,意味着每个用户至少需要一个 collection。 (由此推论,如果必须允许一个用户根本没有collection,那么要求他有一个默认值是荒谬的,自相矛盾。)