Оптимизация баз данных SQL путем добавления столбцов индекса - PullRequest
1 голос
/ 26 мая 2010

скажем, у меня есть база данных, похожая на эту;

Product with columns [ProductName] [Price] [Misc] [Etc]
Order with columns [OrderID] [ProductName] [Quantity] [Misc] [Etc] 

ProductName - это первичный ключ Product, некоторый тип строки и уникальный.
OrderID является первичным ключом и имеет некоторый целочисленный тип, а ProductName является внешним ключом.

Скажем, я меняю первичный ключ Product на новый столбец целочисленного типа, например [ProductID].

Это уменьшит размер базы данных и оптимизирует поиск, объединяющий эти две таблицы (и аналогичные операции), или эти оптимизации выполняются автоматически (большинство / общие / основные) Реализации баз данных SQL?

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

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

Ответы [ 5 ]

2 голосов
/ 26 мая 2010

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

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

Я не мог бы сказать это лучше, поэтому проверьте этот ответ: Должен ли я создать таблицу с первичным ключом varchar илиint , цитата из этого ответа:

Использование VARCHAR (10) или (20) просто занимает слишком много места - 10 или 20 байтов вместо 4, и сколько людейне знаю - значение ключа кластеризации будет повторяться для каждой записи индекса в каждом некластеризованном индексе таблицы, поэтому потенциально вы тратите много места (не только на диске - это дешево), но ив основной памяти SQL Server).Кроме того, поскольку он переменный (может быть 4, может быть 20 символов), SQL-серверу сложнее правильно поддерживать хорошую структуру индекса

0 голосов
/ 26 мая 2010

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

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

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

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

0 голосов
/ 26 мая 2010

Целочисленный тип данных в большинстве реализаций будет меньше по размеру, чем строка (CHAR, VARCHAR и т. Д.), Это уменьшит размер вашего индекса.

Кроме того, при сравнении строк возникают некоторые проблемы:

  1. Некоторые базы данных, а именно MySQL, сжимают строковые ключи, что может сделать поиск менее эффективным.

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

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

0 голосов
/ 26 мая 2010

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

0 голосов
/ 26 мая 2010

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

целочисленные столбцы autoinc в качестве первичного кластерного ключа подходят для вставок

...