Производительность - Int против Char (3) - PullRequest
3 голосов
/ 18 февраля 2010

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

int id

int FK_id

varchar (50) info1

varchar (50) info2

varchar (50) info3

int forTable или char (3) forTable

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

Я вижу два решения:

  • Целое число, представляющее собой FK таблицы настроек, которая имеет фактическое значение.
  • Поле char (3) с сокращенной версией таблицы.

Мне интересно, знает ли кто-нибудь, будет ли один более выгодным по скорости, чем другой, или возникнут какие-либо серьезные проблемы с использованием char (3)

Примечание: Я буду создавать индексированное представление для каждого из 6 различных значений для этого поля. Эта таблица будет содержать ~ 30 тыс. Строк, и ее необходимо будет объединить с гораздо большими таблицами

Ответы [ 6 ]

4 голосов
/ 18 февраля 2010

В этом случае это, вероятно, не имеет значения, за исключением накладных расходов (A против a против ä va à)

Я бы использовал char (3), скажем, для кода валюты, например CHF, GBP и т. Д. Но если бы мой естественный ключ был "швейцарский франк", "британский фунт" и т. Д., Я бы взял числовое значение.

3 байта + сопоставление против 4 байтов числовых? Вам понадобится миллион строк или вы будете управлять страной среднего размера, прежде чем это будет иметь значение ...

2 голосов
/ 19 февраля 2010

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

Я могу придумать пару вариантов:

Вариант 1: таблица ссылок для каждой родительской таблицы. Это будет архитектура Hoyle. Итак, что-то вроде:

Create Table MyTable(
                    id int not null Primary Key Clustered
                    , info1 varchar(50) null
                    , info2 varchar(50) null
                    , info3 varchar(50) null
                    )

Create Table LinkTable1(
                        MyTableId int not null
                        , ParentTable1Id int not null
                        , Constraint PK_LinkTable1 Primary Key Clustered( MyTableId, ParentTable1Id )
                        , Constraint FK_LinkTable1_ParentTable1
                            Foreign Key ( MyTableId )
                            References MyTable ( Id )   
                        , Constraint FK_LinkTable1_ParentTable1
                            Foreign Key ( ParentTable1Id )
                            References ParentTable1 ( Id )  
                        )
...
Create Table LinkTable2...LinkTable3

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

Если вы довольны существующим дизайном, то в отношении размера поля я бы использовал полное имя таблицы. Честно говоря, разница в производительности между char (3) и varchar (50) или даже varchar (128) будет незначительной для количества данных, которые вы, вероятно, поместите в таблицу. Если бы вы действительно думали, что у вас будут миллионы строк, я бы настоятельно рекомендовал вариант связывания таблиц.

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

2 голосов
/ 18 февраля 2010

Рассматривали ли вы использовать TinyInt. Для сохранения значения требуется только один байт. TinyInt имеет диапазон значений от 0 до 255.

1 голос
/ 19 февраля 2010

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

Хотя это может показаться излишним, но многое упрощается, и добавление новых таблиц ссылок не сложнее, чем адаптация новых типов FK. Кроме того, его легче расширить до случая, когда объекту требуется более 1-1 отношения с одной таблицей или требуется несколько 1-1 отношений с 6 другими объектами.

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

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

0 голосов
/ 18 февраля 2010

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

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

Jacob

0 голосов
/ 18 февраля 2010

Я думаю, здесь нужно маленькое целое число (tinyint).«Сокращенная версия» слишком похожа на магическое число.

Я также считаю, что производительность должна быть выше целого числа (3).

...