【问题标题】:SQL child with multiple 1-to-1 parents具有多个一对一父母的 SQL 孩子
【发布时间】:2019-11-25 12:27:49
【问题描述】:

我有 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 为真并表示它应该表示的内容(例如,Type 是 Car,但 Parent ID 是飞机)。

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

【问题讨论】:

  • 不确定,场景 #2 有什么问题?无论如何,您需要知道CarPlane 中的哪一个(或两者)与查询相关。

标签: sql database database-design


【解决方案1】:
  1. 将引擎 ID 放在 Plane 和 Car。我在这里面临的问题是,在查询之前,我需要知道属于哪个父引擎。

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

您需要使 Car.EngineID UNIQUE 具有 0..1:1(0,因为这仍然允许无车引擎)。否则,这看起来很符合您的要求,Car.EngineID 上的索引应确保在获取与已知引擎相对应的汽车时具有良好的性能。

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

正如您正确指出的那样,这对 N:N 进行建模。

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

  1. 在引擎表中有一个软键和类型(Parent_ID,类型)。减少了 1 和 2 场景中的问题,但我无法确保 Type 和 Parent_ID 为真并表示它应该表示的内容(例如,Type 是 Car,但 Parent ID 是飞机)。

这实际上是在 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-07
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多