23

現在、データベースには次のような同じ「基本フィールド」で構成される複数のテーブルがあります。

name character varying(100),
description text,
url character varying(255)

しかし、私はその基本的なテーブルの複数の特殊化を持っています。たとえば、テーブルには、、などtv_seriesのフィールドがあります。seasonepisodeairingmoviesrelease_datebudget

linkgroups最初はこれは問題ではありませんが、これらの特殊なテーブルへの外部キーで呼び出される 2 番目のテーブルを作成したいと考えています。つまり、何らかの形でそれ自体を正規化する必要があります。

私が聞いたこれを解決する1つの方法は、key-valueペアテーブルで正規化することですが、それは一種の「データベース内のデータベース」スキームであるため、私には方法がありません。特定のキー/フィールドを要求したり、特別なタイプを要求したりする必要はありません。後でデータを取得して注文するのは非常に面倒です。

したがって、複数のテーブル間で主キーを「共有」する方法、またはそれ以上の方法を探しています。一般的なテーブルと複数の特殊なテーブルを使用して正規化する方法です。

4

7 に答える 7

26

そうです、問題は、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)
);

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


@Countably Infinite と @Peter による再コメント:

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

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

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

SELECT name, url FROM media WHERE media_id = ?

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

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 になります。

于 2009-02-18T17:18:08.530 に答える
8

メインの基本データ テーブルを使用し、テーブルから拡張して特殊な情報を追加することを検討してください。

元。

basic_data
id int,
name character varying(100),
description text,
url character varying(255)


tv_series
id int,
BDID int, --foreign key to basic_data
season,
episode
airing


movies
id int,
BDID int, --foreign key to basic_data
release_data
budget
于 2009-02-18T15:47:56.407 に答える
3

このPostgreSQLにタグを付けたので、http: //www.postgresql.org/docs/8.1/static/ddl-inherit.htmlを見ることができますが、注意が必要です。

于 2009-02-18T23:06:26.197 に答える
2

あなたが探しているものは、リレーショナルの世界では「ばらばらのサブタイプ」と呼ばれています。これらは言語レベルでは sql でサポートされていませんが、多かれ少なかれsql の上に実装できます。

于 2009-02-18T17:03:27.753 に答える
1

質問はかなり古いですが、最新の postresql バージョンでは、json/jsonb/hstore タイプの使用も検討する価値があります。例えば:

create table some_table (
    name character varying(100),
    description text,
    url character varying(255),
    additional_data json
);
于 2015-05-05T13:10:21.263 に答える
1

Bill Karwin によって提案されたばらばらのサブタイプのアプローチを使用して、INSERT と UPDATE を 2 つのステップで実行することなく、どのように実行しますか?

データを取得すると、特定の media_type に基づいて結合および選択するビューを導入できますが、複数のテーブルに影響するため、そのビューに更新または挿入することはできません (ここでは MS SQL Server について話している)。これは、当然のことながら、2 つの操作を実行せずに、またストアド プロシージャを使用せずに実行できますか。

ありがとう

于 2010-05-13T00:51:36.317 に答える
1

メイン フィールドと uid を持つ 1 つのテーブルを作成し、特定のケースごとに同じ uid を持つ拡張テーブルを作成できます。これらを個別のテーブルのようにクエリするには、ビューを作成できます。

于 2009-02-18T15:44:56.977 に答える