21


17

私は頭がいっぱいになってDatabase Designと呼ばれるものを頭に入れようとしているので、あまり成功していませんので、例を使って私の問題を説明しようと思います。

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

DVDコレクションを保存するためのデータベースを作成したいとしましょう。 以下の情報があります。

  1. 映画のタイトル

  2. 俳優

  3. 実行時間

  4. ジャンル

  5. 説明

  6. ディレクター

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

これが私がデータベース設計のために考えているものです:

映画表⇒映画ID、映画タイトル、実行時間、説明

年テーブル⇒年

ジャンル表⇒ジャンル

監督テーブル⇒監督

*アクターテーブル⇒ actor_name *

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

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

そして最後に、PHPフォームを介して新しいフィルムをデータベースに更新する場合、このデータすべてをどのように(関係とすべてを使用して)挿入しますか。

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

10 Answer


60


あなたは属性と実体を区別しなければなりません。 実体は物です - 通常名詞です。 属性は情報を記述する部分のようなものです。 データベースの専門用語では、entity = table、a​​ttribute = field / columnです。

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

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

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

監督に関するこのような情報をすべて保存したくない場合(名前だけが欲しい場合)は、別のテーブルを作成して(そして代理キーを使用します。1秒以内に取得します)、便利です。誤字や重複を防ぎます - 他人の名前のスペルを間違えたり、名前を間違って入力したり(最初、最後と最後、最初)、他の映画を見つけようとすると失敗します。

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

'' '' '

あなたは本当にこのデザインをかなり遠くまで取ることができます、そしてそれはあなたがそれに格納できるようにしたいものを考え出すことのすべての問題です。

たとえば、映画ごとに1人の監督がいるのではなく、複数の監督がいる映画もあります。 ですから、映画と監督の間には多対多の関係があるでしょう。ですから、例えば以下のような表が必要です。

films_directors => ** filmid、directorid **

それをさらに一歩進めて、時には監督は俳優でもあり、その逆もあります。 そのため、監督テーブルと俳優テーブルさえ持っているのではなく、単一の人物テーブルを持ち、ロールテーブルを使用してそのテーブルに参加することができます。 ロールテーブルは様々なポジションを保持します - 例えば、監督、プロデューサー、スター、エクストラ、グリップ、エディター。 そしてそれはもっと似ているでしょう:

films => ** filmid **、タイトル、その他... people => ** personid **、名前、.... roles => ** roleid **、ロール名、.... film_people => ** filmid、personid、roleid **ジャンル=> ** genreid **、名前、... film_genre => ** genreid、filmid **

また、film_peopleテーブルにrole_detailsフィールドを含めることもできます。これには、役割に応じて追加の情報(俳優が演じているパートの名前など)を含めることができます。

映画は複数のジャンルにまたがる可能性があるため、私はジャンルも多対多の関係として示しています。 これを望まないのであれば、film_genreテーブルの代わりに、フィルムにはgenreidが含まれているだけです。

これが設定されれば、与えられた人がしたことすべて、あるいはある人が監督としてしたことすべて、あるいは映画を監督したことがある人すべて、またはある特定の映画に関わるすべての人を照会して見つけるのは簡単です。 それは続けて行くことができます。


19


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

俳優テーブル

  • id(主キー)

  • ファーストネーム

  • 苗字

  • 等 (アクターに保存したい追加の列)

ディレクターテーブル

  • id

  • ファーストネーム

  • 苗字

ジャンル表

  • id

フィルムテーブル

  • id

  • タイトル

  • 説明

  • 実行時間

  • 発売日

  • 監督ID - これは、映画を監督した監督のID(主キー)を指す外部キーです。

  • ジャンルID - 監督IDのように、これは映画が属するジャンルのIDを表します。

俳優映画インデックス表

  • フィルムID - これはフィルムのIDを参照する外部キーです。

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

