sql >> データベース >  >> RDS >> PostgreSQL

SQLデータベーステーブルのポリモーフィズム?

    問題は、1つのサブタイプの1つのオブジェクトだけが、親クラスの任意の行を参照するようにすることです。 @Jay Sの例から始めて、これを試してください:

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

    これは、@mikegによって言及された互いに素なサブタイプの例です。

    @Countably Infiniteと@Peterによるコメントを再確認してください:

    2つのテーブルへのINSERTには、2つの挿入ステートメントが必要です。しかし、これは、子テーブルがある場合はいつでもSQLにも当てはまります。普通のことです。

    UPDATEには2つのステートメントが必要な場合がありますが、一部のブランドのRDBMSは、JOIN構文を使用したマルチテーブルUPDATEをサポートしているため、1つのステートメントで実行できます。

    データをクエリするときは、mediaをクエリするだけで実行できます。 共通列に関する情報のみが必要な場合は、表:

    SELECT name, url FROM media WHERE media_id = ?
    

    映画をクエリしていることがわかっている場合は、1回の結合で映画固有の情報を取得できます:

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

    特定のメディアエントリの情報が必要で、そのタイプがわからない場合は、そのようなサブタイプテーブルが1つだけ一致することを知って、すべてのサブタイプテーブルに参加する必要があります。

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

    指定されたメディアが映画の場合、t.*のすべての列 NULLになります。



    1. テキストとvarcharの違い(文字が異なります)

    2. スクリプトが機能する場合、Postgres now()のタイムスタンプは変更されません

    3. SCDタイプ6

    4. SQLServerの挿入例