web-dev-qa-db-ja.com

映画データベースを設計するには?

私は、彼らがデータベースデザインと呼んでいる、この成功の余地のないものに頭を悩ませようとしているので、例を使って問題を説明しようと思います。

私はMySQLを使用していますが、ここに私の質問があります:

私のDVDコレクションを保持するデータベースを作成したいとします。含めたい次の情報があります。

  1. 映画のタイトル
  2. 俳優
  3. 実行時間
  4. ジャンル
  5. 説明文
  6. ディレクター

私はそれをより効率的にするためにこれらの間の関係を作成したいと思いますが、方法はわかりません。

これが私がデータベース設計について考えていることです:

フィルムテーブル=> filmid、filmtitle、runningtime、description

年表=>年

ジャンルテーブル=>ジャンル

Director Table => director

Actors Table => actor_name

しかし、これらのテーブル間の関係を作成するにはどうすればよいですか?

また、自動的に増分する主キーを使用して、Filmsテーブルに一意のIDを作成しました。各テーブルに一意のIDを作成する必要がありますか?

最後に、PHPフォームを介してデータベースに新しい映画を更新する場合、このデータのすべてを(関係とすべてとともに)にどのように挿入しますか?)

あなたが与えることができるあらゆる助けをありがとう、キース

22
Keith Donegan

属性とエンティティを区別する必要があります。エンティティはものです-通常名詞。属性は、記述情報のようなものです。データベースの専門用語では、エンティティ=テーブル、属性=フィールド/列。

特定のもののために別のテーブルを持っている場合、例として、directorを使用しましょう。これは正規化と呼ばれます。状況によっては良い場合もありますが、状況によっては不必要になる場合もあります(一般に、クエリが複雑になるため、すべてを結合する必要があり、速度が遅くなります)。

この場合、保存する年自体以外に、年に関する他の属性がないため、年テーブルを用意する必要はありません。これを非正規化し、年をフィルムテーブル自体に格納することをお勧めします。

一方、監督は違います。おそらく、監督の名、姓、生年月日、死亡日(該当する場合)などを保存したいでしょう。この人物が映画を入力するたびに、監督の生年月日を入力したくないのは明らかです。指示するので、ディレクター用に別のエンティティを持つことが理にかなっています。

ディレクターに関するこのすべての情報を保存したくなかったとしても(彼らの名前が必要なだけ)、別のテーブルを用意する(そして代理キーを使用する-すぐにそれを取得する)と便利です。誤植や重複を防ぎます-誰かの名前のスペルが間違っていたり、別の名前(最初、最後、最後、最初)を入力したりしている場合、監督が指示した他の映画を見つけようとすると失敗します。

一般に、テーブルに代理キー(主キー)を使用することをお勧めします。整数のマッチングは、文字列のマッチングよりもはるかに高速です。また、他のテーブルに格納されている外部キーを気にすることなく、名前を自由に変更できます(IDは同じままなので、何もする必要はありません)。


あなたは本当にこのデザインをかなり遠くに持って行くことができます、そしてそれはすべてあなたがそれに保存できるようにしたいものを理解することの問題です。

たとえば、映画ごとに1人の監督がいるのではなく、複数の監督がいる映画もあります。そのため、映画と監督の間には多対多の関係があるため、次のようなテーブルが必要になります。

films_directors => **filmid, directorid**

さらに一歩踏み込んで、監督が俳優になることもあれば、その逆もある。したがって、directorテーブルとactorテーブルを用意するのではなく、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テーブルの代わりに、フィルムにはgenreidのみが含まれます。

これが設定されると、特定の人物が行ったすべて、または監督として行ったすべてのこと、または映画を監督したすべての人、または特定の映画に関わるすべての人々を簡単にクエリして見つけることができます。それは何度も続くことができます。

60
gregmac

以下は実際のMySQLコードではありません。ここで必要なのは、概念的な出発点のようです。これが、データベースがどのように見えるかのモデルです。

俳優テーブル

  • id(主キー)
  • ファーストネーム
  • 苗字
  • など(アクターに格納する追加の列)

監督テーブル

  • id
  • ファーストネーム
  • 苗字
  • 等.

ジャンル表

  • id
  • 名前
  • 等.

フィルムテーブル

  • id
  • 題名
  • 解説
  • 実行時間
  • 発売日
  • director id-これは、映画を監督した監督のID(主キー)を参照する外部キーです。
  • ジャンルID-監督IDと同様に、これは映画が属するジャンルのIDを指します

俳優映画インデックステーブル

  • 映画ID-これは映画のIDを参照する外部キーです
  • actor id-これは、映画の1人の俳優のIDを参照する外部キーです。

映画の俳優ごとに、Actor-Film Indexに行を追加します。したがって、俳優5と13(これらの俳優の主キー)が映画4(ここでも、その映画の主キー)に出演している場合、インデックスにその事実を反映する2つの行があります。1つは映画ID = 4です。俳優ID = 5、映画ID = 4、俳優ID = 13の別のもの。

お役に立てば幸いです。

また、これは各映画に正確に1人の監督がいることを前提としています。ライブラリ内の映画に2人の監督がいる場合(Slumdog Millionaireなど)、監督IDを映画のテーブルから分離し、上記のように俳優映画インデックスのような監督映画インデックスを作成します。

