Mysql 如何在数据库中模拟标记的联合?

Mysql 如何在数据库中模拟标记的联合?,mysql,database,sqlite,postgresql,Mysql,Database,Sqlite,Postgresql,在数据库中进行仿真的最佳方式是什么? 我说的是这样的事情: create table t1 { vehicle_id INTEGER NOT NULL REFERENCES car(id) OR motor(id) -- not valid ... } 其中vehicle_id将是car table或motor table中的id,并且它将知道是哪个 (假设motor和car表没有共同点0一些人使用一种称为多态关联的设计来实现这一点,允许vehicle\u id包含一个存在于car或m

在数据库中进行仿真的最佳方式是什么? 我说的是这样的事情:

create table t1 {
  vehicle_id INTEGER NOT NULL REFERENCES car(id) OR motor(id) -- not valid
  ...
}
其中vehicle_id将是car table或motor table中的id,并且它将知道是哪个


(假设motor和car表没有共同点0

一些人使用一种称为多态关联的设计来实现这一点,允许
vehicle\u id
包含一个存在于
car
motor
表中的值。然后添加一个
vehicle\u type
来命名
t1中给定行所在的表e> 参考资料

CREATE TABLE vehicle (type INT NOT NULL, id INT NOT NULL,
             PRIMARY KEY (type, id)
)

CREATE TABLE car (type INT NOT NULL DEFAULT 1, id INT NOT NULL PRIMARY KEY,
             CHECK(type = 1),
             FOREIGN KEY (type, id) REFERENCES vehicle
)

CREATE TABLE motorcycle (type INT NOT NULL DEFAULT 2, id INT NOT NULL PRIMARY KEY,
             CHECK(type = 2),
             FOREIGN KEY (type, id) REFERENCES vehicle
)

CREATE TABLE t1 (
  ...
  vehicle_type INT NOT NULL,
  vehicle_id INT NOT NULL,
  FOREIGN KEY (vehicle_type, vehicle_id) REFERENCES vehicle
  ...
)
问题在于,如果您这样做,就无法声明真正的SQL外键约束。SQL中不支持具有多个引用目标的外键。还有其他问题,但缺少引用完整性已经是一个问题

更好的设计是借用OO设计中的概念,即
汽车
电机

CREATE TABLE Identifiable (
 id SERIAL PRIMARY KEY
);
然后使
t1
引用此超级类型表:

CREATE TABLE t1 (
  vehicle_id INTEGER NOT NULL,
  FOREIGN KEY (vehicle_id) REFERENCES identifiable(id)
  ...
);
并使子类型引用其父超类型。请注意,子类型的主键不是自动递增的。父超类型负责分配新的id值,子类型仅引用该值

CREATE TABLE car (
  id INTEGER NOT NULL,
  FOREIGN KEY (id) REFERENCES identifiable(id)
  ...
);

CREATE TABLE motor (
  id INTEGER NOT NULL,
  FOREIGN KEY (id) REFERENCES identifiable(id)
  ...
);
现在,您可以拥有真正的引用完整性,但也支持具有自己属性的多个子类型表



@Quassnoi的答案还显示了一种强制执行不相交子类型的方法。也就是说,您希望防止
car
motor
引用其父超类型表中的同一行。执行此操作时,我对
可识别的.id
使用单列主键,但也要在上声明一个
唯一的
键ode>可识别。(id,类型)
汽车
电机
中的外键可以引用两列唯一键,而不是主键。

我认为您可以使用

如果确实需要知道查询中的行来自何处,可以使用简单的UNION ALL语句,如(这种可能性与表继承无关):


如果您将
VEHICLE.VEHICLE\u ID
定义为主键,那么您就不必引用复合键,并且可以使用唯一的约束设置type&ID列。
@OMG Ponies:
使用此布局,您根本不需要引用
VEHICLE
。您只需加入
cars
motorcycle即可es
,取决于
类型
车辆
,此处仅用于监控关系。使用此方法,是否有某种方法可以确保不会出现“孤立”在
汽车
摩托车
中没有相应行的车辆?只有当查询需要选择
可识别
中的属性时,
可识别
的代理键才有效。如果
可识别
仅用于强制约束,则使用复合键将允许获得我自己提出并使用了“通用超类型”方法,并成功地将其应用于大型系统迁移/再开发项目中。(新西兰政府,教育部SPOT25)
SELECT car.*, 'car' table_name
UNION ALL
SELECT motor.*, 'motor' table_name