sql >> Databasteknik >  >> RDS >> PostgreSQL

Polymorfism i SQL-databastabeller?

Okej, problemet är att du bara vill att ett objekt av en undertyp ska referera till en given rad i den överordnade klassen. Utgå från exemplet från @Jay S, prova detta:

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

Det här är ett exempel på de disjunkta undertyper som nämns av @mike g.

Om kommentarer av @Countably Infinite och @Peter:

INSERT till två tabeller skulle kräva två insert-satser. Men det är också sant i SQL när du har underordnade tabeller. Det är en vanlig sak att göra.

UPDATE kan kräva två satser, men vissa märken av RDBMS stöder UPDATE för flera tabeller med JOIN-syntax, så du kan göra det i en sats.

När du frågar efter data kan du göra det helt enkelt genom att fråga media tabell om du bara behöver information om de vanliga kolumnerna:

SELECT name, url FROM media WHERE media_id = ?

Om du vet att du frågar efter en film kan du få filmspecifik information med en enda anslutning:

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

Om du vill ha information för en given mediepost, och du inte vet vilken typ det är, måste du gå med i alla dina undertypstabeller, i vetskap om att endast en sådan undertypstabell matchar:

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 = ?

Om det givna mediet är en film, är alla kolumner i t.* kommer att vara NULL.



  1. Så här löser du ORA-29283:ogiltig filoperation

  2. Vilken är den idealiska datatypen att använda när du lagrar latitud/longitud i en MySQL-databas?

  3. Begränsa dataflexibilitet i en NoSQL-databas

  4. ladda dataspinner från sqlite och mysql