如何存储和查询不同的数据

时间:2013-02-09 16:34:20

标签: sql storage

我需要知道存储以下数据的最佳做法是什么:

假设我有多个车库,每个车库都拥有不同类型的车辆,具有完全不同的属性(例如飞机,坦克,轮船,自行车)。我需要查询一个车库中的所有车辆,包括他们的属性。

使用一个通用查询存储和查询此数据有什么好处?将所有车辆存放在一张桌子中,并列出所有可能属性? 或者创建多个表格,每个表格用于特定类型的车辆?然后,我如何查询一个车库的所有不同车辆,而不知道它们是哪种类型?

使用单个查询甚至可以实现这样的效果吗?或者我是否必须创建多个查询才能获取数据?

我希望你明白我想要实现的目标。

4 个答案:

答案 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'