Какой тип данных наиболее подходит для хранения IP-адреса в SQL server? [дубликат]



этот вопрос уже есть ответ здесь:



каким должен быть наиболее рекомендуемый тип данных для хранения IPv4-адреса в SQL server?



или, может быть, кто-то уже создал пользовательский тип данных SQL (.NET assembly) для это?



Мне не нужна сортировка.

876   15  

15 ответов:

сохранение адреса IPv4 как binary(4) наиболее соответствует тому, что он представляет, и позволяет легко запрашивать маски подсети. Однако он требует преобразования и выхода, если вы на самом деле после текстового представления. В этом случае вы можете предпочесть строковый формат.

мало используемая функция SQL Server, которая может помочь, если вы храните в виде строки, является PARSENAME, кстати. Не предназначен для IP-адресов, но идеально подходит для них. Вызов ниже вернемся '14':

SELECT PARSENAME('123.234.23.14', 1)

(нумерация справа налево).

обычно я просто использую varchar (15) для адресов IPv4 - но сортировка их-это боль, если вы не набираете нули.

Я также хранил их как INT в прошлом. System.Net.IPAddress есть GetAddressBytes метод, который возвращает IP-адрес в виде массива из 4 байт, представляющих IP-адрес. Вы можете использовать следующий код C# для преобразования IPAddress до int...

var ipAsInt = BitConverter.ToInt32(ip.GetAddressBytes(), 0);

я использовал это, потому что я должен был сделать много искал адреса обмана, и хотел, чтобы индексы были как можно меньше и быстрее. Затем, чтобы вытащить адрес обратно из int и в IPAddress объект в .net, используйте GetBytes метод on BitConverter чтобы получить int в виде массива байтов. Передайте этот массив байтов в конструктор на IPAddress это занимает массив байтов, и вы в конечном итоге обратно с IPAddress что вы начали с.

var myIp = new IPAddress(BitConverter.GetBytes(ipAsInt));

относительно этого комментария в принятом ответе

сортировка их-это боль, если вы не pad ноли.

вот трюк для SQL Server 2008 (от Itzik Ben-Gan в книги)

with ip_addresses as
(
SELECT '131.33.2.201' AS ip_address UNION ALL
SELECT '2.12.4.4' AS ip_address UNION ALL
SELECT '131.33.2.202' AS ip_address UNION ALL
SELECT '2.12.4.169' AS ip_address UNION ALL
SELECT '131.107.2.201' AS ip_address 
)
select ip_address
from ip_addresses
ORDER  BY CAST('/' + ip_address + '/' AS hierarchyid)

возвращает

ip_address
-------------
2.12.4.4
2.12.4.169
131.33.2.201
131.33.2.202
131.107.2.201

один из моих любимых статьи говорит о том, почему вы не должны использовать регулярные выражения для анализа IP-адресов. Большая часть того, о чем они говорят, действительно объясняет, почему вы должны быть очень осторожны с текстовыми представлениями IP-адресов. Я предлагаю вам прочитать его, прежде чем решить, какой тип данных использовать в вашей базе данных, и, вероятно, также для любой обработки вашего приложения (хотя статья написана о Perl, она полезна для любого язык.)

Я думаю, что в конце концов 32-битный тип данных (или четыре 8-битных типа данных) будет лучшим выбором.

протокол IPv4? инт? или tinyint x 4?

Это действительно зависит от того, является ли это просто хранение и извлечение или если это будет ранжированный критерий поиска.

Не забывайте о IPv6 - вам нужно гораздо больше места, если вам нужно хранить их-128bits по сравнению с 32 IPv4.

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

Я читаю много подобных вопросов здесь, и ни один из ответов в этом не упоминает ответ номер один в других: "для адресов IPv4 вы можете хранить их как int unsigned и использовать функции INET_ATON() и INET_NTOA() для возврата IP-адреса из его числового значения и наоборот."Я думаю, что это то, что я собираюсь сделать в своей БД, если я не решу использовать функции php, упомянутые выше.

лучший способ (когда нет необходимости сортировки и другого контроля на IPs) является сохранить его как int, хранить его как varchar etc. будет стоить намного больше производительности, чем просто невинный инт.

есть свойство IPAddress.Address но он устарел, я не знаю, почему, так как если вам не нужна сортировка или контроль над классами IP, лучший способ-сохранить его как целое число без знака (которое имеет максимальное значение 0xffffffff что составляет 255.255.255.255 в десятичное представление.

также класс IPAddress имеет конструктор, который принимает длинный аргумент.

и согласно визуализатору отладчика VS, этот класс IPAddress сам хранит свою внутреннюю переменную как одно число (не массив байтов).

подробнее о обходных путях хранения единицы в MS SQL Server:

для эффективного хранения пространства и когда значения должны быть обработаны (сопоставлены или сравнены с диапазоном), я использую int. IP-адрес действительно является всего лишь 32-битным значением.

для простого решения, где вы просто хотите сохранить значение для его просмотра, я использую varchar(15) для хранения строкового представления IP-адреса.

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

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

поскольку IP-адрес имеет 32 бита в нем, вы можете просто использовать LONG для хранения числового значения?
Это было бы не так расточительно, как использование VARCHAR, но тогда вам придется декодировать его обратно на IP-адрес, прежде чем использовать его, каждый раз, и задержка и накладные расходы, которые могут не стоить того.

Я бы, наверное, пошел с varchar или char.

и установите размер до 15.

наиболее подходящим типом данных для хранения IPv4-адреса в базе данных MSSQL является int. Единственный верный бит-это преобразование его обратно в точечную нотацию для отображения / сортировки, поэтому я рекомендую вам создать представление, которое автоматизирует это для вас.

Я новичок @ php, sql, но я думаю, что самый быстрый способ сохранить что-то в SQL db-это преобразовать его в значение int и сохранить как int.

я использовал функцию в php -

function ip_convert() {
    $ip = $_SERVER['REMOTE_ADDR'];
    $intip = str_replace(".","0",$ip);
    return $intip;
}

а потом я просто заменяю все точки нулями. Тогда, если мне нужно использовать этот ip из sql.. если ($ip = = ip_convert ())

но это только если вы используете PHP.

цитирую этой:

хранить IP-адреса в столбце CHAR (15). В зависимости от того, сколько данных вы храните, это может быть довольно расточительно (зачем нам хранить точки?). Я

Comments

    Ничего не найдено.