Збереження IP-адреси


25

Я повинен зберігати IP-адресу всіх зареєстрованих користувачів у базі даних. Мені цікаво, скільки символів я повинен оголосити для такої колонки?

Чи слід також підтримувати IPv6? Якщо так, яка максимальна довжина IP-адреси?

Відповіді:


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.

Ви повинні переконатися, що форматування, яке ви отримуєте, є послідовним, але все програмне забезпечення, яке я бачив, дає стійкі формати адрес.


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

Щоб дізнатися, які IP-адреси є в мережі, SELECT * FROM test WHERE адреса << '1.2.3.0/24'::inet;
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, який є 32-бітовим. Не потрібно коментувати кожен коментар / відповідь, наполягаючи на ваших знаннях.
Очі

У вашій відповіді не зазначається, що він стосується лише старого Інтернет-протоколу, тоді як у цьому питанні прямо вказано IPv6. Зважаючи на те, що останній Інтернет-провайдер міського голови (принаймні в моїй країні) підтримуватиме IPv6 до кінця цього року, вкрай погана ідея розробити структуру бази даних, яка не може впоратися з нею.
Гендрік Бруммерман


1

Ви можете зберігати до 15 символів. Будь ласка, не використовуйте VARCHAR (15), тому що це 16 байт (перший байт керує довжиною рядка і, таким чином, більш повільним пошуком і зберіганням). Використовуйте CHAR (15) завжди на щось на зразок IP-адреси.


Максимальна довжина IP-адреси - 45 символів.
Гендрік Бруммерман

CHAR не буде обробляти пробіли?
Гай

0

На жаль, не можу коментувати відповіді. Існує питання про це на stackoverflow. І я повністю згоден з обраною відповіддю: використання 2xBIGINT - це, мабуть, найкращий спосіб для ipv6 в даний час.

Я б запропонував перейти на 2 * BIGINT, але переконайтесь, що вони НЕ ЗНАЧЕНІ. Є певний природний розкол на кордоні адреси / 64 в IPv6 (оскільки а / 64 - найменший розмір нетблока), який би добре узгоджувався з цим.

Також можна зберігати ipv4 на цьому bigints - або позначаючи один з них NULL, або використовуючи формат V4COMPAT

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.