Відповіді:
Не зберігайте як рядок. Використовуйте int unsigned
стовпець і зберігайте / отримуйте відповідно INET_ATON()
та INET_NTOA()
відповідно. AFAIK mysql не підтримує INET_ * для ipv6.
Редагувати відповідно до коментаря
Використання вбудованої функції для перетворення IP-адрес у цілі числа (та зберігання цих цілих чисел у базі даних) має побічний ефект автоматичної перевірки цих IP-адрес. Скажімо, ви зберігаєте IP-адресу як VARCHAR (16), ви повинні переконатися, що не зберігаєте недійсні IP-адреси (наприклад, 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. Read Best FieldType для зберігання IP - адреса ... .
Коротко кажучи, я пропоную, що я другий, використовувати INT (10) UNSIGNED.
Отже, використовуючи 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 повертає a varbinary(16)
і IPv4 повертає a varbinary(4)
.
http://dev.mysql.com/doc/refman/5.6/uk/miscellaneous-functions.html#function_inet6-aton
Ви можете зберігати до 15 символів. Будь ласка, не використовуйте VARCHAR (15), тому що це 16 байт (перший байт керує довжиною рядка і, таким чином, більш повільним пошуком і зберіганням). Використовуйте CHAR (15) завжди на щось на зразок IP-адреси.
На жаль, не можу коментувати відповіді. Існує питання про це на stackoverflow. І я повністю згоден з обраною відповіддю: використання 2xBIGINT - це, мабуть, найкращий спосіб для ipv6 в даний час.
Я б запропонував перейти на 2 * BIGINT, але переконайтесь, що вони НЕ ЗНАЧЕНІ. Є певний природний розкол на кордоні адреси / 64 в IPv6 (оскільки а / 64 - найменший розмір нетблока), який би добре узгоджувався з цим.
Також можна зберігати ipv4 на цьому bigints - або позначаючи один з них NULL, або використовуючи формат V4COMPAT