Antes de começar, quero salientar que "gás" descreve combustível ou um tipo de motor, não um tipo de sedã. Pense bem antes de continuar seguindo esse caminho. (A semântica é mais importante no design de banco de dados do que a maioria das pessoas pensa.)
O que você quer fazer é bastante simples, mas não necessariamente fácil. O ponto importante neste tipo de design de supertipo/subtipo (também conhecido como arco exclusivo) é tornar impossível ter filas sobre sedãs referenciando filas sobre semi-caminhões, etc.
O MySQL torna o código mais detalhado, porque não impõe restrições CHECK. Você é sortudo; em seu aplicativo, as restrições CHECK podem ser substituídas por tabelas adicionais e restrições de chave estrangeira. Os comentários referem-se ao SQL acima eles.
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');
Esse é o tipo de coisa que eu poderia implementar como uma restrição CHECK em outras plataformas. Você pode fazer isso quando o significado dos códigos for óbvio para os usuários. Eu esperaria que os usuários soubessem ou descobrissem que 's' é para semis e 'c' é para carros, ou que o código de visualização/aplicativo ocultaria os códigos dos usuários.
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)
);
A restrição UNIQUE permite que o par de colunas {veh_id, veh_type_code} seja o destino de uma referência de chave estrangeira. Isso significa que uma linha "carro" não pode referenciar uma linha "semi", mesmo por engano.
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)
);
Outra coisa que eu implementaria como uma restrição CHECK em outras plataformas. (Ver abaixo.)
insert into veh_type_is_car values ('c');
Apenas uma linha de sempre.
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)
);
O valor padrão para veh_type_code, juntamente com a referência de chave estrangeira para veh_type_is_car, garante que essas linhas nesta tabela possam ser apenas sobre carros e somente veículos de referência que são carros. Em outras plataformas, eu apenas declararia a coluna veh_type_code como
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');
Se você tiver que construir tabelas adicionais que referenciam sedans, como gas_sedans, diesel_sedans, etc., então você precisa construir tabelas de uma linha semelhantes a "veh_type_is_car" e definir referências de chave estrangeira para elas.
Na produção, eu revogaria as permissões nas tabelas base e usaria
- visualizações atualizáveis para fazer as inserções e atualizações, ou
- procedimentos armazenados para fazer as inserções e atualizações.