如何向存在跨表外键依赖的多张关联表中插入数据?
解决方案
方案1:调整表结构(推荐,从根源消除循环依赖)
你当前遇到的循环依赖本质是冗余字段导致的不合理依赖,Households表完全没必要单独存储户主的姓名、地址字段,这类信息在People表已经存在,冗余存储反而会带来数据不一致的风险。调整表结构如下:
Households表移除lastName、firstName、addressId字段,新增household_head_id字段,外键关联People.id,该字段设置为可空- 后续需要查询户主信息时直接关联
People表获取即可
调整后的流程仅需要1次更新操作,步骤如下:
- 插入
Addresses记录,获取生成的addressId - 插入
Households记录(可填充家庭相关的其他业务字段,household_head_id留空),获取生成的householdId - 插入所有
People记录,直接携带上一步拿到的householdId,同时记录户主对应的peopleId - 最后仅需更新一次
Households表的household_head_id字段为户主的peopleId即可
该方案比你原流程少了一次批量更新People表的操作,执行效率更高,也从根源避免了数据冗余带来的一致性问题。
方案2:不允许修改表结构的简化方案
如果受现有业务限制无法调整表结构,可以使用数据库的可延迟外键约束(PostgreSQL、Oracle等主流数据库均支持该特性)简化流程,不需要提前插入无householdId的People记录:
- 开启事务,将
People.householdId的外键约束设置为事务提交时再校验 - 插入
Addresses记录,获取生成的addressId - 插入所有
People记录,householdId可先填占位值,同时记录户主的lastName、firstName、addressId字段值 - 用户主的相关字段插入
Households记录,获取真实生成的householdId - 批量更新所有
People记录的householdId为上一步拿到的真实值 - 提交事务,外键约束自动校验,校验通过后事务完成
该方案比原流程少了一次更新Households表的操作,所有操作都在同一事务内执行,数据一致性有保障。
内容的提问来源于stack exchange,提问作者inNeedOfHelp
相关产品推荐
相关产品推荐

