Есть ли когда-нибудь время, когда с помощью базы данных 1:1 отношения имеет смысл?


Я думал на днях о нормализации, и мне пришло в голову, что я не могу думать о времени, когда в базе данных должно быть отношение 1:1.

имя: SSN? У меня бы они были в одной таблице PersonID: AddressID? Опять тот же стол.

Я могу придумать миллион примеров 1:много или много:много (с соответствующими промежуточными таблицами), но никогда 1: 1.

я упускаю что-то очевидное?

25 136

25 ответов:

отношение 1:1 обычно указывает на то, что вы по какой-то причине разделили более крупный объект. Часто это происходит из-за причин производительности в физической схеме, но это может произойти и в логической стороне, если ожидается, что большой кусок данных будет "неизвестен" одновременно (в этом случае у вас есть 1:0 или 1:1, но не более).

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

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

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

одной из причин является эффективность базы данных. Наличие отношения 1:1 позволяет разделить поля, которые будут затронуты во время блокировки строки/таблицы. Если таблица A имеет тонну обновлений, а таблица b имеет тонну чтений (или имеет тонну обновлений из другого приложения), то блокировка таблицы A не повлияет на то, что происходит в таблице B.

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

Моя запись в блоге об этом.

разреженность. Взаимосвязь данных может быть технически 1:1, но соответствующие строки не должны существовать для каждой строки. Поэтому, если у вас есть двадцать миллионов строк, и есть некоторый набор значений, который существует только для 0,5% из них, экономия пространства огромна, если вы выталкиваете эти столбцы в таблицу, которая может быть редко заполнена.

ваш вопрос может быть интерпретирован несколькими способами, из-за того, как вы его сформулировали. Ответы показывают это.

там может быть 1:1 отношения между элементами данных в реальном мире. Никаких вопросов по этому поводу. Отношение "есть", как правило, один к одному. Автомобиль - это транспортное средство. Один автомобиль один автомобиль. Один автомобиль может быть одним автомобилем. Некоторые транспортные средства являются грузовиками, и в этом случае одно транспортное средство не является автомобилем. Несколько ответов касаются этого толкование.

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

правила нормализации для 1NF, 2NF и 3NF никогда не требуют разложения (разделения) таблицы на две таблицы с одним и тем же первичным ключом. Я не удалось выяснить, может ли размещение схемы в BCNF, 4NF или 5NF когда-либо привести к двум таблицам с одинаковыми ключами. С моей головы, я собираюсь догадаться, что ответ-нет.

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

в 6NF отсутствующие данные могут быть представлены опущенной строкой, а не строкой с нулем в некотором столбце.

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

Я использую их в основном по нескольким причинам. Одним из них является значительная разница в скорости изменения данных. Некоторые из моих таблиц могут иметь журналы аудита, в которых я отслеживаю предыдущие версии записей, если я только хочу отслеживать предыдущие версии 5 из 10 столбцов, разбивая эти 5 столбцов на отдельную таблицу с механизмом отслеживания аудита на ней более эффективно. Кроме того, у меня могут быть записи (скажем, для бухгалтерского приложения), которые только пишут. Вы не можете изменить суммы в долларах, или счет они были ибо, если вы допустили ошибку, то вам нужно сделать соответствующую запись, чтобы списать корректировку с неправильной записи, а затем создать запись коррекции. У меня есть ограничения на таблицу, обеспечивающие тот факт, что они не могут быть обновлены или удалены, но у меня может быть несколько атрибутов для этого объекта, которые являются податливыми, они хранятся в отдельной таблице без ограничения на модификацию. В другой раз я делаю это в медицинских приложениях записи. Есть данные, связанные с посещением, которые не могут быть изменено после его выхода из системы, а также другие данные, связанные с посещением, которые могут быть изменены после выхода из системы. В этом случае я разделю данные и поставлю триггер на заблокированную таблицу, отклоняя обновления заблокированной таблицы при выходе из системы, но разрешая обновления данных, которые врач не подписывает.

другой плакат прокомментировал 1: 1 не нормализуется, я бы не согласился с этим в некоторых ситуациях, особенно подтипов. Скажем, у меня есть таблица сотрудников, а первичный ключ-их SSN (это пример, давайте сохраним дискуссию о том, является ли это хорошим ключом или нет для другого потока). Сотрудники могут быть разных типов, скажем, временные или постоянные, и если они постоянны, у них есть больше полей, которые нужно заполнить, например, номер офисного телефона, который должен быть только не нулевым, если тип = 'постоянный'. В базе данных 3-й нормальной формы столбец должен зависеть только от ключа, то есть от сотрудника, но на самом деле он зависит от сотрудника и типа, поэтому отношение 1:1 отлично нормально, и желательно в этом случае. Это также предотвращает чрезмерно разреженные таблицы, если у меня есть 10 столбцов, которые обычно заполняются, но 20 дополнительных столбцов только для определенных типов.

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

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

  • " Is-A " или супертип/подтип или отношения наследования/классификации: эта категория, когда один объект является определенным типом другого объекта. Например, может существовать сущность Employee с атрибутами, которые применяются ко всем сотрудникам, а затем различные сущности для указания конкретные типы сотрудников с атрибутами, уникальными для этого типа сотрудников, например, врач, бухгалтер, пилот и т. д. Эта конструкция позволяет избежать нескольких нулей, так как многие сотрудники не будут иметь специализированных атрибутов определенного подтипа. Другими примерами в этой категории могут быть продукт как супертип, а производство продукции и техническое обслуживание-как подтипы; животное как супертип и собака и кошка как подтипы; и т. д. Обратите внимание, что когда вы пытаетесь сопоставить объектно-ориентированной иерархии наследования в реляционная база данных (например, в объектно-реляционной модели) - это тип отношений, который представляет такие сценарии.

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

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

  • брак (по крайней мере, в правовых системах, где полигамия является незаконной): один человек может быть женат только на одном человеке одновременно. Я получил этот пример из учебника, который использовал это как пример унарных отношений 1:1, когда компания регистрирует браки между своими сотрудниками.

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

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

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

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