映画の各俳優について、あなたは俳優映画インデックスに行を追加するでしょう。 そのため、俳優5と13(これらの俳優の主キー)が映画4(ここでも、その映画の主キー)で主演している場合、インデックスにその事実を反映した2行が表示されます。俳優ID = 5、そして映画ID = 4、俳優ID = 13の別の人。

お役に立てば幸いです。

また、これは各映画がちょうど1人の監督を持っていることを前提としています。 あなたのライブラリーの中の映画に2人の監督がいる場合(Slumdog Millionaireのように)、あなたはfilmテーブルからdirector idを切り離して、上記のActor-Film IndexのようなDirector-Filmインデックスを作成したいでしょう。


11


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

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

監督と俳優のテーブルを持つ代わりに、ただ一人の人々のテーブルを持ってください。 これには乗組員を含めることもできます(2番目のジュニアアシスタントのDolly Gripが誰であるかを追跡したい場合)。 各映画は任意の数のジャンル(例えば、コメディやホラー)にすることができます。 加えて、人々はそれぞれの映画の上で任意の数の役割を果たすことができます - そこにかなりの数の俳優/監督があります。

ロールテーブルは、その俳優が演じているキャラクターを必ずしも意味するわけではありませんが、それは可能です。 それは "監督"、 "プロデューサー"、 "俳優"などです。 あなたがそれをきめ細かくしたいのであれば、あるいは「Luke Skywalker」さえも… 私はIMDBがそれをしていると思います。

うまくいけば、上のフィールドの名前は外部キーを暗示するはずです、そして私は私が使う主キーの周りに `underscores`を置きました。


4


Filmsテーブルには、ジャンル、監督、俳優のテーブルへのリンクも必要です。 俳優たちは、少なくとも多対多(一人の映画が一人以上の俳優をリストアップし、一人の俳優が複数のフィルムに含まれる)になるので、それらをリンクするためのテーブルが必要です。

Film Table => filmid、filmtitle、runningtime、description、genreid、directoridジャンルTable => genreid、ジャンルDirector Table => directorid、director Actorsテーブル=> actorid、actor_name FilmActorリンクテーブル=> actorid、filmid(それぞれにレコードリンク付き)各映画の俳優)

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


3


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

はい、各テーブルには一意の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を挿入します。 理想的には、すべて単一のトランザクションで。 また、私はジャンルが既に記入されていると仮定し、それは選択リストです - それでそれは挿入される必要はありません。


3


Imdbスキーマhttps://code.google.com/p/imdbdumpimport/source/browse/trunk/ imdbdumpimport / imdb-import / db / schema.sql?r = 19 [ここ]をダウンロードできます。


2


私はあなたの質問はすでに答えられていることを実感します、しかし私はあなたをさしたいと思いました:http://www.imdb.com/interfaces

IMDBは、データベースのフラットテキストファイル(主キーを除く)を提供しています。 あなたが行ったらあなたのデータベースを埋めるのにこれが役に立つと思うかもしれません、あるいはあなたが単にあなたの "DVDコレクション"に追加するために映画タイトルを捜して残りの情報を持つことを可能にするためにそれを使うことができますこれらから引っ張った。


2


時には俳優は監督であり、またその逆もあります、多分あなたは「人」のテーブルが欲しいですか?


1


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

また、ジャンル、監督、俳優のテーブルにはそれぞれ固有のIDが必要です。

*編集:*これはもちろん、映画ごとに1つのジャンル、監督、そして俳優だけがいると仮定しています。 おそらくそうではありません。

多くの映画に多くの俳優を所属させるには、別々の関係表が必要になります。 それを "moviesActors"(またはactorsMovies)と呼ぶことができ、各行は* this actor this movie *に含まれていることを示すactor_idとmovie_idを持ちます。


0


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

あなたは database normalizationread upするべきです。

年テーブルはおそらく不要です。

もしそれが発売年であれば、その年を映画に保存することができます。

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