如何强制两个父记录在SQL

时间:2017-05-18 19:46:00

标签: sql database sqlite foreign-keys schema

以下是一个人为例子的架构图片,展示了我面临的问题。

My schema

我的问题是在SQL 中,如何确保门(门和门蓝图)的父记录都具有相同的House Blueprint父级?换句话说,我如何确保每个门记录只有一个House Blueprint祖父母?

我已经使用外键的最佳实践来指定一对多关系。我需要门桌,因为门的实例可以根据房子涂上任何颜色。我需要门蓝图表,因为我想跟踪设计门的人。此外,在这个人为的例子中,门蓝图只能有一个单独的家庭蓝图(我知道这不是现实的,所以只要忽略门蓝图可以在多个房屋蓝图中使用的可能性)。

我遇到的问题是,我有时会获得门记录,其中House记录附加到一个House Blueprint,而Door Blueprint附加到另一个House Blueprint记录。这绝不应该发生。我可能会在我的记录插入逻辑中阻止这种情况,但这不是在SQL级别。

让我感到不安的是,我有两条不同的路径回到House的蓝图,但是我没有看到任何其他方式。

我并不是真的在寻找一堆代码片段,因为我可以自己弄清楚语法。相反,我正在寻找一种高级方法来解决SQL中的问题。另外,我使用的是SQLite3,但我想这个问题可以在任何RDBMS中解决。

提前感谢您对此的任何帮助!

1 个答案:

答案 0 :(得分:1)

在关系数据库中,您将使用断言。在SQL数据库中,使用对唯一约束的重叠外键引用。 (不是外键引用候选键。)

create table house_blueprints (
  house_blueprint_id integer primary key
);

create table houses (
  house_id integer primary key,
  house_blueprint_id integer not null,
  foreign key (house_blueprint_id) 
    references house_blueprints (house_blueprint_id),
  unique (house_id, house_blueprint_id)
);

create table door_blueprints (
  door_blueprint_id integer primary key,
  house_blueprint_id integer not null,
  foreign key (house_blueprint_id) 
    references house_blueprints (house_blueprint_id),
  unique (door_blueprint_id, house_blueprint_id)
);

create table doors (
  door_id integer primary key,
  house_id integer not null,
  house_blueprint_id integer not null,
  foreign key (house_id, house_blueprint_id) 
    references houses (house_id, house_blueprint_id),
  door_blueprint_id integer not null,
  foreign key (door_blueprint_id, house_blueprint_id) 
    references door_blueprints (door_blueprint_id, house_blueprint_id)
);

唯一约束不是候选键,因为它们不是最小的。但是他们必须为重叠的外键提供目标。

表“doors”有一列用于house_blueprint_id,两个重叠的外键约束使用它。这些外键约束不能为house_blueprint_id提供不同的值。