可否通过父表非键属性定义父子表非标识关系
问题答复
该需求完全可以实现,且你当前的表结构已经符合非标识关系的基础要求,只需要补充对应约束即可。
核心逻辑说明
你需要实现的约束本质是参照完整性约束,要求子表Table_B的relation_field_A取值必须在父表Table_A的relation_field_A取值范围内,属于标准的外键应用场景;同时你要求的非标识关系(non-identifying relationship)核心特征是子表主键不包含父表的关联字段,你当前设计里Table_B的主键是独立的Key_B,本身就满足非标识关系的要求,不需要调整主键结构。
实现前提
所有关系型数据库对外键引用的父表字段有强制要求:被引用的父表字段必须是主键,或者添加了唯一约束(UNIQUE)。如果父表的relation_field_A存在重复值,数据库无法唯一匹配参照的父记录,就无法完成完整性校验。
具体操作步骤
- 先给父表
Table_A的relation_field_A添加唯一约束,如果业务要求该字段不允许为空,可以同步加非空限制:
-- 添加唯一约束 ALTER TABLE Table_A ADD CONSTRAINT uk_table_a_relation_field UNIQUE (relation_field_A); -- 可选:如果业务要求relation_field_A非空,执行对应语句即可 -- ALTER TABLE Table_A ALTER COLUMN relation_field_A SET NOT NULL;
- 给子表
Table_B的relation_field_A添加外键约束,指向父表的对应字段即可:
ALTER TABLE Table_B ADD CONSTRAINT fk_table_b_relation_field FOREIGN KEY (relation_field_A) REFERENCES Table_A(relation_field_A);
补充说明
- 上述外键创建完成后,所有对
Table_B的插入、更新操作,如果relation_field_A的取值不存在于Table_A的对应字段集合中,会被数据库直接拦截,完全满足你的约束要求。 - 如果需要配置父表记录删除、更新时的子表联动规则,可以在外键定义中追加
ON DELETE、ON UPDATE参数,支持RESTRICT(默认,拦截父表操作)、CASCADE(级联操作子表)、SET NULL(子表对应字段置空)等选项,配置后不会改变两表的非标识关系属性。 - 注意不要将
relation_field_A加入Table_B的主键组成,否则两表就会变为标识关系,和你的需求不符。
内容的提问来源于stack exchange,提问作者postgres_user_99
相关产品推荐
相关产品推荐

