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

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

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

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

18 ответов


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

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

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


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

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


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

Джефф писал немного об этом относительно дизайна StackOverflow. См. также ссылки post Jeff на by Dare Obasanjo.


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

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

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


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


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

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


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


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

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

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

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

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

вот сообщение Джеффа по теме.


есть преимущества наличия таблиц с меньшим количеством столбцов, но вам также нужно посмотреть на свой сценарий выше и ответить на эти вопросы:

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


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

когда система разрабатывается, вы могли бы рассмотреть 'unnormalizing' часть если вы видите, что в качестве улучшения.


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

Я думаю, что мой ответ будет, используйте свой здравый смысл.


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


Мда.

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

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


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

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


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

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

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


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

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

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

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

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


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


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

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

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

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