外键SQL上的圈一致性

外键SQL上的圈一致性,sql,postgresql,constants,Sql,Postgresql,Constants,我有三张桌子 aircrafts flights events 航班有外键飞机id 事件同时使用外键飞机识别码 和可选外键航班id 有没有办法限制事件以防止如果航班id不为空,那么事件上的飞机id与航班上的飞机id相同,使用此航班id?您需要添加两个限制 ALTER table flights ADD constraint uniq_id_aircraft_id unique (id, aircraft_id); ALTER table events ADD FOREIGN KEY (a

我有三张桌子

aircrafts 
flights
events 
航班
有外键
飞机id

事件
同时使用外键
飞机识别码
可选外键
航班id


有没有办法限制
事件
以防止如果
航班id
不为空,那么
事件上的
飞机id
航班上的
飞机id
相同,使用此
航班id

您需要添加两个限制

ALTER table flights ADD constraint uniq_id_aircraft_id unique (id, aircraft_id);

ALTER table events ADD FOREIGN KEY (aircraft_id, flight_id) REFERENCES event_flights (aircraft_id, id);

要获得您想要的,这取决于基本业务规则。是否存在“不需要飞机也不需要飞行的事件”。如果是这种情况,那么只需从事件中删除飞机id即可。然而,这似乎不太可能,即维护事件不需要飞行。因此,将该规则重申为“事件需要飞行或飞机”。在事件中使飞机id和航班id均为可选的,然后创建一个检查约束,要求其中一个为空,另一个不为空

create table events
       ( event_id integer generated always as identity  
       , aircraft_id  integer
       , flight_id integer
       , constraint events_pk primary key(event_id)
       , constraint event2aircraft_fk
                    foreign key (aircraft_id)
                    references aircraft(aircraft_id)
       , constraint event2flight_fk
                    foreign key (aircraft_id)
                    references aircraft(aircraft_id) 
       , constraint event_or_aircraft_ck
                    check (   (aircraft_id is null and flight_id is not null)  
                           or (aircraft_id is not null and flight_id is null)
                          )
       )
; 
现在,当事件需要飞行时,只能从飞行中检索飞机id