具有多个一对一父级的SQL子级

时间:2019-11-25 12:27:49

标签: sql database database-design

我有3张桌子:

Plane (ID, Name)        //Parent
Car(ID, Name)           //Parent
Engine(ID, Name)        //Child

Engine表必须具有PlaneCar的父表。这些表与一对一关系有关。

最主要的是,需要通过引擎获得父母。如何在此处正确设置数据库?


我在这里看到了多种情况,但无法确定哪一种是最好的:

  1. engine ID放在PlaneCar处。我在这里面临的问题是,在查询之前,我需要知道哪个父引擎属于。
  2. 具有plane_enginecar_engine表。与上述相同的问题+多对多关系需要更多单独表的开销(在这里不是这种情况)
  3. 具有一个软键并在引擎表上键入(Parent_ID,类型)。在1和2种情况下的问题有所减少,但我不能确保Type和Parent_ID为true并表示它应该是什么(例如Type是Car但Parent ID是飞机)。

任何见解都会很棒。谢谢!

1 个答案:

答案 0 :(得分:0)

  
      
  1. 将引擎ID放在飞机和汽车上。我在这里面临的问题是,在查询之前,我需要知道哪个父引擎属于。
  2.   

此模型在CarEngine之间(以及PlaneEngine之间建模N:1。

您需要使Car.EngineID唯一具有0..1:1(0,因为这仍然允许无汽车发动机)。否则,这可以满足您的要求,Car.EngineID上的索引应确保在获得与已知发动机对应的汽车时的良好性能。

  
      
  1. 具有plane_engine和car_engine表。与上述相同的问题+多对多关系需要更多单独表的开销(在这里不是这种情况)
  2.   

正如您正确指出的那样,这将模拟N:N。

通过设置适当的字段可以将其限制为0..1:N或N:0..1或什至0..1:0..1,但是如果您实际上不需要N,则通常不需要:N。

  
      
  1. 具有一个软键并在引擎表上键入(Parent_ID,类型)。在1和2种情况下的问题有所减少,但我不能确保Type和Parent_ID为true并表示它应该是什么(例如Type是Car但Parent ID是飞机)。
  2.   

这实际上在CarEngine(以及PlaneEngine)之间建立了1:N建模。正如您所指出的,它不允许使用proper enforcement of foreign keys

如果实际需要的是1:N,则只需输入...

PlaneID REFERENCES Plane
CarID REFERENCES Car

...在Engine中。而且您可以强制执行排他性(因此同一引擎不能同时用作汽车和飞机的用户)...

CHECK (
    (PlaneID IS NOT NULL AND CarID IS NULL)
    OR (PlaneID IS NULL AND CarID IS NOT NULL)
)

另一方面,如果您需要CarEngine之间的1:0..1,则只需对Engine.CarID施加UNIQUE约束。同上飞机​​。

或者您可以使用inheritance