Odpowiedzi:
Nie przechowuj jako łańcucha. Użyj int unsigned
kolumny i zapisz / pobierz za pomocą INET_ATON()
i INET_NTOA()
. Mysql AFAIK nie obsługuje INET_ * dla ipv6.
EDYTUJ zgodnie z komentarzem
Użycie wbudowanej funkcji do konwersji adresów IP na liczby całkowite / z liczb całkowitych (a więc przechowywanie liczb całkowitych w bazie danych) ma efekt uboczny automatycznego sprawdzania tych adresów IP. Załóżmy, że przechowujesz adres IP jako VARCHAR (16), musisz upewnić się, że nie zapisujesz nieprawidłowych adresów IP (np. 999.999.999.999) z pewną niestandardową weryfikacją. Zajmują się tym funkcje INET_ *.
Prawdopodobnie czas zacząć rozważać IPv6. MySQL nie ma metod konwersji adresów IPv6 na format binarny. Czterdziestoznakowy ciąg obsługuje wszystkie normalne adresy IPv6. Istnieje format, który może przekraczać 40 znaków, uważam, że te mało prawdopodobne są ćwiczenia.
Możesz obliczyć rozmiar na podstawie informacji, że będzie maksymalnie 8 czterech grup znaków z 7 znakami separatora. Nieprawidłowy format zastępuje dwie ostatnie grupy adresem w formacie IPv4. Bez kompresji adresu zastępuje ostatnie 9 znaków maksymalnie 15 znakami.
Jeśli przechowujesz bloki, wskazanie rozmiaru bloku może zająć 4 znaki zamiast 3 znaków wymaganych dla IPv4.
Powinieneś upewnić się, że formatowanie, które otrzymujesz, jest spójne, ale całe oprogramowanie, które widziałem, zapewnia spójne formaty adresów.
Sugeruję migrację do PostgreSQL i użycie typów danych INET lub 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
Oto najlepsza odpowiedź na jednej z list mailingowych MySQL. Przeczytaj Najlepszy FieldType przechowywać adres IP ... .
W skrócie sugeruje, że po drugie, używam INT (10) UNSIGNED.
Tak więc używając 192.168.10.50:
(192 * 2 ^ 24) + (168 * 2 ^ 16) + (10 * 2 ^ 8) + 50 = 3232238130 (wyniki w 192.168.10.50)
W MySQL możesz bezpośrednio użyć,
SELECT INET_ATON('192.168.10.50');
aby uzyskać3232238130
.
Lub
192 + (168 * 2 ^ 8) + (10 * 2 ^ 16) + (50 * 2 ^ 24) = 839559360 (wstecz, wyniki 50.10.168.192)
W MySQL możesz bezpośrednio użyć,
SELECT INET_NTOA(3232238130);
aby odzyskać192.168.10.50
.
Jak MySQL v5.6.3 dodali wsparcie INET6_ATON
i INET6_NOTA
że zajmie się adresów IPv4 i IPv6. Ale nie przechowują go już jako liczby całkowitej. IPv6 zwraca varbinary(16)
a, a IPv4 zwraca a varbinary(4)
.
http://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_inet6-aton
Możesz przechowywać do 15 znaków. Nie używaj VARCHAR (15), ponieważ jest to 16 bajtów (pierwszy bajt zarządza długością łańcucha, a zatem wolniej pobiera i zapisuje). Użyj CHAR (15) zawsze na czymś takim jak adres IP.
Przepraszamy, nie mogę komentować odpowiedzi. Jest pytanie na ten temat na temat przepełnienia stosu. I całkowicie zgadzam się z wybraną odpowiedzią: użycie 2xBIGINT jest prawdopodobnie najlepszym obecnie sposobem na ipv6.
Sugeruję wybranie 2 * DUŻYCH, ale upewnij się, że są PODPISANE. Jest coś w rodzaju naturalnego podziału na granicy adresu / 64 w IPv6 (ponieważ a / 64 jest najmniejszym rozmiarem bloku sieciowego), który dobrze by się z tym zgadzał.
Możliwe jest również przechowywanie ipv4 na tym biginterze - albo oznaczając jeden z nich NULL, albo używając formatu V4COMPAT