Какой тип данных наиболее подходит для хранения IP-адреса в SQL server? [дубликат]
этот вопрос уже есть ответ здесь:
каким должен быть наиболее рекомендуемый тип данных для хранения IPv4-адреса в SQL server?
или, может быть, кто-то уже создал пользовательский тип данных SQL (.NET assembly) для это?
Мне не нужна сортировка.
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метод onBitConverterчтобы получить 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-адрес, прежде чем использовать его, каждый раз, и задержка и накладные расходы, которые могут не стоить того.
наиболее подходящим типом данных для хранения 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