Room SQLite环境下杂志与多角色人员关联数据库设计咨询
问题1解答:三字段联合主键设计合理性
这个设计是完全合理的,刚好匹配你的业务需求:
- 你的场景需要支持同一人员在同一份杂志中承担多个角色,若仅使用
person_id+magazine_id作为联合主键,无法存储同一人同本杂志的多条角色记录,加入type字段组成三字段联合主键后,刚好可以避免同个人员同本杂志同个角色的重复插入,从数据库层面就避免了脏数据写入 - 设计完全符合关系型数据库第三范式,没有冗余存储,字段语义清晰
问题2解答:方案对比与优化建议
你当前的关联表方案远优于按角色单独建表的思路,两者对比如下:
- 按角色单独建表的缺陷:每新增一种角色(比如后续要加插画师、特约编辑等)都需要新增对应的关联表,表结构会随业务迭代不断膨胀,查询时也需要关联多张表,无论是数据库维护还是代码层面的Room DAO编写成本都会大幅提升,扩展性极差
- 你当前方案的优势:新增角色不需要修改表结构,仅需给
type字段新增合法枚举值即可,扩展性极强,数据集中管理维护成本更低,Room查询也更简便:你可以通过条件过滤+@Relation注解直接映射得到你需要的Magazine(title, listOfWriters, listOfPhotographers)结构,不需要手动处理多表关联结果。
如果要对现有方案做优化,可以给关联表的type字段增加CHECK约束,限定type仅能写入预设的合法角色值,从数据库层面避免非法值插入,Room中可以直接在表定义中加入约束规则:
@Entity( primaryKeys = ["person_id", "magazine_id", "type"], foreignKeys = [ ForeignKey(entity = Person::class, parentColumns = ["id"], childColumns = ["person_id"]), ForeignKey(entity = Magazine::class, parentColumns = ["id"], childColumns = ["magazine_id"]) ], // 加入CHECK约束限定type合法值 checks = [Check(value = "type IN ('writer', 'photographer', 'illustrator')")] ) data class PersonMagazineRelation( val person_id: Int, val magazine_id: Int, val type: String )
内容的提问来源于stack exchange,提问作者android iPhone
相关产品推荐
相关产品推荐