с точки зрения чистой науки, да, они бесполезны.

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

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

Я также могу думать о ситуациях, когда у вас есть модель OO, в которой вы используете наследование, и дерево наследования должно быть сохранено в БД.

например, у вас есть класс птица и рыба, которые оба наследуют от животного. В вашей БД вы можете иметь таблицу "животное", которая содержит общие поля класса Animal, а таблица Animal имеет отношение один к одному с таблицей Bird и отношение один к одному с таблицей Fish.

в этом в этом случае вам не нужно иметь одну таблицу Animal, которая содержит много столбцов с нулевым значением для хранения свойств Bird и Fish, где все столбцы, содержащие данные Fish, имеют значение NULL, когда запись представляет птицу.

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

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

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

Если вы используете данные с одним из популярных ORM, вы можете разбить таблицу на несколько таблиц, чтобы соответствовать иерархии объектов.

Я обнаружил, что когда я делаю отношения 1:1, это полностью по системной причине, а не по реляционной причине.

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

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

в SQL невозможно обеспечить связь 1:1 между двумя таблицами, которая является обязательной с обеих сторон (если только таблицы не доступны только для чтения). Для большинства практических целей отношение "1:1" в SQL действительно означает 1:0/1.

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

большую часть времени проекты считаются 1:1, пока кто-то не спросит: "Ну, почему это не может быть 1: много"? Преждевременно отделять понятия друг от друга делается в ожидании этого общего сценария. Человек и адрес не связывают так крепко. У многих людей есть несколько адресов. И так далее...

обычно два отдельных пространства объектов подразумевают, что один или оба могут быть умножены (x:many). Если два объекта были действительно, действительно 1:1, даже философски, то это больше похоже на это-отношения. Эти два "объекта" на самом деле являются частями одного целого объекта.

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

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

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

лучшая причина, которую я вижу для отношений 1:1, - это подтип Супертипа дизайна базы данных. Я создал структуру данных MLS недвижимости на основе этой модели. Было пять различных каналов данных; жилой, коммерческий, многоквартирный, отели и Земли.

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

создать пять отдельных Подтипы, хранящие уникальные элементы данных для каждого из пяти каналов данных. Каждая запись Супертипа имела отношение 1:1 к соответствующей записи подтипа.

Если клиент хотел детальный поиск, они должны были выбрать супер-Sub тип, например PropertyResidential.

на мой взгляд, отношение 1:1 отображает наследование класса на СУБД. Существует таблица A, которая содержит общие атрибуты, т. е. статус класса partent Каждый унаследованный статус класса отображается на СУБД с таблицей B с отношением 1:1 к таблице, содержащей специализированные атрибуты. Таблица namend a также содержит поле "type", которое представляет функцию" casting"

пока Марио

1:1 отношения на самом деле не имеет смысла, если вы в нормализации, как все, что было бы 1:1 будет храниться в той же таблице.

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

возможно, если у вас есть какие-то типизированные объекты в вашей базе данных.

скажем в таблице, T1, у вас есть столбцы C1, C2, C3... с отношением один к одному. Все нормально, все в нормализованном виде. Теперь скажем в таблице T2, у вас есть столбцы C1, C2, C3, ... (имена могут отличаться, но говорят, что типы и роль одинаковы) с отношением один к одному. Это нормально для T2 по тем же причинам, что и с T1.

в этом случае, однако, я вижу, что подходит для отдельной таблицы T3, удерживая C1, C2, C3... и отношение один к одному от T1 к T3 и от T2 к T3. Я еще больше вижу соответствие, если существует другая таблица, с которой уже существует один к нескольким C1, C2, C3... скажем, из таблицы A в несколько строк в таблице B. тогда вместо T3 вы используете B и имеете отношение один к одному от T1 до B, то же самое Для от T2 до B, и все же одно и то же отношение к нескольким от A до B.

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

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

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

пример:

 Citizen Table
 id = 1, citizen_name = "EvryBod"
 id = 2, citizen_name = "Lesly"
 id = 3, citizen_name = "Wasserman"

 Candidate Table
 id = 1, citizen_id = 1, candidate_name = "Bern Nie"
 id = 2, citizen_id = 2, candidate_name = "Bern Nie"
 id = 3, citizen_id = 3, candidate_name = "Hill Arry"

тогда, если мы видим таблицу голосования так:

 Voting Table
 id = 1, citizen_id = 1, candidate_name = "Bern Nie"
 id = 2, citizen_id = 2, candidate_name = "Bern Nie"
 id = 3, citizen_id = 3, candidate_name = "Hill Arry"
 id = 4, citizen_id = 3, candidate_name = "Hill Arry"
 id = 5, citizen_id = 3, candidate_name = "Hill Arry"

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

человек стоматолог (его 1: N, так что его неправильно!)

человек врач (его 1: N, так что это тоже неправильно!)

человек супруга (его 1: 0/1, так что его в основном неправильно!)

EDIT: Да, это были довольно плохие примеры, особенно если я всегда искал 1:1, а не 0 или 1 с обеих сторон. Я думаю, что мой мозг был неправильный огонь : -)

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

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

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

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

Павел.