简体   繁体   中英

How to implement a disjoint contraint on 1:1 relation in PostgreSQL?

I need to implement a specialization of an entity, using a 1-to-1 relation, let's say something like this:

create table vehicles (
  vehicle_id int primary key,
  ...
)

create table cars (
  car_id int primary key,
  vehicle_id int references vehicles(vehicle_id),
  ...
)

create table bikes (
  bike_id int primary key,
  bike_id int references vehicles(vehicle_id),
  ...
)

Now, I would like to enforce a disjoint contraint, to make sure a vehicle can be either a car or a bike, maybe neither, but never both. As I understand, it is not easy to achieve via RDBM itself, so I decided to validate this in the application (Ruby on Rails). In this case, I think it would be easier to validate if I do the relations the other way around, as it doesn't need any aditional selects and locks during insert:

create table vehicles (
  vehicle_id int primary key,
  car_id int references cars(car_id),
  bike_id int references bikes(bike_id),
  ...
)

create table cars (
  car_id int primary key,
   ...
)

create table bikes (
  bike_id int primary key,
  ...
)

Now, none of the disjoint constraints implementations I have found uses this way. Does it have any disadvantages that I can't see?

Just add a CONSTRAINT CHECK, something like this should answer

ALTER TABLE ONLY vehicles
    ADD CONSTRAINT cars_or_bikes  CHECK (car_id IS NULL OR bike_id IS NULL);

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM