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

Database 如何在关系数据库中定义一对多关系上的一对一关系?,database,relational-database,database-schema,Database,Relational Database,Database Schema,我正在使用以下表创建一个数据库架构(很抱歉,伪代码不正确): 从用户到集合,从集合到问题,存在一对多的关系。因此,单个用户可以维护多个集合,每个集合都有许多问题 问题:我想指定用户首次登录应用程序时显示的“默认”集合。作为记录,我是在Django框架中做这件事的,但我更感兴趣的是优雅的独立于平台的解决方案。当我试图在User中创建一列作为集合的外键时,它会抱怨集合还不存在(我想是因为User是首先创建的)。我可以在集合中添加一个“default”布尔列,并通过我的应用程序强制每个用户只有一条记录

我正在使用以下表创建一个数据库架构(很抱歉,伪代码不正确):

从用户到集合,从集合到问题,存在一对多的关系。因此,单个用户可以维护多个集合,每个集合都有许多问题


问题:我想指定用户首次登录应用程序时显示的“默认”集合。作为记录,我是在Django框架中做这件事的,但我更感兴趣的是优雅的独立于平台的解决方案。当我试图在User中创建一列作为集合的外键时,它会抱怨集合还不存在(我想是因为User是首先创建的)。我可以在集合中添加一个“default”布尔列,并通过我的应用程序强制每个用户只有一条记录为“true”,但这似乎不雅观。我还可以有一个单独的表,比如说,User\u Default\u Collection,它将User\u id作为外部唯一键,还有一个Collection\u id列,它是集合的外键。但我敢肯定,这也比第三范式小。有什么建议吗?

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

  • 将可为空的“默认”字段添加到集合表
  • 为使用的\u id和默认值创建唯一约束
  • 在“默认”列中保留“true”-s和null(无false)


    这将不允许与同一用户id关联的多个集合具有相同的“默认”值(null除外)。您不需要开发任何应用程序逻辑。但是,此设计不会强制您始终拥有用户的默认集合。

    如果您希望强制每个用户必须且将始终拥有其“默认”集合,则由于包含依赖项中的明显循环,您将被迫进行延迟约束检查(如果DBMS首先允许声明FK循环)或应用程序强制的完整性

    如果您可以容忍用户根本没有任何默认集合,则创建一个单独的表DFT_COLL(userid,DFT_COLL_id),其中包含用户和集合的密钥userid和FK

    如果在用户没有默认集合的情况下给您带来麻烦,那么可能仍然可以通过让系统选择一个(例如,id最低[或最高]的集合)并使用联合视图实现这一点来解决(这样,如果您需要默认集合,那么您可以读取联合视图,并且可以保证(*)获得一些结果)


    (*)如果用户有一个集合,也就是说。请注意,要求默认集合并要求其存在,意味着每个用户至少需要一个集合。(其推论是,如果必须允许用户完全没有集合,那么要求用户拥有默认集合是毫无意义的,也是矛盾的。)

    但这仍然是第三种正常形式吗?我不确定。不是真的。但额外的表解决方案需要使其与集合表保持同步(如果在DFT_COLL中设置了用户收集链接,但未在收集中设置该怎么办?)我认为这是一个更大的不幸。抱歉,我在手机上回复。我的理解是,归一化适用于整个数据库,而不仅仅是一个表。至于你的其他评论,我不确定你在问什么。用户必须有一个默认集合,并且可能只有一个。我们说数据库是以某种正常的形式表示A。所有表都至少是正常形式。我们说,表是基于约束的特定正常形式,它受每个函数依赖项和联接依赖项的约束。这些约束不是表间约束。建议您了解有关标准化的更多信息。(来自学院/大学教科书/幻灯片/课程。许多都是在线的。)你是我最后一个附言:好的,用户与集合的比例是1:1。接下来的评论也适用。不,用户与集合的比例是一对多。但是他们与默认集合的比例是1:1。我想我说的很清楚“从用户到集合,从集合到问题,都存在一对多的关系。因此,单个用户可以维护多个集合,每个集合都有许多问题。”目标是“标记”每个用户恰好有一个集合为“默认”,“也就是说,在打开应用程序时默认显示。可能我问题的标题有误导性。我喜欢这个答案,我将使用第二个表。在应用程序级别,我在创建用户时创建一个集合,因此始终至少会有一个(我不允许用户删除他们的最后一个收藏)。
    User
    ====
    user_id, PK
    
    Collection
    ==========
    collection_id, PK
    user_id, FK(User->user_id)
    
    Issue
    =====
    issue_id, PK
    collection_id, FK(Collection->collection_id)