Есть ли время, когда использование базы данных 1: 1 имеет смысл? - PullRequest
151 голосов
/ 05 февраля 2009

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

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

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

Я что-то упускаю из виду?

Ответы [ 25 ]

149 голосов
/ 05 февраля 2009

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

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

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

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

119 голосов
/ 05 февраля 2009

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

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

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

40 голосов
/ 05 февраля 2009

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

24 голосов
/ 04 февраля 2015

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

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

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

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

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

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

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

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

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

21 голосов
/ 06 февраля 2009

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

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

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

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

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

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

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

19 голосов
/ 05 февраля 2009

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

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

13 голосов
/ 05 февраля 2009

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

9 голосов
/ 05 февраля 2009

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

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

8 голосов
/ 05 февраля 2009

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

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

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

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

8 голосов
/ 05 февраля 2009

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

...