Я использовал MongoDB в течение большей части моей ранней разработки Javascript, и был избалован тем, насколько простым был мангуст. Однако по мере того, как вы углубляетесь в бэкэнд-разработку, становится трудно игнорировать SQL.
Вы заметите много различий между SQL и mongoose - в частности, отсутствие эквивалента для mongoose для систем баз данных SQL. И теперь, поскольку все хранится в таблицах (а не в объектах), отношения также обрабатываются по-другому.
Типы отношений
Для меня это была новая концепция при использовании баз данных SQL. Пуритане SQL будут утверждать, что существует только два типа отношений: Многие-к-одному и Многие-ко-многим (с небольшим подмножеством, относящимся к Нет как другой тип отношений).
При их определении очень важно направление. Мы подойдем к этому с точки зрения таблицы и рассмотрим пять типов отношений: - Соединение-к-одному, Один-к-соединению, Многие-к -Один, Один-ко-многим и Многие-ко-многим. Однако по пути вы познакомитесь с еще одним или двумя типами для завершения.
Один к одному
Подождите, это даже не один из указанных вами родственников.
Итак, чтобы понять, где подходит Соединение, мы должны сначала взглянуть на взаимно-однозначные отношения и понять, почему ни одно из них (один-к-одному, соединение-к-одному и один-к-соединению ) Рекомендовано. Мы будем использовать две таблицы USER и PROFILE. Взаимосвязь заключается в том, что каждый Пользователь может иметь только один Профиль, а каждый Профиль может принадлежать только одному Пользователю. Изначально две таблицы будут выглядеть примерно так:
Однако, если между этими двумя таблицами существует истинная взаимно-однозначная связь, их вообще не должно быть. Эту структуру таблицы лучше всего оптимизировать путем объединения двух таблиц вместе для формирования одной таблицы, содержащей оба набора полей:
Однако нам все еще могут понадобиться две отдельные таблицы по разным причинам (за счет эффективных запросов к базе данных). Одна таблица может содержать конфиденциальные данные, или ожидается, что простое ее существование будет временным. В этом случае нам все равно придется изобрести способ связывания или объединения строк между двумя таблицами.
Присоединяйтесь к одному
Строки в таблице USER не точно совпадают со строками в таблице PROFILE. Необходимо добавить еще один столбец, чтобы связать одну таблицу с другой. В истинных отношениях «один к одному» не имеет значения, в какой таблице это происходит. Ключевое слово Присоединиться помогает идентифицировать таблицу, содержащую этот столбец.
В этом примере таблица USER имеет отношение соединение к одному с таблицей PROFILE и, таким образом, будет содержать столбец profile_id. Идентифицирует строку в таблице PROFILE, которая связана с пользователем.
USER.profile_id will have 2 constraints - FOREIGN key constraint (referencing the PROFILE table) - UNIQUE constraint, as the relationship is one-to-one
Один-к-присоединиться
Если бы вместо этого ссылочный столбец был сохранен в таблице PROFILE, таблица USER имела бы отношение один-к-соединению с ПРОФИЛЬ таблицы. И наоборот, таблица PROFILE будет иметь отношение соединения к одному с таблицей USER. Две таблицы будут выглядеть примерно так: -
PROFILE.user_id will have 2 constraints - FOREIGN key constraint (referencing the USER table) - UNIQUE constraint, as the relationship is one-to-one
Присоединяйтесь к присоединению
!!!! НЕ РЕКОМЕНДУЕТСЯ !!!!
Не было бы лучше, если бы обе таблицы содержали reference_ids, чтобы я мог легко получить доступ к одной из другой?
Нет. Нет, не пойдет. Ошибки неизбежно возникают при вставке и обновлении данных. Они будут выброшены при удалении строк. Циклическая ссылка могла быть хорошей в MongoDB, но здесь она определенно не рекомендуется.
Выберите таблицу, в которой будет столбец объединения, и придерживайтесь его! Или, еще лучше, просто объедините две таблицы вместе.
Однако для любопытных это будет выглядеть так:
PROFILE.user_id will have 2 constraints - FOREIGN key constraint (referencing the USER table) - UNIQUE constraint, as the relationship is one-to-one USER.profile_id will have 2 constraints - FOREIGN key constraint (referencing the PROFILE table) - UNIQUE constraint, as the relationship is one-to-one
Один ко многим
Давайте воспользуемся здесь двумя разными таблицами: АВТОР и КНИГА.
Каждая книга может принадлежать автору, но несколько книг могут иметь одного и того же автора. Другими словами, таблица AUTHOR имеет отношение один ко многим с таблицей BOOK. (У каждого автора может быть несколько книг)
В MongoDB и других базах данных NoSQL вы можете хранить это как массив с вашим документом.
{ id: 1, name: JK Rowling, dob: 1965, Books: [1, 2] } As long as Author.Books references the Book schema/model.
Это не работает и в SQL по нескольким причинам. Первый - это неспособность многих систем управления реляционными базами данных хранить массивы. И если массивы могут быть сохранены посредством сериализации или преобразования в строку, тогда теряется возможность легко просеивать элементы в массиве. Postgres поддерживает типы массивов, и их можно запрашивать с помощью оператора ANY. Это полезно, но все же не дает представления о том, как следует проектировать отношения "один ко многим".
Вместо этого, поскольку у каждой книги может быть только один автор, идентификатор автора следует сохранить в виде столбца в КНИГЕ таблица. Это избавляет нас от необходимости сохранять массивы любого типа.
BOOK.Author_id will have 1 constraint - FOREIGN key constraint (referencing the AUTHOR table)
Это очень естественно приводит нас к ...
Многие к одному
Это наша первая настоящая SQL-связь. Используя тот же пример, что и выше, мы можем сказать, что таблица BOOK имеет отношение многие-к-одному с таблицей AUTHOR. Столбец внешнего ключа хранится в таблице BOOK со ссылкой на идентификатор соответствующего автора.
BOOK.Author_id will have 1 constraint - FOREIGN key constraint (referencing the AUTHOR table)
Многие ко многим
Но если мы не можем хранить массивы, как мы можем иметь дело с отношениями «многие ко многим»! Давайте создадим здесь новую таблицу GENRE, в которой для каждой книги может быть несколько жанров и каждый жанр может быть связан со множеством книг.
Идея состоит в том, чтобы создать совершенно новую таблицу - RELATION_BOOK_GENRE. В этой новой таблице будут существовать два столбца: один относится к таблице BOOK, а другой - к таблице Genre. Чтобы снизить риск избыточности, мы также можем ввести ограничение, гарантирующее, что никакие две строки в этой таблице не могут быть идентичными.
Relation_Book_Genre will have 3 constraints - FOREIGN key constraint on book_id (referencing the BOOK table) - FOREIGN key constraint on genre_id (referencing the GENRE table) - UNIQUE key constraint on ( book_id, genre_id )
Никто
В завершение я должен упомянуть отношение None. Это когда таблица не имеет отношения к другой таблице.
Вывод
Надеюсь, мне удалось более четко объяснить тонкости отношений SQL. Пожалуйста, оставьте комментарий, если что-то из того, что я упомянул, было неправильным для будущих читателей, и я постараюсь отредактировать эту статью как можно скорее. Я действительно надеюсь, что это было полезно для того, чтобы разобраться в этом очень неестественном образе мышления.
Следующая статья будет посвящена созданию таблиц в SQL с учетом отношений.