1

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

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

使用一个通用查询来存储和查询这些数据的好做法是什么?将所有车辆存储在一张表中,包含所有可能的属性?或者创建多个表,每个表对应一种特定类型的车辆?那么,如何查询一个车库的所有不同车辆,而不知道它们是哪种类型?

这样的事情甚至可以通过单个查询来实现吗?还是我必须创建多个查询才能获取数据?

我希望你明白我想要达到的目标。

4

4 回答 4

1

这当然是可能的,但是在创建数据模型时需要进行一些规划。

正如您已经提到的,有不同的方法来实现子类型-超类型关系(又名继承)。

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 到外键。

于 2013-02-09T16:59:09.077 回答
1

我会做这样的事情:

表车库——garageid,名字,其他东西

表车辆 - 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 等。

于 2013-02-09T20:56:40.007 回答
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)
);
于 2013-02-09T16:55:50.893 回答
0

您可以存储所有可能的车库是一个单独的表车库。然后将所有可能组合的车辆存储在 Vehicles 表中。在车辆表中添加一个引用的外键列

create table vehicle(column1,column2...,garageid foreign key references garage)

然后要选择单个车库中的所有车辆,可以查询车辆表

select * from vehicle where garage='garage_value'
于 2013-02-09T16:56:48.343 回答