Как создать базу данных фильмов? - PullRequest
21 голосов
/ 29 января 2009

Я пытаюсь разобраться в этом ошеломляющем материале, который они называют Database Design, но без особого успеха, поэтому я попытаюсь проиллюстрировать мою проблему на примере.

Я использую MySQL, и вот мой вопрос:

Скажем, я хочу создать базу данных для хранения моей коллекции DVD. У меня есть следующая информация, которую я хочу включить:

  1. Название фильма
  2. Актеры
  3. Продолжительность
  4. Жанр
  5. Описание
  6. год
  7. директор

Я хотел бы создать отношения между ними, чтобы сделать его более эффективным, но не знаю как.

Вот что я думаю по поводу дизайна базы данных:

Таблица фильмов => filmid, filmtitle, время выполнения, описание

Таблица Год => Год

Таблица жанров => Жанр

Таблица директоров => Директор

Таблица актеров => имя_актора

Но как мне создать отношения между этими таблицами?

Кроме того, я создал уникальный идентификатор для таблицы фильмов с первичным ключом, который автоматически увеличивается, нужно ли создавать уникальный идентификатор для каждой таблицы?

И, наконец, если бы я обновил новый фильм в базе данных через форму PHP, как бы я вставил все эти данные (со связями и всем?)

спасибо за любую помощь, которую вы можете оказать, Кит

Ответы [ 10 ]

60 голосов
/ 29 января 2009

Вы должны различать атрибуты и сущности. Сущность - это вещь, обычно существительное. Атрибут больше похож на часть описания информации. В жаргоне базы данных сущность = таблица, атрибут = поле / столбец.

Имея отдельную таблицу для определенных вещей, давайте использовать директор, в качестве примера, называется нормализация. Хотя в одних обстоятельствах он может быть хорошим, в других он может оказаться ненужным (как правило, это усложняет запросы - нужно объединять все - и это медленнее).

В этом случае наличие таблицы года не является необходимым, поскольку нет никаких других атрибутов относительно года, кроме самого года, которые вы бы сохраняли. Лучше денормализовать это и сохранить год в самой таблице фильмов.

Директор, с другой стороны, другой. Возможно, вы захотите сохранить имя, фамилию режиссера, дату рождения, дату смерти (если применимо) и т. Д. Очевидно, что вы не хотите вводить дату рождения режиссера каждый раз, когда вы входите в фильм, который этот человек направляет, поэтому имеет смысл иметь отдельную сущность для директора.

Даже если вы не хотите хранить всю эту информацию о директоре (вам просто нужно его имя), иметь для него отдельную таблицу (и использовать суррогатный ключ - я вернусь к этому через секунду) полезно, потому что это предотвращает опечатки и дубликаты - если у вас написано чье-то имя неправильно или введено по-другому (первый, последний против последнего, первый), то если вы попытаетесь найти другие фильмы, которые они сняли, у вас не получится.

Обычно рекомендуется использовать суррогатный ключ (первичный ключ) для таблиц. Совпадение целого числа намного быстрее, чем сопоставление строки. Это также позволяет вам свободно менять имя, не беспокоясь о внешних ключах, хранящихся в других таблицах (идентификатор остается прежним, поэтому вам не нужно ничего делать).


Вы действительно можете зайти довольно далеко, и все зависит от того, что вы хотите в нем хранить.

Например, вместо того, чтобы иметь одного режиссера на фильм, в некоторых фильмах есть несколько режиссеров ... так что между фильмами и режиссерами будет много-много отношений, поэтому вам понадобится таблица с, например:

films_directors => **filmid, directorid**

Делая это еще дальше, иногда режиссеры также являются актерами, и наоборот. Таким образом, вместо того, чтобы иметь таблицы директора и актера, вы можете иметь таблицу с одним человеком и присоединиться к этой таблице, используя таблицу ролей. Таблица ролей будет занимать различные должности - например, режиссер, продюсер, звезда, экстра, ручка, редактор ... и будет выглядеть примерно так:

films => **filmid**, title, otherstuff...
people => **personid**, name, ....
roles => **roleid**, role name, ....
film_people => **filmid, personid, roleid**
genre => **genreid**, name, ...
film_genre => **genreid, filmid**

У вас также может быть поле role_details в таблице film_people, которое может содержать дополнительную информацию в зависимости от роли (например, название роли, которую играет актер).

Я также показываю жанр как множество <> много отношений, потому что возможно фильм в нескольких жанрах. Если вы этого не хотите, то вместо таблицы film_genre фильмы будут содержать жанр.

Как только это настроено, легко запрашивать и находить все, что сделал данный человек, или все, что человек сделал в качестве режиссера, или всех, кто когда-либо снимал фильм, или всех людей, связанных с одним конкретным кино .. Это может продолжаться и продолжаться.

19 голосов
/ 29 января 2009

То, что следует, не является действительным кодом MySQL. Кажется, здесь нужно больше концептуального начала. Итак, вот модель того, как должна выглядеть ваша база данных.

Актёрский стол

  • id (первичный ключ)
  • имя
  • фамилия
  • и т.д.. (любые дополнительные столбцы, которые вы хотите сохранить на актере)

Стол директора

  • ID
  • имя
  • фамилия
  • и т.д.

Жанровая таблица

  • ID
  • имя
  • и т.д.

Пленочный стол

  • ID
  • название
  • описание
  • время работы
  • дата выхода
  • идентификатор директора - это внешний ключ, который относится к идентификатору (первичному ключу) режиссера, который снял фильм
  • идентификатор жанра - как и идентификатор режиссера, это относится к идентификатору жанра, к которому относится фильм

