Хранение IP-адреса

25

Я должен хранить IP-адрес всех зарегистрированных пользователей в базе данных. Мне интересно, сколько символов я должен объявить для такого столбца?

Должен ли я также поддерживать IPv6? Если да, какова максимальная длина IP-адреса?

Cleankod
источник

Ответы:

27

Не хранить в виде строки. Используйте int unsignedстолбец и сохраните / получите с INET_ATON()и INET_NTOA()соответственно. AFAIK mysql не поддерживает INET_ * для ipv6.

РЕДАКТИРОВАТЬ согласно комментарию

Использование встроенной функции для преобразования IP-адресов в целые числа и из них (и, таким образом, сохранение этих целых чисел в базе данных) имеет побочный эффект автоматической проверки этих IP-адресов. Скажем, вы храните IP-адрес как VARCHAR (16), вы должны убедиться, что не сохранили недопустимые IP-адреса (например, 999.999.999.999) с некоторой пользовательской проверкой. Функции INET_ * позаботятся об этом.

Мистер Шунц
источник
1
-1, IP-адреса до 128 бит, а самый большой целочисленный тип, поддерживаемый MySQL, равен 64 битам.
Хендрик Браммерманн
3
IPv4 является 32-битным. 128-бит для IPv6, который, как он упомянул, материал INET_ * не поддерживает.
Ричард
1
Для адреса IPv6 используйте функции INET6_ATON () и INET6_NTOA (), см. Пример - rathishkumar.in/2017/08/how-to-store-ip-address-in-mysql.html
rathishDBA
6

Вероятно, пришло время начать рассматривать IPv6. MySQL не имеет методов для преобразования адресов IPv6 в двоичный формат. Строка из сорока символов будет обрабатывать любые обычные адреса IPv6. Существует формат, который может превышать 40 символов, я бы посчитал, что это вряд ли произойдет на практике.

Вы можете рассчитать размер на основе информации о том, что будет не более 8 четырехсимвольных групп с 7 символами-разделителями. Ненормальный формат заменяет две последние группы адресом формата IPv4. Без сжатия адреса он заменяет последние 9 символов до 15 символов.

Если вы храните блоки, для указания размера блока может потребоваться 4 символа, а не 3 символа, требуемые для IPv4.

Вы должны убедиться, что форматирование, которое вы получаете, является согласованным, но все программное обеспечение, которое я видел, предоставляет согласованные форматы для адресов.

BillThor
источник
2
Я полностью согласен, IPv6 идет, и лучше быть готовым к этому, чем ждать его как Y2K: D
Джефф
Не только идет, но уже здесь, в моих системах.
BillThor
6

Я бы предложил перейти на PostgreSQL и использовать типы данных INET или CIDR .

CREATE TABLE test ( test_id serial PRIMARY KEY, address inet );
INSERT INTO test ( address ) VALUES ( '1.2.3.4'::inet );
INSERT INTO test ( address ) VALUES ( 'a:b::c:d'::inet );
SELECT * FROM test;
 test_id | address  
---------+----------
       1 | 1.2.3.4
       2 | a:b::c:d
JKJ
источник
Чтобы узнать, какие IP- адреса
JKJ
4

Вот лучший ответ, сделанный в одном из списков рассылки MySQL. Read Best FieldType для хранения IP - адрес ... .

Вкратце он предлагает, во-вторых, использовать INT (10) UNSIGNED.

  1. Он использует меньше памяти (только 4 байта)
  2. Лучше всего подходит для сортировки и поиска диапазонов IP-адресов, особенно если вы ищете страну происхождения ваших посетителей.

Итак, используя 192.168.10.50:

(192 * 2 ^ 24) + (168 * 2 ^ 16) + (10 * 2 ^ 8) + 50 = 3232238130 (результат 192.168.10.50)

В MySQL вы можете напрямую использовать SELECT INET_ATON('192.168.10.50'); для получения 3232238130.

Или

192 + (168 * 2 ^ 8) + (10 * 2 ^ 16) + (50 * 2 ^ 24) = 839559360 (в обратном порядке результат 50.10.168.192)

В MySQL вы можете напрямую использовать, SELECT INET_NTOA(3232238130); чтобы 192.168.10.50вернуться.

глаз
источник
Впечатляет, +1 для Вас! Использование 4 байтов без знака обязательно превосходит манипуляции со строками.
RolandoMySQLDBA
-1, IP-адреса до 128 бит, а самый большой целочисленный тип, поддерживаемый MySQL, равен 64 битам.
Хендрик Браммерманн
3
nhnb, IPv6 составляет 128 бит, но разговор о IPv4 , который IS 32 бит. Не нужно комментировать каждый комментарий / ответ, настаивая на ваших знаниях.
Eye
В вашем ответе не упоминается, что он имеет дело только со старым интернет-протоколом, тогда как в конце вопроса явно упоминается IPv6. Учитывая, что последний мэр интернет-провайдера (по крайней мере, в моей стране) будет поддерживать IPv6 до конца этого года, крайне плохая идея создать структуру базы данных, которая не сможет справиться с этим.
Хендрик Браммерманн
1

Вы можете хранить до 15 символов. Пожалуйста, не используйте VARCHAR (15), потому что это 16 байтов (первый байт управляет длиной строки и, следовательно, медленнее извлекает и хранит). Используйте CHAR (15) всегда на чем-то вроде IP-адреса.

RolandoMySQLDBA
источник
Максимальная длина IP-адреса составляет 45 символов.
Хендрик Браммерманн
Разве CHAR не дополнит его пробелами?
Гай
0

Извините, не могу комментировать ответы. Есть вопрос об этом на stackoverflow. И я полностью согласен с выбранным ответом: использование 2xBIGINT, вероятно, является лучшим способом для ipv6 в настоящее время.

Я бы предложил 2 * BIGINT, но убедитесь, что они НЕ ПОДПИСАНЫ. На границе адреса / 64 в IPv6 существует своего рода естественное разделение (так как / 64 - это наименьший размер сетевого блока), которое хорошо согласуется с этим.

Также можно хранить ipv4 на этих bigints - либо пометив один из них как NULL, либо используя формат V4COMPAT

RVS
источник