sql >> Database >  >> RDS >> Mysql

MySQL - Supertype/Subtype-ontwerp

Voordat ik begin, wil ik erop wijzen dat "gas" brandstof of een soort motor beschrijft, niet een soort sedan. Denk goed na voordat je dit pad blijft volgen. (Semantiek is belangrijker bij het ontwerpen van databases dan de meeste mensen denken.)

Wat je wilt doen is vrij eenvoudig, maar niet per se gemakkelijk. Het belangrijkste punt bij dit soort supertype/subtype-ontwerp (ook bekend als een exclusieve boog) is om het onmogelijk te maken om rijen over sedans te hebben die verwijzen naar rijen over semi-vrachtwagens, enz.

MySQL maakt de code uitgebreider, omdat het geen CHECK-beperkingen oplegt. Jij hebt geluk; in uw toepassing kunnen de CHECK-beperkingen worden vervangen door extra tabellen en externe-sleutelbeperkingen. Opmerkingen verwijzen naar de SQL hierboven hen.

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');

Dit is het soort dingen dat ik zou kunnen implementeren als een CHECK-beperking op andere platforms. U kunt dat doen wanneer de betekenis van de codes voor gebruikers duidelijk is. Ik zou verwachten dat gebruikers weten of erachter komen dat 's' voor halve finales is en 'c' voor auto's, of dat weergaven/applicatiecode de codes voor gebruikers zouden verbergen.

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)
);

De UNIQUE-beperking laat het paar kolommen {veh_id, veh_type_code} het doel zijn van een refererende sleutelreferentie. Dat betekent dat een "auto"-rij onmogelijk kan verwijzen naar een "halve" rij, zelfs niet per ongeluk.

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)
);

Iets anders dat ik zou implementeren als een CHECK-beperking op andere platforms. (Zie hieronder.)

insert into veh_type_is_car values ('c');

Slechts één rij ooit.

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)
);

De standaardwaarde voor veh_type_code, samen met de refererende sleutelreferentie naar veh_type_is_car, garandeert dat deze rijen in deze tabel alleen over auto's kunnen gaan en alleen kunnen referentievoertuigen die auto's zijn. Op andere platforms zou ik de kolom veh_type_code gewoon declareren als 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');

Als u extra tabellen moet maken die verwijzen naar sedans, zoals gas_sedans, diesel_sedans, enz., dan moet u tabellen met één rij maken die vergelijkbaar zijn met "veh_type_is_car" en daar refererende sleutelverwijzingen naar instellen.

In productie zou ik de machtigingen voor de basistabellen intrekken en ofwel

. gebruiken
  • bijwerkbare weergaven om de invoegingen en updates te doen, of
  • opgeslagen procedures om de invoegingen en updates uit te voeren.


  1. Shuffle een string met mysql/sql

  2. Hoe NULL-waarden in datetime-velden in MySQL op te slaan?

  3. beste manier om 1:1 gebruikersrelaties op te slaan in een relationele database

  4. Hoe REPEAT() werkt in MariaDB