如何从关系数据库中删除循环引用

问题描述

假设我正在建立一个包含群组和房间的聊天。我需要为它创建关系数据库方案。

  • 每组可以有多个房间。
  • 并且每组总是恰好有 1 个主房间(这也是与其他房间相同的房间)
  • 房间已经预建(无论是否为主房间)结构且无法复制。像它的外键,或描述、通知设置等。

因此,由于它是一对多关系,因此以下数据库架构可以表示此模型:

,-----------------.
|Group            |
|-----------------|
|*id: pk          |
|*name: string    |
|*main_room_id: fk|
`-----------------'
      ↑      ᗐ             
      ᗑ      ↓,-------------.  
  |Room         |  
  |-------------|  
  |*id:         |  
  |*name: string|
  |*notif: bool |    
  |*group_id: fk|  
  `-------------'  

但我想在这个方案中避免循环引用。我可以通过在一个房间里有一个布尔字段来说明这是一个主房间:

,-------------.  
 |Group        |  
 |-------------|  
 |*id: pk      |  
 |*name: string|  
 `-------------'  
         ↑        
         ᗑ,----------------.
|Room            |
|----------------|
|*id:            |
|*name: string   |
|*notif: bool    |
|*group_id: fk   |
|*is_main: bool  |
`----------------'

但是在使用这个方案时数据库没有被规范化。主房间 is_main 布尔字段取决于其他房间 is_main 字段。此外,应该创建更复杂的约束来支持数据一致性。

针对此问题的适当数据库架构是什么?

解决方法

-- Group GRP exists.
--
group {GRP}
   PK {GRP}
-- Room ROM exists.
--
room {ROM}
  PK {ROM}
  • 每个房间属于最多一个组;
    每组可能拥有多个房间。
-- Room ROM is owned by group GRP.
--
room_group {ROM,GRP}
        PK {ROM}
        SK {ROM,GRP}

FK1 {ROM} REFERENCES room  {ROM}
FK2 {GRP} REFERENCES group {GRP}
  • 每组最多有一个主房间;
    每个主要房间属于一个组。

  • 如果一个房间是一个组的主房间,
    那么那个房间必须属于那个组。

-- Room ROM is main room for group GRP.
--
main_room {GRP,ROM}
       PK {GRP}
       AK {ROM}

        FK {ROM,GRP} REFERENCES
room_group {ROM,GRP}

注意事项:

请注意,模型中不强制有主房间,请使用应用程序级别来强制执行。

All attributes (columns) NOT NULL

PK = Primary Key
AK = Alternate Key   (Unique)
SK = Proper Superkey (Unique)
FK = Foreign Key
,

我不认为这是一种多对一的关系。假设我理解正确,在我们的架构中,每个组都可以与多个房间相关联,并且每个房间也可以与一个或多个组相关联,因此这意味着这是一种多对多关系。

例如,假设您可以在架构中拥有这些关联:

Group     Room
group_1   room_1
group_1   room_2
group_2   room_1
group_2   room_2

最好创建一个新实体来保存房间和组实体之间的关系。在这个新实体上,您可以有一个布尔字段来指示哪个关联是 main

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...