Актер-фильм указательный стол

  • идентификатор фильма - это внешний ключ, который относится к идентификатору фильма
  • идентификатор актера - это внешний ключ, который относится к идентификатору одного актера в фильме.

Для каждого актера в фильме вы должны добавить строку в указатель «Актер-фильм». Итак, если актеры 5 и 13 (первичные ключи для этих актеров) сыграли главную роль в фильме 4 (опять же, первичный ключ для этого фильма), у вас было бы две строки, отражающие этот факт в вашем индексе: один с идентификатором фильма = 4, и актер id = 5, и другой с фильмом id = 4, и актер id = 13.

Надеюсь, это поможет.

Кроме того, это предполагает, что в каждом фильме ровно один режиссер. Если у какого-либо фильма в вашей библиотеке есть два режиссера (например, «Миллионер из трущоб»), вам нужно отделить идентификатор режиссера от таблицы фильмов и создать указатель «Режиссерский фильм», например «Указатель актерского фильма», как указано выше.

11 голосов
/ 29 января 2009

Вот таблицы, которые я бы использовал:

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

Вместо того, чтобы иметь стол режиссеров и актеров, просто за одним столом людей. Сюда также могут входить члены экипажа (в случае, если вы хотите отследить, кто был вторым младшим помощником Долли Грип). Каждый фильм может иметь любое количество жанров (например, комедия и ужастик). Кроме того, люди могут играть любое количество ролей в каждом фильме - там довольно много актеров / режиссеров.

Таблица ролей не обязательно означает персонажа, которого играет актер, но это возможно. Это может быть "Режиссер", "Продюсер", "Актер" ... или даже "Люк Скайуокер", если вы хотите получить этот мелкозернистый ... Я считаю, что IMDB это делает.

Надеюсь, что названия полей выше должны указывать на внешние ключи, и я поместил _underscores_ вокруг первичных ключей, которые я бы использовал.

4 голосов
/ 29 января 2009

Ваша таблица Films также нуждается в ссылках на таблицы жанров, режиссеров и актеров. Поскольку актеров, по крайней мере, будет много ко многим (в одном фильме будет более одного актера, один актер будет в нескольких фильмах), вам понадобится таблица, чтобы связать их.

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)

Любая таблица, которая может быть много-много, нуждается в связующей таблице.

3 голосов
/ 12 марта 2014

Скачать схему Imdb можно здесь .

3 голосов
/ 29 января 2009

Я создал уникальный идентификатор для таблицы фильмов с первичным ключом, который автоматически увеличивается, нужно ли создавать уникальный идентификатор для каждой таблицы?

Да, каждая таблица должна иметь уникальный идентификатор. Но это не обязательно основной автоинкрементный ключ - это то, что делает этот конкретный экземпляр уникальным. Например, для фильмов, я думаю, что это обычно название + год выпуска - хотя вы бы хотели проверить это с любителем фильмов (экспертом в области), чтобы быть уверенным в этом. Автоинкремент является запасным вариантом - в основном, когда у вас действительно нет ничего уникального.

Вы можете использовать автоинкрементный ключ для простоты использования в соединениях и тому подобное, но в любом случае у вас должно быть уникальное ограничение на поля уникальности.

Что касается реального дизайна, я бы предложил что-то вроде:

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 - если вы можете добавить дату рождения или что-то еще в таблицу «Актеры и режиссеры», то уникальное ограничение может сделать это проще).

Итак, вы должны вставить Актера (ов), Режиссера, Фильм, а затем Films_Actors. В идеале все в одной транзакции. Кроме того, я предполагаю, что Жанр уже заполнен и является списком выбора, поэтому его не нужно вставлять.

2 голосов
/ 29 января 2009

Иногда актеры являются режиссерами, и наоборот, может быть, вы хотите «народный» стол?

2 голосов
/ 29 января 2009

Я понимаю, что на ваш вопрос уже был дан ответ, однако я хотел бы указать вам:
http://www.imdb.com/interfaces

IMDB предоставляет текстовые файлы своей базы данных (за исключением первичных ключей). Это может оказаться полезным для заполнения вашей базы данных, как только вы начнете работу, или вы можете использовать ее в своей программе / на веб-сайте, чтобы позволить вам просто искать название фильма, чтобы добавить его в «DVD Collection», и получить остальную информацию вытащил из них.

1 голос
/ 29 января 2009

Вам на самом деле не нужен YearTable, и все, что вам нужно, это столбцы genre_id, Director_id и actor_id в вашей таблице фильмов.

Кроме того, для ваших таблиц жанров, режиссеров и актеров требуются собственные уникальные идентификаторы.

Редактировать: Это, конечно, при условии, что у вас будет только 1 жанр, режиссер, и актер для каждого фильма. Что, вероятно, не так.

Чтобы иметь много актеров, принадлежащих ко многим фильмам, вам понадобится отдельная таблица отношений. Вы могли бы назвать это «moviesActors» (или актерыMovies), и в каждой строке будет указан actor_id и movie_id, чтобы сказать, этот актер был в этот фильм .

0 голосов
/ 29 января 2009

Каждая таблица должна иметь первичный ключ, который является уникальным.

Вы должны прочитать на нормализация базы данных .

Таблица года, вероятно, не нужна.

Если это год выпуска, скажем, тогда год можно сохранить в фильме.

Если в фильме несколько режиссеров, то у вас будет отдельная таблица, в которой будут находиться первичный ключ таблицы фильмов и таблицы режиссеров. Точно так же для любого из ограничений внешнего ключа, которые являются многими-к-одному или многими-ко-многим. В частности, я считаю, что это относится к актеру.

...