Подтвердить что ты не робот

Как вы относитесь к отношениям m..n в реляционной базе данных?

Посмотрим на пример - книги. Книга может иметь 1..n авторов. У автора могут быть 1..m книги. Что представляет собой хороший способ представить всех авторов книги?

У меня возникла идея создать таблицу Books и таблицу авторов. В таблице Авторы есть первичный ключ AuthorID, имя автора. В таблице "Книги" есть основной идентификатор книги и метаданные о книге (название, дата публикации и т.д.). Однако должен быть способ связать книги с авторами и авторами с книгами. И здесь проблема.

Скажем, у нас есть три книги Боба. Однако в одной книге он написал это как Боб, доктор философии. Другой он написал как доктор Боб, а третий написал как доктор Роберт. Я хочу уметь идентифицировать тот факт, что эти авторы на самом деле являются одним и тем же человеком, но приписываются под разными именами. Я также хочу отличить Боба от другого Боба, который писал разные книги.

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

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

4b9b3361

Ответ 1

Добавьте еще одну таблицу под названием BookAuthors со столбцами для BookID, AuthorID и NameUsed. Значение NULL для NameUsed означает вывести его из таблицы Author. Это называется таблицей пересечения.

Ответ 2

Вам понадобится три таблицы -

  • Книга
  • Автор
  • BookAuthors

Книга будет содержать идентификатор книги, название книги и всю другую информацию, которую вам нужно собрать о книге.

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

BookAuthors будет состоять из множества ко многим, включая BookID, AuthorID и NameUsed. Это позволило бы книге иметь либо нулевое, либо много авторов, поскольку у автора было либо ноль, либо много книг, а также информация об этом отношении. Например, у вас также может быть столбец в таблице BookAuthor, который описывает отношение автора к книге ( "Отредактировано", "Переднее слово" ).

Ответ 3

Я думаю, что ты в значительной степени там. Вам нужна таблица "Книги", таблица "Авторы", а затем таблица "authors_of_books" с основным ключом книги, основным ключом автора и текстовым полем "цитируется как", показывающим, как этот конкретный автор цитировался в этой книге.

Ответ 4

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

http://www.tekstenuitleg.net/en/articles/database_design_tutorial/8

Ответ 5

Учитывая, что доктор Боб и доктор Роберт и Боб, доктор философии, все те же люди, они будут ссылаться на одну и ту же строку в таблице авторов.

Тем не менее, я думаю, что вам нужна таблица с людьми, на которую ссылаются авторы. Вы также можете связать свою интересную таблицу людей с ней. Таким образом, автор Боб и автор Роберт, а также интересный Боб, ссылаются на Человека Боба. Надеюсь, что это имеет смысл.

Ответ 6

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

Столбцы будут AuthorID, BookID и, возможно, CreditAs, поэтому вы можете различать доктора Боба и Боба, доктора философии. (А также имена пера, такие как Стивен Кинг и Ричард Бахман).

И вы все еще можете однозначно идентифицировать автора.

Ответ 7

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

Я бы начал на самом грамотном уровне, и сказал, что ЛЮБОЙ автор должен быть человеком. Я бы упростил этот процесс.

Создайте таблицу лиц с информацией о лицах и PersonId, разместите там информацию.

Создайте таблицу BookAuthors с тремя столбцами BookId, PersonId, TitledName. В этом случае вы можете использовать другое имя, если это необходимо, если нет, вы можете использовать COALESE или что-то подобное, чтобы получить имя по умолчанию, если TitledName имеет значение null.

Просто идея..

Ответ 8

То, о чем вы действительно спрашиваете, - это не то, как вы имеете дело с отношениями 1..n, но n..n отношениями (так же эффективно на автора и имеют много книг, а одна книга может иметь много авторов).

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

Таблица авторов (authorID, authorDetails) Книжный стол (bookID, подробная информация о книге) Таблица AuthorBook (authorID, bookID)

Если вы действительно беспокоитесь об изменении имен авторов, используйте таблицу сведений о файле 1..n, поэтому добавьте

AuthorDetails (authorID, itemID, authorDetails)

и удалите authorDetails из таблицы автора

Ответ 9

Для отношений 1..n(у автора много книг, у автора много псевдонимов):

  • Поместите внешний ключ author_id в Книги, указывая на автора.
  • Создайте новую таблицу, author_aliases, чтобы сохранить информацию о псевдонимах.
  • Поместите внешний ключ alias_id в книги, указывающие на псевдоним (с возможностью обнуления, если данные автора не являются defaul).
  • Поместить авторский_файл_и_и_и_автор в author_aliases.

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

Для отношения n..m(у автора много книг, у книги много авторов):

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

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

Ответ 10

возможная реализация в postgresql, просто для удовольствия:

create table books (
  book_id integer primary key,
  title varchar not null
);

create table aliases (
  alias_id integer primary key,
  alias varchar not null
);

create table books_aliases (
  book_id integer references books (book_id),
  alias_id integer references aliases (alias_id),
  primary key (book_id, alias_id)
);

create table authors (
  author_id integer primary key,
  author varchar not null,
  interesting boolean default false
);

create table aliases_authors (
  alias_id integer references aliases (alias_id),
  author_id integer references authors (author_id),
  primary key (alias_id, author_id)
);

create view books_aliases_authors as
  select * from books 
    natural join books_aliases
    natural join aliases
    natural join aliases_authors
    natural join authors;

можно использовать "использование" вместо естественного соединения:

create view books_aliases_authors as
  select *
    from books 
    join books_aliases using (book_id) 
    join aliases using (alias_id) 
    join aliases_authors using (alias_id) 
    join authors using (author_id);

или выполните сложную задачу для совместимости с mysql (обратите внимание, что mysql также должен иметь явную максимальную длину для вышеперечисленных varchars):

create view books_aliases_authors as
  select b.book_id, title, l.alias_id, alias, t.author_id, author, interesting
    from books b
    join books_aliases bl on bl.book_id = b.book_id
    join aliases l on bl.alias_id = l.alias_id
    join aliases_authors lt on lt.alias_id = l.alias_id
    join authors t on t.author_id = lt.author_id;

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