Одиночная таблица против производительности двух связанных таблиц - PullRequest
0 голосов
/ 05 июня 2019

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

Countries
[PK]CountryId, CountryName, CapitalCityName, CapitalCityPostCode

Или мы можем расположить его более нормализованным образом в 2 таблицы в соотношении 1: 1:

 Coutries  
 [PK]CountryId, CountryName, [FK]CapitalCityId

и

 CapitalCities
 [PK]CapitalCityId, CapitalCityName, CapitalCityPostCode, [FK]CountryId

Как это повлияет на производительность? Например, если нам нужно перечислить все страны с названиями столиц, будет ли это значительно быстрее в первом случае? Сколько записей / столбцов мне нужно, чтобы увидеть разницу?

Ответы [ 3 ]

2 голосов
/ 05 июня 2019

В приведенном выше примере с таблицами для Country и CapitalCities нормализация не очень полезна.Отношение один к одному не вызывает дублирования или осложнений при чтении и обновлении данных.Это было бы полезно в случае данных, для которых нужны таблицы, такие как Страна и Город со страной, в которой столица обозначена как fk of City.Чтение из двух таблиц требует объединения, которое определенно медленнее (не намного), чем чтение из одной таблицы.При записи нескольких сотен различие будет составлять от 10 до 15 мс.

1 голос
/ 05 июня 2019

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

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

Как и в любой другой разработке, нет ни одной серебряной пули.Всегда есть исключения из правил;контекст имеет значение для каждого вопроса.Тем не менее, широкий подход гласит: нормализуйтесь, если вы не ЗНАЕТЕ, что НИКОГДА не будет роста.(никогда не бывает долго! но тогда, возможно, система имеет известный срок годности и никогда не достигнет такого длительного срока существования.)

0 голосов
/ 05 июня 2019

В общем случае, если существует однозначное соответствие, нет смысла разбивать данные на две таблицы.Вы не «нормализуете» данные, если нет избыточности.Просто укажите, что столбец CapitalCityName проиндексирован, если вам нужен поиск по городам.Вы по-прежнему будете получать результаты поиска и избавляться от необходимости объединять две таблицы для запроса.

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

...