sql >> Databáze >  >> RDS >> PostgreSQL

Polymorfismus v SQL databázových tabulkách?

Správně, problém je v tom, že chcete, aby pouze jeden objekt jednoho podtypu odkazoval na jakýkoli daný řádek nadřazené třídy. Počínaje příkladem, který uvedl @Jay S, zkuste toto:

create table media_types (
  media_type     int primary key,
  media_name     varchar(20)
);
insert into media_types (media_type, media_name) values
  (2, 'TV series'),
  (3, 'movie');

create table media (
  media_id       int not null,
  media_type     not null,
  name           varchar(100),
  description    text,
  url            varchar(255),
  primary key (media_id),
  unique key (media_id, media_type),
  foreign key (media_type) 
    references media_types (media_type)
);

create table tv_series (
  media_id       int primary key,
  media_type     int check (media_type = 2),
  season         int,
  episode        int,
  airing         date,
  foreign key (media_id, media_type) 
    references media (media_id, media_type)
);

create table movies (
  media_id       int primary key,
  media_type     int check (media_type = 3),
  release_date   date,
  budget         numeric(9,2),
  foreign key (media_id, media_type) 
    references media (media_id, media_type)
);

Toto je příklad disjunktních podtypů zmíněných @mike g.

Komentáře od @Countably Infinite a @Peter:

INSERT do dvou tabulek by vyžadoval dva příkazy vložení. Ale to platí také v SQL, kdykoli máte podřízené tabulky. Je to běžná věc.

UPDATE může vyžadovat dva příkazy, ale některé značky RDBMS podporují UPDATE s více tabulkami se syntaxí JOIN, takže to můžete provést jedním příkazem.

Při dotazování na data to můžete udělat jednoduše dotazem na media pokud potřebujete pouze informace o běžných sloupcích:

SELECT name, url FROM media WHERE media_id = ?

Pokud víte, že se dotazujete na film, můžete získat informace specifické pro film jediným spojením:

SELECT m.name, v.release_date
FROM media AS m
INNER JOIN movies AS v USING (media_id)
WHERE m.media_id = ?

Pokud chcete informace pro daný záznam média a nevíte, o jaký typ se jedná, museli byste se připojit ke všem tabulkám podtypů s vědomím, že bude odpovídat pouze jedna taková tabulka podtypů:

SELECT m.name, t.episode, v.release_date
FROM media AS m
LEFT OUTER JOIN tv_series AS t USING (media_id)
LEFT OUTER JOIN movies AS v USING (media_id)
WHERE m.media_id = ?

Pokud je daným médiem film, pak všechny sloupce v t.* bude NULL.



  1. Oracle UTL_SMTP:Příklad odeslání pošty s přílohou pomocí ověřování Oracle Wallet Authentication

  2. Vložit více řádků do chyby SQLite (kód chyby =1)

  3. Výlet přes GIMR

  4. Jak funguje justify_days() v PostgreSQL