Вопрос

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

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

Это было полезно?

Решение

Не храните в качестве строки. Использовать int unsigned колонка и хранить/извлечь с INET_ATON() а также INET_NTOA() соответственно. AFAIK MySQL не поддерживает inet_* для IPv6.

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

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

Другие советы

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

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

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

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

Я бы предложил миграцию в 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

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

Вкратце, это предлагает, что я второй, использовать int (10) без знака.

  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 назад.

По состоянию на MySQL v5.6.3 они добавили поддержку INET6_ATON а также INET6_NOTA Это позаботится об адресах IPv4 и IPv6. Но они больше не хранят его как целое число. IPv6 возвращает а varbinary(16) и IPv4 возвращает varbinary(4).

http://dev.mysql.com/doc/refman/5.6/en/miscellory-functions.html#function_inet6-aton

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

Извините, не могу комментировать ответы. Eсть Вопрос об этом на Stackoverflow. И я полностью согласен с выбранным ответом: использование 2xbigint, вероятно, является лучшим способом для IPv6 в настоящее время.

Я бы посоветовал пойти на 2 * bigint, но убедитесь, что они без подписи. На границе адреса /64 в границе адреса /64 есть своего рода естественный раскол (так как A /64 - самый маленький размер сети), что будет хорошо соответствовать этому.

Также можно хранить IPv4 в этом Bigints - либо отметив один из них NULL, либо с помощью формата V4Compat

Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top