Intereting Posts
Получить последнее известное значение для каждого столбца строки Рельсы имеют activerecord захватить все необходимые ассоциации за один раз? Вычисление общего времени в месте с SQL Server datetime Oracle SQL. Какое заявление следует использовать SQL-запрос для поиска пользователей с общими тегами в определенном наборе Как использовать динамический параметр в разделе IN запроса JPA с именем? SELECT * FROM X WHERE id IN (…) с Dapper ORM PostgreSQL: последовательно применять табличную функцию к набору значений и результатам UNION ALL Как вернуть несколько строк из хранимой процедуры? (Oracle PL / SQL) Являются ли результаты детерминированными, если я разделяю запрос SQL SELECT без ORDER BY? Существует ли более простой способ достижения этого стиля обмена сообщениями пользователей? java.sql.SQLException: числовое переполнение при использовании оператора IN java.sql.SQLException: ORA-01005: задан пустой пароль; отказ в регистрации Поддержка Bool Oracle SQL Использование отдельной функции в SQL

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

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

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

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

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

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

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

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

  1. Книга
  2. автор
  3. BookAuthors

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

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

BookAuthors будет состоять из множества ко многим, включая BookID, AuthorID и NameUsed. Это позволило бы книге иметь либо нулевое, либо много авторов, поскольку у автора было либо ноль, либо много книг, а также информация об этом отношении. Например, у вас также может быть столбец таблицы BookAuthor, в котором описывается отношение автора к книге («Edited By», «Fore word by»).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Таблица авторов (authorID, authorDetails) Таблица книг (bookID, подробная информация о книге) АвторBook table (authorID, bookID)

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

AuthorDetails (authorID, itemID, authorDetails)

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

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

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

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

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

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

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

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