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

65

This question already has an answer here:

Datatype for storing ip address in SQL Server 10 answers

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

Or maybe someone has already created a user SQL data-type (.Net assembly) for it?

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

Не забывайте, что IPv6 уже здесь. Когда я анализирую журналы веб-сервера сегодня, я иногда сталкиваюсь с адресом v6 ... Eric J.
Как это может быть дубликатом нового вопроса? Chuck Le Butt

Ваш Ответ

15   ответов
-1

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

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

вам нужно понизить
1

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

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

Почему отрицательный голос? Проголосовал против.
0

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

-4

Я новичок @ 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.

Какое отношение это имеет вообще к SQL Server?
1.0.100.1 - & gt; 10001001 100.1.0.1 - & gt; 10001001 Если вы не добавляете ноль где-либо, это кажется очень плохой идеей. Обратите внимание, что вы можете преобразовать пунктирную запись в 32-разрядное целое число (если вы уверены, что это всегда будет адрес IPv4, а не имя хоста). или адрес IPv6)
61

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

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

SELECT PARSENAME('123.234.23.14', 1)

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

И при необходимости вы также можете создавать UDF для работы с этими данными с десятично-точечной нотацией ... Может быть, как для ввода, так и для извлечения.
Я не сказал, что они были. Я сказал, что это было истинное представление данных.
Да. Или, если вы работаете с ORM, это преобразование можно легко обернуть - например, пользовательский тип в (N) Hibernate.
как мне сделать выбор, чтобы он возвращал один int? Кроме того, что стоит больше места, один sql int или двоичный (4)? Поэтому я могу использовать IP-адрес & apos; конструктор (который занимаетlong в качестве аргумента)? посмотреть @ мой ответ:stackoverflow.com/questions/1038950/3445015#3445015 Shimmy
@DavidM почему не целое число? Не могли бы вы объяснить преимущества производительности хранения в виде двоичного файла вместо целого числа?
2

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

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

3

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

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

0

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

3

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

Это MySQL ....
3

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

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

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

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

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

Я на самом деле не понимаю ваш первый абзац ... вы говорите "store" как int или нет?
Что вы комментируете на этот пост:stackoverflow.com/questions/1385552/…
@Pacerier, Делай какint. Shimmy
3

IPV4? Int? или tinyint x 4?

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

26

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

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

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

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

var myIp = new IPAddress(BitConverter.GetBytes(ipAsInt));
Если вы добавляете IP-адрес, было бы разумнее использовать CHAR (15)
Вы не используете varchar и забыли про нули? Shimmy
я не дополняю нули, просто добавил это как предложение.
Просто добавив предложение :-)
Заполнение IP-адреса нулями может сделать его другим IP-адресом. 010.001.001.100 - это не то же самое, что 10.1.1.100. Если перед октетом указано значение с нулем, это означает, что этот октет записывается в восьмеричном виде. Правильный путь (tm) для хранения IP-адресов состоит в том, чтобы проанализировать их различные возможные представления и сохранить их в виде двоичных значений (32- или 128-разрядных, в зависимости от того, являются ли они адресами IPv4 или IPv6).
-4

квотированиеэтот:

Store IP addresses in a CHAR(15) column. Depending on how much data you're storing, this can be quite wasteful (why do we need to store the dots?). I

& Quot; 12121212 & Quot; это 12.12.12.12 или 12.121.2.12 или возможно 12.121.21.2 или ....
Вам необходимо сохранить точки, потому что в противном случае вы не смогли бы определить разницу между 127.1.1.10 и 127.1.11.0, и оба были бы сохранены как 1271110. Я предполагаю, что вы можете сохранить его как 4 отдельных байтовых поля, но если вы действительно обеспокоенный экономией места для большого количества данных, я не думаю, что это стоит дополнительных усилий (и обработки, чтобы собрать их вместе).
«Это может быть довольно расточительным» Если вы не храните все IP-адреса в мире, я думаю, что лучше хранить их с точками. «Преждевременная оптимизация - корень всего зла»
вы можете игнорировать точки, если вы добавляете значение, то есть 127.1.1.10 станет 127001001010
@tekBlues: & quot; Преждевременная оптимизация & quot; хороший дизайн базы данных.
4

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

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

Немного вне контекста, не так ли? Он сериализует их в базу данных - он будет контролировать это преобразование независимо от того, какой тип данных или формат он выберет. Эта статья просто педантична - я не вижу ни одного реального применения того, о чем она говорит.
Иногда простой тупой способ является лучшим
Это хорошая статья. Я давно не был у перл-монахов.
18

По поводу этого комментария в принятом ответе

sorting them is a pain unless you pad zeros.

Вот трюк для 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

Похожие вопросы