Оптимальная структура базы данных - более широкая таблица с пустыми полями или большее количество таблиц? - PullRequest
12 голосов
/ 26 ноября 2010

Мне нужно добавить дополнительные данные в базу данных, и у меня есть выбор между изменением существующей таблицы (table_existing) или созданием новых таблиц.

Вот как выглядит table_existing прямо сейчас:

table_existing
-------------------------
| ID | SP | SV | Field1 |
| .. | WW |  1 | ...... |
| .. | WW |  1 | ...... |
-------------------------

Опция (A)

table_existing
----------------------------------------------------------------------
| ID | SP | SV | Field1 | Field2 | Field3 | Field4 | Field5 | Field6 |
| .. | XX |  1 | ...... | ...... | ...... | ...... | ...... | ...... |
| .. | YY |  2 | ...... | ...... | ...... | ...... | ...... | ...... |
----------------------------------------------------------------------

Опция (B)

table_existing would be converted into table_WW_1_data
---------------
| ID | Field1 |
| .. | ...... |
| .. | ...... |
---------------

table_XX_1_data
------------------------
| ID | Field1 | Field2 |
| .. | ...... | ...... |
| .. | ...... | ...... |
------------------------

table_YY_2_data
---------------------------------
| ID | Field1 | Field2 | Field3 |
| .. | ...... | ...... | ...... |
| .. | ...... | ...... | ...... |
---------------------------------

Контекст: комбинация SP, SV определяет «количество» полей, которые будутнаселен.Например, (XX, 1) имеет 2 поля.(YY, 2) имеет 3 поля.

Если бы я использовал вариант (A), у меня было бы много пустых / NULL-значений в «более широкой» таблице.Вариант (B), я в основном создаю больше таблиц ... по одной на "каждую" комбинацию SP, SV - всего будет 4-5.Но каждый из них будет полностью заполнен нужным количеством полей.table_existing также будет изменен.

Какая структура базы данных более оптимальна с точки зрения скорости? Я думаю, что с точки зрения удобства обслуживания, Option(B) может быть лучше.


Edit1

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

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

Я пытаюсь понять, есть ли плюсы и минусы в том, что ОДНА большая таблица со многими неиспользуемыми значениями против одинаковых данных, разбитых по большему количеству таблиц.Приводит ли большее количество таблиц к снижению производительности в базе данных (у нас уже ~ 80 таблиц)?

Ответы [ 5 ]

19 голосов
/ 27 ноября 2010

Какая структура базы данных более оптимальна с точки зрения скорости?

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

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

Более маленькие таблицы - это природа нормализованной реляционной базы данных. Привыкай к этому. Меньше, большие таблицы медленнее, из-за отсутствия нормализации, дубликатов и нулей. Присоединение в SQL громоздко, но это все, что у нас есть. В самих соединениях нет затрат, только в случае объединения таблиц (строки, ширина строки, столбцы соединения, типы данных, несоответствия, индексы [или нет]). Базы данных оптимизированы для нормализованных таблиц, а не для куч данных. И большое количество таблиц.

Что является оптимальным показателем производительности, неудивительно. По двум причинам:

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

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

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

Ответ остается неизменным независимо от того, рассматриваете ли вы 4 или 400 новых таблиц.

  • Одна рекомендация, если вы серьезно рассматриваете такое количество столов: вы движетесь в направлении Шестой Нормальной Формы, не осознавая этого. Так осознайте это и сделайте это формально. 400 столов будут намного лучше контролироваться. Если вы сделаете это для профессионала, они нормализуют его и в итоге получат менее 100.
2 голосов
/ 28 ноября 2010

Я администратор базы данных SQL-сервера, поэтому буду предлагать то, что буду делать в SQL Server 2008.

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

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

  1. , переименуйте таблицу
  2. Создайте представление со структурой исходной таблицы и назовите его именем исходной таблицы

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

0 голосов
/ 26 ноября 2010

Я согласен с DVK, что если вы выберете (B), вам придется выполнять запросы к нескольким таблицам, чтобы получить все ваши исходные значения Field1, не говоря уже о сложности JOIN и т. Д. Это не имеет смысла, если не разбить наотдельные таблицы также соответствовали разделению на разные сущности.

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

0 голосов
/ 26 ноября 2010

Я помню, что раньше у меня были такие сомнения.

С точки зрения проверки данных вариант (B) оказывается более благоприятным.Вы можете наложить ограничения на поля лучше.Именно поэтому вы захотите разделить, скажем, таблицу users на students, teachers и т. Д., Чтобы применить ограничения NOT NULL в зависимости от роли пользователя.

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

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

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

0 голосов
/ 26 ноября 2010

Ваши запросы, скорее всего, будут нуждаться в объединении строк из набора (XX, 1) с набором (YY, 2) и т. Д ...?

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

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

...