sql >> Databáze >  >> RDS >> Mysql

MySQL - design supertypu/podtypu

Než začnu, chci upozornit, že „plyn“ popisuje buď palivo, nebo druh motoru, nikoli druh sedanu. Pořádně se zamyslete, než budete pokračovat touto cestou. (Sémantika je při návrhu databáze důležitější, než si většina lidí myslí.)

To, co chcete udělat, je poměrně jednoduché, ale ne nutně snadné. Důležitým bodem tohoto typu designu supertypu/podtypu (také známého jako exkluzivní oblouk) je znemožnit vytváření řádků o sedanech odkazujících na řádky o návěsech atd.

MySQL dělá kód podrobnější, protože nevynucuje omezení CHECK. Máte štěstí; ve vaší aplikaci mohou být omezení CHECK nahrazena dalšími tabulkami a omezeními cizího klíče. Komentáře odkazují na SQL výše je.

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

To je věc, kterou bych mohl implementovat jako omezení CHECK na jiných platformách. Můžete to udělat, když je uživatelům zřejmý význam kódů. Očekával bych, že uživatelé budou vědět nebo zjistí, že 's' je pro semi a 'c' je pro auta, nebo že zobrazení/kód aplikace by před uživateli kódy skryl.

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

Omezení UNIQUE umožňuje dvojici sloupců {veh_id, veh_type_code} být cílem odkazu na cizí klíč. To znamená, že řádek „auto“ nemůže odkazovat na řádek „polo“, a to ani omylem.

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

Něco jiného bych implementoval jako omezení CHECK na jiných platformách. (Viz níže.)

insert into veh_type_is_car values ('c');

Vždy pouze jeden řádek.

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

Výchozí hodnota pro veh_type_code spolu s odkazem na cizí klíč na veh_type_is_car zaručuje, že tyto řádky v této tabulce mohou být pouze o autech a mohou pouze referenční vozidla, kterými jsou automobily. Na jiných platformách bych pouze deklaroval sloupec veh_type_code jako 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');

Pokud musíte sestavit další tabulky, které odkazují na sedany, jako jsou gas_sedans, diesel_sedans atd., musíte sestavit jednořádkové tabulky podobné "veh_type_is_car" a nastavit na ně odkazy na cizí klíče.

V produkci bych zrušil oprávnění k základním tabulkám a buď použil

  • aktualizovatelná zobrazení pro vkládání a aktualizace, nebo
  • uložené procedury pro vkládání a aktualizace.


  1. Jak získat aktuální týdenní data v MySQL

  2. Jak změnit datový adresář MySQL?

  3. SQL Server 2016 v systému Linux

  4. Jak získat přístup k datové/datové složce v zařízení Android?