21
Matt Howell

これらは私が使用するテーブルです:

films (_id_, title, runningtime, description)
genres (_id_, name)
people (_id_, name, birthdate, etc...)
roles (_roleid_, rolename)
filmgenres (_filmid_, _genreid_)
castandcrew (_filmid_, _roleid_, _personid_)

監督と俳優のテーブルを用意する代わりに、1つのテーブルだけを用意します。これには、クルーのメンバーを含めることもできます(2番目のジュニアアシスタントドリーグリップが誰であるかを追跡する場合)。各映画は、任意の数のジャンル(コメディーやホラーなど)にすることができます。さらに、人々は各映画でいくつもの役割を演じることができます-そこにはかなりの数の俳優/監督がいます。

Rolesテーブルは、俳優が演じているキャラクターを必ずしも意味するわけではありませんが、そうである可能性もあります。それを細かく取得したい場合は、「ディレクター」、「プロデューサー」、「俳優」、または「ルークスカイウォーカー」などです。

うまくいけば、上記のフィールドの名前が外部キーのヒントになるはずであり、_underscores_使用する主キーの周り。

11
nickf

Imdbスキーマ ここ をダウンロードできます。

4

Filmsテーブルには、ジャンル、ディレクター、俳優のテーブルへのリンクも必要です。俳優は少なくとも多対多になるため(1つの映画には複数の俳優がリストされ、1人の俳優は複数の映画に登場します)、それらをリンクするためのテーブルが必要になります。

Films Table => filmid, filmtitle, runningtime, description, genreid, directorid
Genre Table => genreid, genre
Director Table => directorid, director
Actors Table => actorid,actor_name
FilmActor link table => actorid, filmid (with a record linking each actor to each film)

多対多のテーブルには、リンクテーブルが必要です。

4
thursdaysgeek

Filmsテーブルに一意のIDを作成しましたが、主キーは自動的に増分されます。テーブルごとに一意のIDを作成する必要がありますか

はい、各テーブルmustには一意のIDがあります。ただし、これは必ずしも自動インクリメントの主キーではありません。特定のインスタンスを一意にするものは何でもかまいません。たとえば、映画の場合、タイトル+リリース年にするのが一般的だと思います。ただし、映画ファン(ドメインの専門家)に確認して確認してください。自動インクリメントはフォールバックです-基本的に、他に固有のものがない場合。

結合などで使いやすいように自動インクリメントキーを使用できますが、いずれにしても一意性フィールドには一意の制約を設定する必要があります。

実際のデザインについては、次のようなものをお勧めします。

Films => Primary Key(filmid), Unique Constraint(filmtitle, year), 
         runningtime, description, 
         Foreign Key(Genre), Foreign Key(DirectorId)

Genre Table => Primary Key(Genre)

Director Table => Primary Key(DirectorId), DirectorName

Actors Table => Primary Key(ActorId), ActorName

Films_Actors => Primary Key(Foreign Key(ActorId), Foreign Key(FilmId))

挿入については、まあ-正直なところ、それはPITAです。逆の順序で挿入する必要があります(自動インクリメントキーがさらに大きなPITAになる可能性がある場所です-Actors and Directorsテーブルに生年月日などを追加できる場合、一意の制約により簡単になります)。

したがって、Actor、Director、Film、Films_Actorsの順に挿入します。理想的には、すべて1つのトランザクションで処理します。また、ジャンルはすでに入力されており、選択リストであるため、挿入する必要はありません。

3
Mark Brackett

あなたの質問にはすでに回答済みですが、次の点を指摘したいと思います。
http://www.imdb.com/interfaces

IMDBは、データベースのフラットテキストファイルを提供します(主キーを除く)。これは、データベースにデータを入力するときに便利です。または、プログラムやWebサイトで使用して、映画のタイトルを検索して「DVDコレクション」に追加し、残りの情報を入手することもできます。これらから引っ張った。

2
mmcdole

俳優が監督である場合もあれば、その逆の場合もありますが、「人」テーブルが必要な場合もあります。

2
leancz

YearTableは実際には必要ありません。必要なのは、filmsテーブルのgenre_id、director_id、およびactor_id列だけです。

また、ジャンル、ディレクター、アクターのテーブルには、それぞれ固有のIDが必要です。

編集:もちろん、これは、1つのジャンル、監督、、俳優のみを使用することを前提としています各映画。おそらくそうではありません。

多くの俳優が多くの映画に属するには、別個の関係テーブルが必要になります。 "moviesActors"(またはactorsMovies)と呼ぶことができ、各行にはactor_idとmovie_idがあり、this actor was was this movieと言います。

1
Dean Rather

すべてのテーブルには一意の主キーが必要です。

read up on database normalization を実行する必要があります。

年表はおそらく不要です。

たとえば、発売年であれば、その年をフィルムに保存できます。

映画に複数の監督がいる場合は、映画テーブルの主キーと監督テーブルを保持する別のテーブルがあります。同様に、多対1または多対多の外部キー制約のいずれか。特に、これは俳優に当てはまると思います。

0
Cade Roux