Создать связанную таблицу, чтобы избежать возможных пустых полей - PullRequest
0 голосов
/ 01 сентября 2018

допустим, у меня есть таблица с именем movie_celebrity , которая имеет следующие столбцы:

CREATE TABLE `movie_celebrity` (
  `id` int(11) NOT NULL,
  `movie_id` int(11) NOT NULL,
  `celebrity_id` int(11) NOT NULL,
  `movie_celebrity_type_id` int(11) NOT NULL,
  `role` varchar(10) DEFAULT NULL,
  `character_name` varchar(50) DEFAULT NULL
)

, поэтому, если тип знаменитости писатель или режиссер поля role и character_name будут пустыми, только если тип актер эти поля будут заполнены.

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

Редактировать (включая схему)

Таблица фильмов:

CREATE TABLE `movie` (
  `id` int(11) NOT NULL,
  `name` varchar(100) NOT NULL,
  `poster` varchar(255) DEFAULT NULL,
  `release_Date` date NOT NULL,
  `runtime` time NOT NULL,
  `storyline` text NOT NULL,
  `rated` varchar(10) DEFAULT NULL,
  `rating` float(2,1) NOT NULL DEFAULT '0.0',
  `inserted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
)

Таблица знаменитостей:

CREATE TABLE `celebrity` (
  `id` int(11) NOT NULL,
  `name` varchar(100) NOT NULL,
  `picture` varchar(255) DEFAULT NULL,
  `date_of_birth` date NOT NULL,
  `biography` text NOT NULL
)

Movie_Celebrity table:

CREATE TABLE `movie_celebrity` (
  `id` int(11) NOT NULL,
  `movie_id` int(11) NOT NULL,
  `celebrity_id` int(11) NOT NULL,
  `type` varchar(10) NOT NULL,
  `role` varchar(10) DEFAULT NULL,
  `character_name` varchar(50) DEFAULT NULL
)

1 Ответ

0 голосов
/ 02 сентября 2018

Кажется, вы пытаетесь составить комбинированный стол "Состав и команда". В зависимости от того, что вы делаете с ним, может быть хорошей идеей объединить их все в одном столе, или, возможно, было бы лучше иметь отдельные «бросок» и «команду». Я бы сказал, чтобы начать с комбинированной таблицы и посмотреть, как это происходит. Если это не сработает, вы можете разделить таблицу и создать представление для обратной совместимости.

Согласно комментариям автора, movie_celebrity_type_id для таких вещей, как "писатель", "актер" или "режиссер", а role для "ведущих" или "поддерживающих". Это кажется странным. Многие фильмы не определяют «ведущий» против «вспомогательный» актерский состав. А многие знаменитости - это каталоги, писатели, актеры и продюсеры. Альфред Хичкок - хороший пример.

Ваши movie и celebrity таблицы в порядке, хотя я бы, вероятно, просто назвал их persons. Я бы разработал таблицу, соединяющую их так:

create table cast_and_crew (
    id integer primary key auto_increment,
    movie_id integer not null,
    celebrity_id integer not null,
    role text not null,
    character_name text,
    credited boolean not null default true,
    notes json not null default '{}'

    foreign key(movie_id) references movie(id),
    foreign key(celebrity_id) references celebrity(id),

    -- Include the character name for people who act in more than one role
    unique(movie_id, celebrity_id, role, character_name)
);

Это гораздо больше, чем просто таблица присоединения к фильму / знаменитости, поэтому я дал ей описательное имя cast_and_crew. Поскольку подавляющее большинство записей будут актерами с character_name, хорошо бы сделать этот столбец реальным. Столбец notes JSON обеспечивает гибкость для любых других битов данных без добавления дополнительных столбцов.

Например, некредитованное появление Альфреда Хичкока в Птицах ...

insert into cast_and_crew (movie_id, celebrity_id, role, character_name, credited)
    values(<The Birds>, <Alfred Hitchcock>, 'actor', 'Man Walking Dogs Out of Pet Shop', false);

<The Birds> и <Alfred Hitchcock> являются их соответствующими идентификаторами.

Затем снова как продюсер и режиссер.

insert into cast_and_crew (movie_id, celebrity_id, role)
    values(<The Birds>, <Alfred Hitchcock>, 'producer');

insert into cast_and_crew (movie_id, celebrity_id, role)
    values(<The Birds>, <Alfred Hitchcock>, 'director');

Принимая во внимание, что Пегги Робертсон, помощник Альфреда Хичкока, может использовать колонку notes, например, так.

insert into cast_and_crew (movie_id, celebrity_id, role, noes)
    values(<The Birds>, <Peggy Robertson>, 'assistant', '{ "to": <Alfred Hitchcock> }');

Код, использующий эту таблицу, может быть написан для создания экземпляра подкласса на основе роли. Например, вы можете написать общий класс CastAndCrew. Тогда подкласс CastAndCrew::Actor предоставит метод name и потребует его определения. CastAndCrew::Assistant будет знать, чтобы искать to поле в notes.

Другой пример - Рэй Бервик, которого считают "дрессировщиком птиц". Вы можете ввести role = 'trainer of the birds', но что, если вы хотите найти всех дрессировщиков? Вы можете иметь вербатум и нормализованные роли, роль вербатума - «дрессировщик птиц», а нормализованная роль - «дрессировщик животных». Зависит от того, что вы пытаетесь достичь.

Может быть больше улучшений, но они зависят от знания того, что вы хотите делать с данными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...