我需要知道存储以下数据的最佳做法是什么:
假设我有多个车库,每个车库都拥有不同类型的车辆,具有完全不同的属性(例如飞机,坦克,轮船,自行车)。我需要查询一个车库中的所有车辆,包括他们的属性。
使用一个通用查询存储和查询此数据有什么好处?将所有车辆存放在一张桌子中,并列出所有可能属性? 或者创建多个表格,每个表格用于特定类型的车辆?然后,我如何查询一个车库的所有不同车辆,而不知道它们是哪种类型?
使用单个查询甚至可以实现这样的效果吗?或者我是否必须创建多个查询才能获取数据?
我希望你明白我想要实现的目标。
答案 0 :(得分:1)
这可以肯定,但是在创建数据模型时需要进行一些规划。
正如您已经提到的,有不同的方法来实现子类型 - 超类型关系(也称为继承)。
1。)所有在一个表
在这种情况下,我会像你这样模拟你的问题:
Garage(GarageId_PK, Name)
Vehicle(VehicleId_PK, LicenceNr, GarageId_FK, SomethingOnlyCarsHave, SoemthingOnlyMortorbikesHave, Type)
对于Type,您可以提供ID并有一个单独的表,您可以将ID与Name相关联,或者只是在那里写下名称(不是一个非常干净的解决方案!)。 顺便说一句:如果你想拥有多重继承(我猜你不需要车辆),你也可以使用Type a bitmask。
就我个人而言,我并不喜欢这种方法,但这样做是可以的。 Oracle即在他们的研究材料中提出这一点。对于您的一个查询问题,它也是更简单的解决方案:
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到外键。
答案 1 :(得分:1)
我会做这样的事情:
表车库 - 车库,名称,其他东西
表车辆 - VehicleId,VehicleTypeId,其他东西
表格VehicleType - VehicleTypeId,类型,其他内容
表属性 - AttributeId,AttributeName,其他东西
表VehicleAttribute - VehicleId,AttibuteId,Value,其他东西
表VehicleGarage - VehicleId,GarageId,DateIn,DateOut,其他东西
查询车库中的所有车辆和属性
select v.vehicleId
, vt.type
, a.attributename
, va.value
from VehicleGarage vg join Vehicle v on vg.VehicleId = v. VehicleId
join VehicleType vt on v.VehicleTypeId = vt.VehicleTypeId
join VehicleAttribute va on v.VehicleId = va.VehicleId
join Attribute a on va.AttributeId = a.AttributeId
where garageId = 1
对于表格,其他东西就像CreatedWhen,CreatedBy等等。
答案 2 :(得分:0)
您可以拥有一个看起来
的模型vehicle_type(vehicle_type_id, description, PK(vehicle_type_id));
(1, 'bike'; 2, 'plane', ..etc);
vehicle(vehicle_id, vehicle_type_id (FK to vehicle_type),
[common attributes], PK(vehicle_id),
UNIQUE(vehicle_id,vehicle_type_id )
);
bike(vehicle_id,vehicle_type_id , [bike attributes],
PK(vehicle_id,vehicle_type_id),
FK(vehicle_id,vehicle_type_id ) to vehicle,
CHECK(vehicle_type_id=1));
plane(vehicle_id,vehicle_type_id , [plane attributes],
PK (vehicle_id,vehicle_type_id),
FK(vehicle_id,vehicle_type_id ) to vehicle,
CHECK(vehicle_type_id=2)
);
garage(garage_id, name, ..., PK (garage_id));
garage_vehicle(garage_id - FK to garage,
vehicle_id - FK to vehicle, PK(garage_id,vehicle_id)
);
答案 3 :(得分:0)
你可以存储所有可能的车库是一个单独的表车库。 然后将所有可能组合的车辆存放在车辆中 表。在车辆表中添加引用
的外键列
create table vehicle(column1,column2...,garageid foreign key references garage)
然后选择一个车库中的所有车辆,您可以查询车辆表
select * from vehicle where garage='garage_value'