Я собираюсь создать таблицу с двумя полями - ID
как BIGINT
и IPAddress
как либо varchar(45)
или varbinary(16)
. Идея состоит в том, чтобы сохранить все уникальные IP-адреса и использовать ссылку ID
вместо фактической IP address
в других таблицах.
Как правило, я собираюсь создать хранимую процедуру, которая возвращает ID
заданный IP address
или (если адрес не был найден) вставить адрес и вернуть сгенерированный ID
.
Я ожидаю иметь много записей (я не могу точно сказать, сколько), но мне нужно, чтобы хранимая процедура, описанная выше, была выполнена как можно быстрее. Итак, мне интересно, как сохранить фактический IP-адрес - в текстовом или байтовом формате. Что будет лучше?
Я уже написал SQL CLR
функции для преобразования байтов IP-адреса в строку и наоборот, поэтому преобразование не является проблемой (работа с обоими IPv4
и IPv6
).
Я думаю, мне нужно создать индекс для оптимизации поиска, но я не уверен, стоит ли включать IP address
поле в кластеризованный индекс или создавать отдельный индекс и с каким типом поиск будет быстрее?
IPv4
я думаю, я бы преобразовал адресINT
и использовал поле в качестве ключа индекса. Но дляIPv6
меня нужно использовать дваBIGINT
поля, и я предпочитаю хранить значение в одном поле - мне кажется более естественным.Ответы:
Поскольку термин «текст» здесь относится к
VARCHAR(45)
«байты»VARBINARY(16)
, я бы сказал: ни то, ни другое .Учитывая следующую информацию (из статьи Википедии по IPv6 ):
Я бы начал с использования 8
VARBINARY(2)
полей для представления 8 групп. Поля для групп 5 - 8 должны бытьNULL
такими, поскольку они будут использоваться только для адресов IPv6. Поля для групп 1 - 4 должны бытьNOT NULL
такими, как они будут использоваться как для адресов IPv4, так и для адресов IPv6.Поддерживая независимость каждой группы (в отличие от объединения их в
VARCHAR(45)
или,VARBINARY(16)
или даже в двеBIGINT
области), вы получаете два основных преимущества:IF
/IIF
/CASE
операторы для облегчения этого.ROW COMPRESSION
илиPAGE COMPRESSION
. Поскольку оба типа COMPRESSION позволят использовать поля, которые0x00
должны занимать 0 байтов, все эти группы нулей теперь не будут вам ничего стоить. С другой стороны, если вы сохранили приведенный выше пример адреса (в цитате Википедии), тогда 3 набора всех нулей в середине будут занимать свое полное пространство (если вы не выполняетеVARCHAR(45)
и не используете сокращенную запись) , но это может не сработать для индексации и потребует специального разбора для восстановления его в полный формат, поэтому давайте предположим, что это не вариант ;-).Если вам нужно захватить сеть, создайте
TINYINT
поле для этого с именем[Network]
:-)Для получения дополнительной информации о значении сети, вот некоторая информация из другой статьи Википедии об адресе IPv6 :
Для индексации, я бы сказал, создайте некластеризованный индекс на 8 полях группы и, возможно, на поле сети, если вы решите включить это.
Конечный результат должен выглядеть примерно так:
Заметки:
BIGINT
это поле для идентификатора, но действительно ли вы собираетесь собирать более 4 294 967 295 уникальных значений? Если это так, то просто измените поле на BIGINT, а затем вы даже можете изменить начальное значение на 0. Но в противном случае вам лучше использовать INT и начинать с минимального значения, чтобы вы могли использовать весь диапазон этого типа данных. ,SELECT *
операции поля будут возвращены в ожидаемом порядке. Но индекс их идущие вверх , от 1 до 8, как то , как они заполнены.Пример (незавершенный) вычисляемого столбца для представления значений в текстовой форме:
Контрольная работа:
Результат:
источник
VARDECIMAL
закончено,VARBINARY
посколькуDATA_COMPRESSION
недоступно?BINARY(16)
;-). Можете ли вы привести пример с начальным / конечным диапазоном и по крайней мере двумя возвращаемыми строками, один действительный и хотя бы один недействительный? Возможно, VARbinary сокращает некоторые значения.Меньше всегда будет быстрее. С меньшими значениями вы можете разместить больше из них на одной странице, следовательно, меньше ввода-вывода, потенциально меньше B-деревьев и т. Д.
Разумеется, при прочих равных условиях (накладные расходы на перевод, читаемость, совместимость, загрузка процессора, возможность индексации и т. Д.).
источник