设计可以引用多个其他表的数据库表

时间:2018-03-25 17:52:48

标签: sql postgresql database-design

设置

我有两张Postgres 10表格,这些表格有些相似但远非相同:

MotorVehicles
 Id (auto-incrementing int)
 PaintColor (varchar; not null)
 EngineSize (int; not null)
 Capacity (int)

Trailers
 Id (auto-incrementing int)
 PaintColor (varchar; not null)
 AttachedVehicle (int; not null; foreign key referring to MotorVehicles Id)
 Capacity (int)

两者都是路上的东西,并且有一些共同的属性,虽然一个明显地附着在另一个上(一辆卡车可以有多个预告片 - 至少就我的目的而言 - 预告片本身不应该存在)。

我试图设计一个适用于MotorVehicleTrailerLicensePlates的事物表。

LicensePlates
 PlateNumber (varchar; not null)
 Issuer (varchar)
 ExpirationDate (timestamp)
 ... some kind of reference to the above tables ...

我不确定如何完成LicensePlates表格,因为MotorVehiclesTrailers之间没有唯一标识符(例如,每个人都可以拥有ID号为1的行,这些内容不一样,因此ParentId}中只能包含LicensePlates属性。

约束

任何给定的LicensePlate类行必须引用一个 MotorVehicle或Trailer,但不能同时引用两者,而不是两者。但是,给定的MotorVehicle或Trailer 可能有多个牌照(例如,一个来自加拿大,一个来自欧洲国家);甚至根本没有盘子(如果它刚刚出厂,尚未注册或存放)。

选项

我应该如何设计LicensePlates我想出了一些选择:

  • MotorVehiclesTrailers合并到一个ThingsOnTheRoad表中,这样ID就不会发生冲突
    • 我反对这样做,因为每个现有的表都有一些不会对另一个产生语义感的属性,加上这会干扰约束
  • LicensePlates中,将相关表格中的ID保存在一列中,并将其引用的表格保存在另一列中
    • 这似乎是最直接的,但也非常不优雅。
  • 创建一个跨越两个表的自动递增列,因此永远不会出现ID号冲突
    • what I've read开始,这实际上是不可能的,加上可能会有一些令人头疼的问题,即使它是独一无二的,也要知道ID属于哪个表格
  • 用GUID替换现有的自​​动增量ID
    • 可以工作,但有人类可读性的混乱
  • 以某种方式合并视图中的MotorVehiclesTrailers以获得第二个选项的所有好处,但没有任何缺点
    • 这看起来很吸引人,但我对如何实际设置起来并不是最模糊的想法

那我该怎么做?我还没有其他选择吗?特别是,是否可以设置我上次提到的视图,如果是,如何设置?

(正如你可能已经猜到的那样,这些不是我的真实表格,但他们确实模拟了这段关系的重点。)

2 个答案:

答案 0 :(得分:3)

第二种选择是完美的,它被称为多态关系。我在少数铁路应用中广泛使用的概念就是满足这些要求。

简而言之,LicencePlates表应包含两列,VehicleIDVehicleTypeVehicleID存储MotorVehiclesTrailersVehicleType的ID的位置可以引用从中引用ID的表。

这种方法有很多优点。

  1. 明确性 - 您知道正在引用哪个表,以及id。
  2. 简单 - 非常简单,您不必管理ID,GUID,序列等。数据库擅长管理ID等某些内容,使用它,不要低估它。< / LI>
  3. 可维护性 - 不仅在代码级别,而且还有附加的概念 - 将LicencePlate分离到特定资源(Trailer / MotorVehicle)很容易维护。两者都是在道路上行驶的车辆,但具有不同的用途,访问模式,信息,验证等等。

答案 1 :(得分:1)

Postgres只需要inheritance

基本上,trailersmovingvehicles都应该来自另一个表格 - 比如licensablevehicles

然后,您可以与两个原始表或licensablevehicles建立外键关系。