含sequence属性的1:n关联对象模型转关系型schema及外键设计咨询
问题1:是否需要设置sequence类型的外键属性?
不需要。原因如下:
- 你原始对象定义中SPORTS ARENA的
sports序列属于冗余属性,1:n的场馆-项目关联关系本身就可以通过外键反向查询得到场馆下的所有项目,不需要单独存储序列。 - 关系型数据库不支持将序列(多值数组)作为外键使用,既无法实现参照完整性校验,也会违反第一范式(列值原子性要求),后续关联查询、数据统计的操作都会非常难处理。
问题2:正确的关系型方案设计
总共需要3张表,完全覆盖原始对象的所有属性和关联关系,结构如下:
表1:sports_arena(运动场馆表)
存储场馆基础信息
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
arena_id | 整型/UUID | 主键 | 场馆唯一标识 |
name | varchar | 非空 | 场馆名称 |
表2:sport(运动项目表)
存储运动项目基础信息,通过外键关联所属场馆
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
sport_id | 整型/UUID | 主键 | 运动项目唯一标识 |
name | varchar | 非空 | 运动项目名称 |
arena_id | 整型/UUID | 外键,关联sports_arena.arena_id,非空 | 项目所属的场馆ID,对应1:n的场馆-项目关系 |
表3:sport_discipline(运动分项表)
存储运动项目下的多个分项,对应原始SPORT对象的disciplines序列属性
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
discipline_id | 整型/UUID | 主键 | 分项唯一标识 |
sport_id | 整型/UUID | 外键,关联sport.sport_id,非空 | 分项所属的运动项目ID |
discipline_name | varchar | 非空 | 分项名称 |
设计说明
- 原始对象中的两个序列属性都通过关联关系实现,不需要在主表存储多值列:
- 查询某场馆承接的所有运动项目:直接过滤
sport表的arena_id字段即可 - 查询某运动项目的所有分项:直接过滤
sport_discipline表的sport_id字段即可
- 查询某场馆承接的所有运动项目:直接过滤
- 所有外键都可以设置级联操作,比如删除场馆时同步删除关联的项目、分项,保证数据一致性
- 完全符合关系型数据库的范式要求,后续查询、统计、扩展的灵活性都更高
内容的提问来源于stack exchange,提问作者Spyromancer
相关产品推荐
相关产品推荐

