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

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

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

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


person raven    schedule 12.09.2008    source источник


Ответы (18)


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

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

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

person Chris Ammerman    schedule 12.09.2008
comment
Что такое «таблица нисходящего потока»? - person olive; 28.09.2010
comment
Я имею в виду нисходящий поток в контексте потока данных. По сути, это означает, что у вас есть процесс, который использует нормализованные таблицы в качестве источника и каким-то образом преобразует данные, а затем помещает результат в другое место. - person Chris Ammerman; 29.09.2010

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

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

person Bill the Lizard    schedule 12.09.2008

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

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

person swilliams    schedule 12.09.2008
comment
По моему опыту, это явно неверно. Я работал с запросами, которые объединяют десятки таблиц, каждая содержит более миллиона строк, и пока вы объединяетесь по первичным ключам, результаты возвращаются очень быстро. - person JosephStyons; 12.09.2008
comment
Что «быстро»? Если вы запускаете веб-сайт, который пытается обслуживать тысячи просмотров страниц в секунду, «достаточно быстро» имеет совершенно иное значение, чем база данных с одним пользователем, где все, что вас беспокоит, - это время отклика для пользователя. - person Chris Upchurch; 12.09.2008
comment
пока вы присоединяетесь к первичным ключам, результаты возвращаются очень быстро Ну да. Но, по моему опыту работы с большим количеством таблиц, более вероятно, что соединения будут происходить в столбцах, отличных от pk, неиндексированных столбцах и т. Д. - person swilliams; 12.09.2008
comment
Нормализация и последующее объединение таблиц обычно способствует повышению производительности, поскольку по определению можно быть более избирательным и избегать сканирования таблиц - самого медленного метода выбора. - person Ed Guiness; 12.09.2008
comment
Плохой дизайн обычно является самым большим фактором плохой работы, а не нормализация. - person Ed Guiness; 12.09.2008
comment
Да, у меня было приложение для обработки данных в реальном времени, и соединения убивали запросы. Я денормализовал данные, и все было хорошо, они снова интегрируются в нормализованную базу данных в конце дня, когда количество запросов снижается. - person Quibblesome; 12.09.2008

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

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

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

person JosephStyons    schedule 12.09.2008
comment
Согласованный. Я когда-либо делал денормализацию только для уменьшения сложности запроса, обычно для устранения некоторого несоответствия импеданса с помощью ORM. Никогда, потому что оптимизация требовалась для повышения производительности, даже в большом масштабе. - person Ben Simmons; 07.02.2015

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

person Joel Coehoorn    schedule 12.09.2008
comment
Привет, Джоэл, более узкие столы означают меньше? Если взять пример выше, если в адресе компании должен быть только 1 адрес, что лучше поместить все поля адреса в отдельную таблицу или в одну и ту же таблицу? Кроме того, если компания совершила много покупок, и я хочу сохранить сводку (например, TotalOrders, TotalOrderValue, TotalComplains, etc..), не лучше ли поместить эти поля в другую таблицу (даже если это однозначно с таблицей компании)? - person Sam; 23.06.2021
comment
@Sam Narrower означает меньше столбцов в таблице и, следовательно, возможно больше таблиц для обработки тех же полей. Очень редко бывает хорошей идеей хранить сводки. Если вы правильно индексируете, даже для крупных компаний создание сводки может оказаться эффективным во время запроса. - person Joel Coehoorn; 23.06.2021
comment
Спасибо Джоэл за вашу помощь - person Sam; 24.06.2021

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

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

person Mark Cidade    schedule 12.09.2008

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

person Chris Upchurch    schedule 12.09.2008
comment
У меня есть 40 уникальных полей с пользовательской информацией, которые уникальны, и они один к одному из системы аутентификации пользователей. Как вы думаете, нормально, если я сохраню эти 40 столбцов в одной таблице? Если я разделю их, мне нужно будет писать больше объединений в моих запросах :-(. Вы можете предложить - person vkrams; 17.06.2013

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

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

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

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

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

Вот сообщение Джеффа по этой теме.

person Michael Haren    schedule 12.09.2008

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

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

person Dillie-O    schedule 12.09.2008

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

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

person zappan    schedule 12.09.2008
comment
Мои 2 цента: я не согласен; такая оптимизация во время проектирования - классический случай преждевременной оптимизации. Подождите, пока вы не увидите, что производительность - это проблема, прежде чем пожертвовать хорошим дизайном. - person JosephStyons; 12.09.2008

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

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

person Craig H    schedule 12.09.2008

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

person kemiller2002    schedule 12.09.2008

Хм.

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

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

person John Christensen    schedule 12.09.2008

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

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

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

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

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

person Marco Guignard    schedule 29.07.2014

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

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

person ColinYounger    schedule 12.09.2008

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

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

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

person Tundey    schedule 12.09.2008

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

person pbars23    schedule 11.08.2014

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

Я бы ответил (к сожалению): это зависит от обстоятельств.

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

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

person Bart Rozinga    schedule 21.11.2016