Когда использовать отношения 1-к-1 между таблицами базы данных? - PullRequest
21 голосов
/ 05 февраля 2009

Вопрос разработки БД: когда вы решите использовать таблицы отношений 1 к 1?

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

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

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

Итак, если мне нужно создать таблицу User и таблицу UserProfile, лучше ли мне сделать это в одной таблице?

Ответы [ 8 ]

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

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

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

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

Подумайте, как бы вы проектировали бизнес-объекты. У вас будет объект User с 50 свойствами, или у вас будет объект User с несколькими свойствами детализации, а затем объект Profile, который содержит другие данные для профиля?

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

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

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

Классическая причина - избегать пустых столбцов.

Наличие значения NULL в столбце может усложнить написание понятного (поддерживаемого) SQL. @ Овидий написал об этом здесь , опираясь на работу Крис Дата .

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

Только когда поля в таблице UserProfile не требуются для всего количества записей в пользовательской таблице. Например, если у вас было 3 000 000 пользователей, но только 3 000 из них имеют UserProfiles, имеет смысл разделить их (чтобы избежать целого ряда пустых столбцов).

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

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

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

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

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

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

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

Вторая таблица имела треть строк, но в три раза больше столбцов.

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

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

1 голос
/ 03 мая 2013

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

Шейн Д. и другие описывают сценарии, в которых используется этот факт.

0 голосов
/ 09 апреля 2009

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

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

Дайте мне знать, если есть лучшее решение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...