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

标签 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)

两者都是在路上行驶的东西,并且有一些共同的属性,尽管一个明显地依附于另一个(一辆卡车可以有多个拖车,而且——至少就我的目的而言——一个拖车不应该单独存在)。

我正在尝试设计一个可应用于 MotorVehicleTrailer 的事物表:LicensePlates

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

我不确定如何完成 LicensePlates 表,因为 MotorVehiclesTrailers 之间没有唯一标识符(例如,它们可以每个都有 ID 号为 1 的行,这些东西不会相同,所以我不能在 LicensePlates 中只有一个 ParentId 属性。

约束

任何给定的 LicensePlate 类型行必须引用恰好一个机动车或拖车,但不能同时引用两者,也不能两者都引用。但是,给定的机动车或拖车可能有多个牌照(例如,一个来自加拿大省,一个来自欧洲国家);甚至根本没有印版(如果它是刚从工厂出来但尚未注册或存储的)。

选项

我实际上应该如何设计 LicensePlates我想出了几个选项:

  • MotorVehiclesTrailers 合并到一个 ThingsOnTheRoad 表中,这样 ID 就不会冲突
    • 我反对这样做,因为每个现有表都有一些对另一个表没有语义意义的属性,而且这会干扰约束
  • LicensePlates 中,将相关表中的 ID 保存在一列中,将其引用的表保存在另一列中
    • 这似乎是最直接的,但也很不优雅。
  • 创建一个跨越两个表的自动递增列,因此永远不会有 ID 号冲突
    • 来自 what I've read ,这实际上是不可能的,而且即使它是唯一的,也可能会让人头疼地弄清楚该 ID 属于哪个表
  • 用 GUID 替换现有的自​​动递增 ID
    • 可以工作,但会影响人类的可读性
  • 以某种方式合并 MotorVehiclesTrailers 以获得第二个选项的所有好处,但没有缺点
    • 这看起来很吸引人,但我对如何实际设置它一无所知

那我到底在做什么呢?还有其他我没有列出的选项吗?特别是,是否可以设置我最后提到的 View ,如果可以,如何设置?

(您可能已经猜到了,这些不是我的真实表格,但它们确实模拟了关系的要点。)

最佳答案

第二种选择是完美的,它被称为多态关系。我在我的几个 Rails 应用程序中广泛使用的概念来满足此类需求。

简而言之,LicencePlates 表应该有两列,VehicleIDVehicleTypeVehicleID 存储 MotorVehiclesTrailers 的 id,VehicleType 可以引用从中引用 id 的表.

这种方法有很多优点。

  1. 明确性 - 您知道所引用的表和 ID。
  2. 简单 - 它非常简单,您不必管理 ID、GUID、它们的序列等。DB 擅长管理某些东西,例如 ID,使用它,不要低估它。
  3. 可维护性 - 不仅在代码层面,还有附加概念 - 将 LicencePlate 分离到特定资源(Trailer/MotorVehicle)很容易维护。两者都是在道路上行驶的车辆,但具有不同的用途、访问模式、信息、验证等。

关于sql - 设计可以引用多个其他表的数据库表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49479011/

相关文章:

java - 如何使用 Java 将 JPEG 图像插入 PostgreSQL bytea 字段,然后使用 PHP 显示在网站上?

mysql - 数据库 : aggregation vs storing pre computed data for lookup in large data store?

mysql - 如何对可以具有 1-M 个多个实体的实体建模?

mysql - 通过 UNION ALL 中的两个字段进行选择并在行之间排序

sql - Postgres无限 self 加入

ruby-on-rails - 按计数查询加快 Active Record 组

java - 使用 SQL 中的关键字对搜索结果进行排名

java - Apache Derby : how can I do "insert if not exists"?

mysql - 一行sql中来自不同表的行

sql - 删除在另一个表中没有匹配项的记录