SQL数据库设计入门:外键放置最佳实践及关联方案咨询
外键放置逻辑最佳实践及方案选型
首先先明确三个方案的适用场景,你可以根据自己的业务需求匹配:
- 你当前在用的方案:将
Address表的PKAddress_ID作为外键存入Parent/Student/Teacher表
适用场景:每个实体仅对应1个地址,且地址不会被多个实体共享。该方案完全符合1:1关系的设计规范,结构最简单,查询时仅需一次联表即可拿到实体+地址信息,性能最高,没有错误。 - 方案2:将
Parent表的PK作为外键存入Address表
完全不推荐用于你的多实体共用Address的场景。如果采用该方案,你需要在Address表额外新增Student_ID、Teacher_ID等多个外键字段,每次插入地址时仅能填充其中一个字段,会产生大量空值,违反数据库第三范式,后续新增关联地址的实体时还需要修改Address表结构,扩展性极差。 - 方案1:新建关联中间表
适用场景:一个实体可对应多个地址,或地址可被多个实体共享。比如同一个家庭地址同时属于家长和其关联的学生,或者需要支持用户维护家庭地址、办公地址等多类地址,该方案灵活性最高,适合规模较大的系统后续扩展。
适配师生课程预约系统的落地建议
如果你的系统不需要多地址、地址共享能力,直接沿用你当前的设计即可,不需要做调整。
如果需要支持多地址、地址共享,推荐设计通用关联中间表,不需要为每个实体单独建关联表,参考表结构如下:
CREATE TABLE Entity_Address ( entity_id INT NOT NULL COMMENT '关联实体的主键ID', entity_type TINYINT NOT NULL COMMENT '实体类型:1=家长,2=学生,3=老师', address_id INT NOT NULL COMMENT '关联地址的主键ID', address_type TINYINT COMMENT '地址类型:1=家庭地址,2=办公地址,3=接送地址', is_default TINYINT DEFAULT 0 COMMENT '是否为该实体的默认地址', PRIMARY KEY (entity_id, entity_type, address_id), FOREIGN KEY (address_id) REFERENCES Address(Address_ID) );
设计注意事项
仅多对多关系需要使用中间表,1:1/1对多关系用中间表会额外增加联表成本,没有必要
共用型基础表(如Address、Attachment这类会被多个业务实体关联的表)不要存储业务实体的外键,避免表结构无限膨胀
参考示意图:
内容的提问来源于stack exchange,提问作者Scott Cooper
相关产品推荐
相关产品推荐

