Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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

SELECT PARSENAME('123.234.23.14', 1)

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

Ответ 2

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

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

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

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

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

Ответ 3

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

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

Вот трюк для SQL Server 2008 (от Ицика Бен-Гана в этой книге)

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

Ответ 4

IPV4? Int? или tinyint x 4?

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

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

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

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

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

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

Подробнее об обходах, хранящихся в MS SQL Server, читайте больше:

Ответ 8

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

Ответ 9

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

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

Ответ 10

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

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

Ответ 11

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

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

Ответ 12

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

Ответ 13

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

Ответ 14

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

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

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

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

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

Ответ 15

Цитата this:

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