这当然是可能的,但是在创建数据模型时需要进行一些规划。
正如您已经提到的,有不同的方法来实现子类型-超类型关系(又名继承)。
1.) 一张桌子
在这种情况下,我会像这样模拟您的问题:
Garage(GarageId_PK, Name)
Vehicle(VehicleId_PK, LicenceNr, GarageId_FK, SomethingOnlyCarsHave, SoemthingOnlyMortorbikesHave, Type)
对于类型,您可以提供 ID 并有一个单独的表,您可以在其中将 ID 与名称相关联,或者只是在那里写下名称(不是一个非常干净的解决方案!)。顺便说一句:如果您想要多重继承(我猜您不需要车辆),您也可以将 Type 设置为位掩码。
我个人不是很喜欢这种方法,但是这样做是可以的。Oracle ie 在他们的学习资料中建议了这一点。对于您的一个查询问题,它也是更简单的解决方案:
SELECT *
FROM Vehicle v
INNER JOIN Type t ON (v.Type = t.TypeId)
WHERE GarageId = 42
2.) 每个子类型的表
对我来说,这感觉像是更干净的解决方案,因为您的 NULL 值较少,但您需要更多的工作才能在一个查询中获取所有内容。
Garage(GarageId_PK, Name)
Vehicle(VehicleId_PK, LicenceNr, GarageId_FK)
Car(VechicleId_PK_FK, SomethingOnlyCarsHave)
Motorbike(VechicleId_PK_FK SoemthingOnlyMortorbikesHave)
这在理论上允许多重继承,您应该编写一个只允许子类型的触发器。
本例中的 SQL:
SELECT *
FROM Vehicles v
LEFT JOIN Car c ON(v.VehicleId = c.VehicleId)
LEFT JOIN Motorbike m ON (v.VehicleId = m.VehicleId)
WHERE GarageId = 42
或者,如果您有更多类型,您可以将丑陋的东西放入视图中:
CREATE OR REPLACE View v_allVehicles AS
(SELECT *
FROM Vehicles v
LEFT JOIN Car c ON(v.VehicleId = c.VehicleId)
LEFT JOIN Motorbike m ON (v.VehicleId = m.VehicleId)
SELECT *
FROM v_allVehicles
编辑:
关于符号的一句话:当我将 _PK 放在名称后面时,它指的是作为主键的列。_FK 到外键。