Какой дизайн базы данных лучше:больше таблиц или больше столбцов?[закрыто]

StackOverflow https://stackoverflow.com/questions/59482

Вопрос

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

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

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

Это было полезно?

Решение

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

  1. Выступайте за нормализацию.Денормализация — это форма оптимизации со всеми необходимыми компромиссами, поэтому к ней следует подходить с осторожностью. ЯГНИ отношение.
  2. Убедитесь, что клиентский код, ссылающийся на базу данных, достаточно отделен от схемы, чтобы его переработка не требовала серьезного изменения конструкции клиента(ов).
  3. Не бойтесь денормализации, если это дает явное преимущество в производительности или сложности запросов.
  4. Используйте представления или последующие таблицы для реализации денормализации, а не денормализации ядра схемы. когда объем данных и сценарии использования позволяют это.

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

Другие советы

Я бы высказался за большее количество таблиц, но только до определенного момента.Используя ваш пример, если вы разделили информацию о пользователе на две таблицы, скажем, ПОЛЬЗОВАТЕЛИ и АДРЕС, это даст вам возможность иметь несколько адресов для каждого пользователя.Одним из очевидных применений этого является пользователь, у которого есть отдельные адреса для выставления счетов и доставки.

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

Это похоже не столько на вопрос о таблицах/столбцах, сколько на вопрос о нормализации.В некоторых ситуациях имеют высокую степень нормализация («больше таблиц» в данном случае) — это хорошо и чисто, но для получения релевантных результатов обычно требуется большое количество соединений JOIN.А при достаточно большом наборе данных это может снизить производительность.

Джефф написал немного об этом, касательно дизайна StackOverflow.См. также сообщение, на которое ссылается Джефф. Дэйр Обасанджо.

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

Это веские причины для нормализации ситуации.Я бы предпочёл сначала нормализовать, а потом только денормализовать. специфический столы после вы видели, что производительность становится проблемой.

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

Это зависит от вашей базы данных.Например, MS SQL Server предпочитает более узкие таблицы.Это также более «нормализованный» подход.Другие двигатели могут предпочесть наоборот.Мейнфреймы, как правило, попадают в эту категорию.

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

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

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

Как и все остальное:это зависит.

Не существует жесткого правила относительно количества столбцов и количества таблиц.

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

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

По возможности избегайте сложности.Например, если у клиента может быть только два адреса (не произвольное количество), возможно, имеет смысл просто хранить их все в одной таблице (CustomerID, Name, ShipToAddress, BillingAddress, ShipToCity, BillingCity и т. д.).

Вот пост Джеффа по теме.

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

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

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

Когда система разрабатывается, вы можете рассмотреть возможность «ненормализации» какой-либо ее части, если считаете это улучшением.

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

Думаю, мой ответ будет таким: руководствуйтесь своим здравым смыслом.

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

Хм.

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

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

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

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

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

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

Суть в том, что подобные решения должны учитываться самим приложением, прежде чем вы начнете стремиться к эффективности.ИМХО.

Когда вы проектируете свою базу данных, вы должны быть как можно ближе к значению данных, а НЕ к потребностям вашего приложения!

Хороший дизайн базы данных должен прослужить более 20 лет без изменений.

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

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

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

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

Приятно видеть так много вдохновляющих и обоснованных ответов.

Мой ответ будет (к сожалению):это зависит.

Два случая:* Если вы создаете модель данных, которая будет использоваться в течение многих лет и, следовательно, возможно, потребует внесения многих будущих изменений:используйте больше таблиц и меньше строк и довольно строгую нормализацию.* В других случаях вы можете выбрать между «больше таблиц — меньше строк» ​​или «меньше таблиц — больше строк».Этот последний подход может быть более интуитивным и простым для понимания, особенно для людей, относительно плохо знакомых с этой темой.

То же самое справедливо и для выбора между объектно-ориентированным подходом и другими вариантами.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top