我需要创建以下数据库:
对于半卡车我不需要额外的亚型,而对于Car我只需要那3种亚型而且对于轿车我也需要四种亚型。 对于SELECT,我将使用JOIN(规范化数据库),但我需要找到一种简单的方法来进行INSERT。
我需要完全按照图中的方式创建此数据库。
到目前为止,我的第一种方法是使用以下表格:
我的问题是,我不确定这是不正确的方法,而且我也不确切知道如何在表格之间建立关系。
有什么想法吗?
谢谢!
更新
以下图表基于@Mike的回答:
答案 0 :(得分:7)
在我开始之前,我想指出“气体”描述燃料或某种发动机,而不是一种轿车。在继续沿着这条路走下去之前要认真思考。 (语义学在数据库设计中比大多数人想象的更重要。)
您想要做的事情相当简单,但不一定容易。这种超类型/子类型设计(也称为专用弧)的重要一点是,不能让关于轿车的行引用关于半卡车等的行。
MySQL使代码更加冗长,因为它不强制执行CHECK约束。你很幸运;在您的应用程序中,CHECK约束可以由其他表和外键约束替换。注释引用它们上面的SQL 。
create table vehicle_types (
veh_type_code char(1) not null,
veh_type_name varchar(10) not null,
primary key (veh_type_code),
unique (veh_type_name)
);
insert into vehicle_types values
('s', 'Semi-truck'), ('c', 'Car');
这可能是我在其他平台上作为CHECK约束实现的。当代码的含义对用户来说很明显时,您就可以这样做。我希望用户知道或者发现's'适用于半成品而'c'适用于汽车,或者视图/应用程序代码会隐藏用户的代码。
create table vehicles (
veh_id integer not null,
veh_type_code char(1) not null,
other_columns char(1) default 'x',
primary key (veh_id),
unique (veh_id, veh_type_code),
foreign key (veh_type_code) references vehicle_types (veh_type_code)
);
UNIQUE约束允许列对{veh_id,veh_type_code}成为外键引用的目标。这意味着“汽车”行不可能引用“半”行,即使是错误的。
insert into vehicles (veh_id, veh_type_code) values
(1, 's'), (2, 'c'), (3, 'c'), (4, 'c'), (5, 'c'),
(6, 'c'), (7, 'c');
create table car_types (
car_type char(3) not null,
primary key (car_type)
);
insert into car_types values
('Van'), ('SUV'), ('Sed');
create table veh_type_is_car (
veh_type_car char(1) not null,
primary key (veh_type_car)
);
我在其他平台上实现的CHECK约束。 (见下文。)
insert into veh_type_is_car values ('c');
只有一行。
create table cars (
veh_id integer not null,
veh_type_code char(1) not null default 'c',
car_type char(3) not null,
other_columns char(1) not null default 'x',
primary key (veh_id ),
unique (veh_id, veh_type_code, car_type),
foreign key (veh_id, veh_type_code) references vehicles (veh_id, veh_type_code),
foreign key (car_type) references car_types (car_type),
foreign key (veh_type_code) references veh_type_is_car (veh_type_car)
);
veh_type_code的默认值以及对veh_type_is_car的外键引用保证此表中的这些行只能是汽车,并且仅引用汽车的车辆。在其他平台上,我只是将栏目veh_type_code声明为veh_type_code char(1) not null default 'c' check (veh_type_code = 'c')
。
insert into cars (veh_id, veh_type_code, car_type) values
(2, 'c', 'Van'), (3, 'c', 'SUV'), (4, 'c', 'Sed'),
(5, 'c', 'Sed'), (6, 'c', 'Sed'), (7, 'c', 'Sed');
create table sedan_types (
sedan_type_code char(1) not null,
primary key (sedan_type_code)
);
insert into sedan_types values
('g'), ('d'), ('h'), ('e');
create table sedans (
veh_id integer not null,
veh_type_code char(1) not null,
car_type char(3) not null,
sedan_type char(1) not null,
other_columns char(1) not null default 'x',
primary key (veh_id),
foreign key (sedan_type) references sedan_types (sedan_type_code),
foreign key (veh_id, veh_type_code, car_type) references cars (veh_id, veh_type_code, car_type)
);
insert into sedans (veh_id, veh_type_code, car_type, sedan_type) values
(4, 'c', 'Sed', 'g'), (5, 'c', 'Sed', 'd'), (6, 'c', 'Sed', 'h'),
(7, 'c', 'Sed', 'e');
如果你必须构建引用轿车的其他表,例如gas_sedans,diesel_sedans等,那么你需要构建一个类似于“veh_type_is_car”的单行表,并为它们设置外键引用。
在生产中,我将撤销对基表的权限,并使用
答案 1 :(得分:3)
我推荐您使用以下三个标签下的“信息”标签:
class-table-inheritance single-table-inheritance shared-primary-key
前两个描述了在设计关系数据库时处理类/子类(aka类型/子类型)情况的两种主要设计模式。第三种方法描述了一种使用单个主键的技术,该主键在超类表中分配并传播到子类表。
他们并没有完全回答你提出的问题,但他们对整个主题有所了解。这个模仿SQL中继承的主题在SO和DBA领域都反复出现。