What is the best way to enforce a #39;subset#39; relationship with integrity constraints(强制执行具有完整性约束的“子集关系的最佳方法是什么)
问题描述
例如,给定 3 个表:
For example, given 3 tables:
- 腹足类
- 蜗牛
- 蛞蝓
并假设我们要强制执行
- 'gastropod' 中的每一行在 'snail' 或 'slug' 中都有一个对应的行(但不能同时存在)
- 'slug' 中的每一行在 'gastropod' 中都有一个对应的行
- 'snail' 中的每一行在'gastropod' 中都有一个对应的行
设置架构以强制执行这些约束的最佳方法是什么?
what is the best way to set up my schema to enforce these constraints?
我已经为 postgres 提供了一个可能的答案,我对 postgres 和 Oracle 的解决方案特别感兴趣,但也有兴趣查看其他 RDBMS 的解决方案
I've provide one possible answer for postgres, and I am particularly interested in solutions for postgres and Oracle, but would also be interested to see solutions for other RDBMSs
编辑
作为参考,来自以下回答/评论的 SO 问题解决了类似的问题:
EDIT
For reference, SO questions from from answers/comments below addressing similar problems:
- 维护关系数据库中的子类完整性
- 数据库设计 - 文章、博文、照片、故事
- 来自不同实体的相同数据在数据库中 - 最佳实践 - 电话号码示例
推荐答案
我自己的 postgres 解决方案(但我不知道它是否是最好的方法):
My own solution for postgres (but I have no idea if it is the best way):
枚举:
create type gastropod_type as enum ('slug', 'snail');
表和约束:
create table gastropod(
gastropod_id serial unique,
gastropod_type gastropod_type,
slug_gastropod_id integer,
snail_gastropod_id integer,
average_length numeric,
primary key(gastropod_id, gastropod_type),
check( (case when slug_gastropod_id is null then 0 else 1 end)+
(case when snail_gastropod_id is null then 0 else 1 end)=1) );
create table slug(
gastropod_id integer unique,
gastropod_type gastropod_type check (gastropod_type='slug'),
is_mantle_visible boolean,
primary key(gastropod_id, gastropod_type),
foreign key(gastropod_id, gastropod_type)
references gastropod deferrable initially deferred );
create table snail(
gastropod_id integer unique,
gastropod_type gastropod_type check (gastropod_type='snail'),
average_shell_volume numeric,
primary key(gastropod_id, gastropod_type),
foreign key(gastropod_id, gastropod_type)
references gastropod deferrable initially deferred );
alter table gastropod
add foreign key(slug_gastropod_id, gastropod_type)
references slug deferrable initially deferred;
alter table gastropod
add foreign key(snail_gastropod_id, gastropod_type)
references snail deferrable initially deferred;
测试:
insert into gastropod(gastropod_type, slug_gastropod_id, average_length)
values ('slug', currval('gastropod_gastropod_id_seq'), 100);
insert into slug(gastropod_id, gastropod_type, is_mantle_visible)
values (currval('gastropod_gastropod_id_seq'), 'slug', true);
select gastropod_id, gastropod_type, average_length, is_mantle_visible
from gastropod left outer join slug using(gastropod_id, gastropod_type)
left outer join snail using(gastropod_id, gastropod_type);
gastropod_id | gastropod_type | average_length | is_mantle_visible
--------------+----------------+----------------+-------------------
1 | slug | 100 | t
(1 row)
这篇关于强制执行具有完整性约束的“子集"关系的最佳方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:强制执行具有完整性约束的“子集"关系的最佳方法是什么


基础教程推荐
- 无法在 ubuntu 中启动 mysql 服务器 2021-01-01
- Sql Server 字符串到日期的转换 2021-01-01
- SQL Server 2016更改对象所有者 2022-01-01
- 使用pyodbc“不安全"的Python多处理和数据库访问? 2022-01-01
- SQL Server 中单行 MERGE/upsert 的语法 2021-01-01
- ERROR 2006 (HY000): MySQL 服务器已经消失 2021-01-01
- 将数据从 MS SQL 迁移到 PostgreSQL? 2022-01-01
- 在 VB.NET 中更新 SQL Server DateTime 列 2021-01-01
- SQL Server:只有 GROUP BY 中的最后一个条目 2021-01-01
- 如何在 SQL Server 的嵌套过程中处理事务? 2021-01-01