三级祖孙表结构下如何为子表t3添加关联祖父表t1的外键FK
操作实现步骤
- 第一步:给t3表新增存储t1主键的字段,字段类型必须和t1表的id字段完全匹配
-- 示例:假设t1.id是INT UNSIGNED类型,可根据你的实际字段类型调整 ALTER TABLE t3 ADD COLUMN t1_id INT UNSIGNED NOT NULL;
- 第二步:回填t3中所有历史数据的t1_id值,通过t2表关联更新
UPDATE t3 INNER JOIN t2 ON t3.t2_id = t2.id SET t3.t1_id = t2.t1_id;
- 第三步:给t3的t1_id字段添加指向t1.id的外键约束
-- 外键名可自定义,只要库内唯一即可 ALTER TABLE t3 ADD CONSTRAINT `fk_t3_t1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`);
- 第四步:调整数据写入逻辑,后续新增/修改t3记录时,同步写入正确的t1_id值
插入t3数据前可以从t2表查询对应t1_id写入,也可以直接从业务上下文传值(前提是业务侧能保证值的正确性)
可选优化说明
如果不想修改业务代码维护冗余字段,也可以用数据库触发器自动维护t3.t1_id的值:
-- 插入前自动填充t1_id的触发器示例 DELIMITER // CREATE TRIGGER tr_t3_before_insert BEFORE INSERT ON t3 FOR EACH ROW BEGIN SET NEW.t1_id = (SELECT t1_id FROM t2 WHERE id = NEW.t2_id); END // DELIMITER ; -- 更新t2_id时自动同步t1_id的触发器示例 DELIMITER // CREATE TRIGGER tr_t3_before_update BEFORE UPDATE ON t3 FOR EACH ROW BEGIN IF NEW.t2_id != OLD.t2_id THEN SET NEW.t1_id = (SELECT t1_id FROM t2 WHERE id = NEW.t2_id); END IF; END // DELIMITER ;
这种设计属于典型的反范式优化,好处是减少关联查询提升读性能,代价是需要额外维护冗余字段的数据一致性,可根据业务的查询频率、数据更新频率权衡是否采用。
内容的提问来源于stack exchange,提问作者user16049828
相关产品推荐
相关产品推荐

