sql >> Database teknologi >  >> RDS >> PostgreSQL

Polymorfi i SQL-databasetabeller?

Okay, problemet er, at du kun vil have ét objekt af én undertype til at referere til en given række i den overordnede klasse. Start med eksemplet givet af @Jay S, prøv dette:

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

Dette er et eksempel på de usammenhængende undertyper nævnt af @mike g.

Om kommentarer af @Countably Infinite og @Peter:

INSERT til to tabeller ville kræve to insert-sætninger. Men det gælder også i SQL, hver gang du har underordnede tabeller. Det er en almindelig ting at gøre.

OPDATERING kan kræve to sætninger, men nogle mærker af RDBMS understøtter multi-table UPDATE med JOIN-syntaks, så du kan gøre det i én erklæring.

Når du forespørger data, kan du gøre det blot ved at forespørge på media tabel, hvis du kun har brug for information om de fælles kolonner:

SELECT name, url FROM media WHERE media_id = ?

Hvis du ved, at du forespørger på en film, kan du få filmspecifikke oplysninger med en enkelt join:

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

Hvis du vil have information om en given medieindgang, og du ikke ved, hvilken type det er, skal du tilslutte dig alle dine undertypetabeller, velvidende at kun én sådan undertypetabel vil matche:

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

Hvis det givne medie er en film, så er alle kolonner i t.* vil være NULL.



  1. Introduktion af ny funktion:Always On Availability Group

  2. Sådan ændres bruger til superbruger i PostgreSQL

  3. MySQL-forespørgsel, MAX() + GRUPPER EFTER

  4. Hvordan pg_typeof() virker i PostgreSQL