私は、データベース設計と呼ばれるこの難解なものを理解しようとしていますが、あまりうまくいっていないので、例を挙げて自分の問題を説明してみたいと思います。
私は MySQL を使用していますが、質問は次のとおりです。
たとえば、DVD コレクションを保存するためのデータベースを作成したいとします。次の情報を含めたいと考えています。
- 映画のタイトル
- 俳優
- 実行時間
- ジャンル
- 説明
- 年
- 監督
効率を上げるために、これらの間に関係を作成したいのですが、方法がわかりません。
データベース設計について私が考えていることは次のとおりです。
映画テーブル => 映画ID、映画タイトル、上映時間、説明
年表 => 年
ジャンル表 => ジャンル
ディレクターテーブル => ディレクター
俳優テーブル => actor_name
しかし、これらのテーブル間の関係を作成するにはどうすればよいでしょうか?
また、自動的に増加する主キーを持つ Films テーブルに一意の ID を作成しましたが、各テーブルに一意の ID を作成する必要がありますか?
そして最後に、PHP フォームを通じて新しい映画をデータベースに更新する場合、このすべてのデータ (関係性などすべてを含む) をどのように挿入するのでしょうか。
何か助けていただければ幸いです、キース
ベストアンサー1
属性とエンティティを区別する必要があります。エンティティは物であり、通常は名詞です。属性は、情報を説明するもののようなものです。データベースの専門用語では、エンティティ = テーブル、属性 = フィールド/列です。
特定のもの (ここではディレクターを使用) 用に別のテーブルを用意することを正規化と呼びます。これは状況によっては良いこともありますが、他の場合には不要な場合があります (一般的にクエリが複雑になり、すべてを結合する必要があり、速度が遅くなるため)。
この場合、年自体以外に保存する年に関する属性はないので、年テーブルは不要です。これを非正規化し、年をフィルム テーブル自体に保存する方が適切です。
一方、監督は異なります。監督の名、姓、生年月日、死亡日 (該当する場合) などを保存したい場合があります。当然、この人物が監督した映画を入力するたびに監督の生年月日を入力したくないので、監督用に別のエンティティを用意するのが理にかなっています。
監督に関するすべての情報を保存したくない (名前だけが必要な場合) 場合でも、別のテーブルを用意すると (代理キーを使用する - これについては後で説明します)、入力ミスや重複を防ぐことができるので便利です。名前のスペルが間違っていたり、別の形式で入力されていたり (名、姓と姓、名) すると、その人が監督した他の映画を検索しようとしても、検索に失敗します。
テーブルに代理キー (主キー) を使用するのは、一般的に良いアイデアです。整数のマッチングは、文字列のマッチングよりもはるかに高速です。また、他のテーブルに保存されている外部キーを気にすることなく、自由に名前を変更することもできます (ID は同じままなので、何もする必要はありません)。
このデザインは実にさまざまな可能性を秘めており、何を収納したいかを考えるだけで十分です。
たとえば、映画ごとに監督が 1 人ではなく、複数の監督がいる映画もあります。そのため、映画と監督の間には多対多の関係があり、次のようなテーブルが必要になります。
films_directors => **filmid, directorid**
さらに一歩進んで、監督が俳優を兼ねる場合もあり、その逆もあります。そのため、監督と俳優のテーブルを用意するのではなく、1 つの人物テーブルを用意し、役割テーブルを使用してそのテーブルを結合することができます。役割テーブルには、監督、プロデューサー、主演、エキストラ、グリップ、編集者など、さまざまな役職が保持され、次のようになります。
films => **filmid**, title, otherstuff...
people => **personid**, name, ....
roles => **roleid**, role name, ....
film_people => **filmid, personid, roleid**
genre => **genreid**, name, ...
film_genre => **genreid, filmid**
また、film_people テーブルに role_details フィールドがあり、役割に応じて追加の情報 (俳優が演じている役の名前など) が含まれる場合もあります。
また、映画が複数のジャンルに属する可能性があるため、ジャンルを多<>多の関係として表示しています。これを望まない場合は、film_genre テーブルの代わりに、films にジャンル ID のみが含まれます。
これを一度設定すると、特定の人物が行ったすべてのこと、監督として行ったすべてのこと、映画を監督したことがあるすべての人、特定の映画に関わったすべての人などを照会して見つけることが容易になります。