Here is a picture of the schema for a contrived example that demonstrates the problem I am facing.
My question is : In SQL , how do I make sure that the parent records to Door (House and Door Blueprint) each both have the same House Blueprint parent? In other words, how do I make sure that every Door record only has one House Blueprint grandparent?
I am already using best practices for foreign keys to designate the one to many relationships. I need the Door table, because the door instance could be painted any color based on the house. I need the Door Blueprint table, because I want to track who designed the door. Also, in this contrived example, the Door Blueprint can only have a single parent House Blueprint (I know this isn't realistic, so just ignore the possibility that Door Blueprints could be used in multiple House Blueprints).
The problem I am running into is that I sometimes get Door records with a House record attached to one House Blueprint and a Door Blueprint attached to a different House Blueprint record. This should never happen. And I could probably prevent this in my record insertion logic, but that is not at the SQL level.
It makes me uneasy that I have two different paths back to House Blueprint from Door, but I don't see any other way of doing it.
I'm not really looking for a bunch of code snippets, because I can figure out the syntax myself. Rather, I'm looking for a high-level approach to solving the problem in SQL . Also, I am using SQLite3, but I imagine this problem can be solved in any RDBMS.
Thanks in advance for any help with this!
In a relational database, you'd use assertions. In a SQL database, use overlapping foreign key references to unique constraints. (Not foreign key references to candidate keys.)
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)
);
The unique constraints aren't candidate keys, because they're not minimal. But they're necessary to provide targets for the overlapping foreign keys.
The table "doors" has one column for house_blueprint_id, and two overlapping foreign key constraints that use it. No way those foreign key constraints can have different values for house_blueprint_id.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.