Przechowywanie adresu IP

25

Muszę przechowywać adres IP wszystkich zarejestrowanych użytkowników w bazie danych. Zastanawiam się, ile znaków powinienem zadeklarować dla takiej kolumny?

Czy powinienem również obsługiwać IPv6? Jeśli tak, jaka jest maksymalna długość adresu IP?

Cleankod
źródło

Odpowiedzi:

27

Nie przechowuj jako łańcucha. Użyj int unsignedkolumny 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_ *.

Pan Shunz
źródło
1
-1, adresy IP są do 128 bitów, a największy typ liczb całkowitych obsługiwany przez MySQL to 64 bity.
Hendrik Brummermann
3
IPv4 jest 32-bitowy. 128-bit jest przeznaczony dla IPv6, który, jak wspomniał, nie obsługuje INET_ *.
Richard,
1
Aby uzyskać adres IPv6, użyj funkcji INET6_ATON () i INET6_NTOA (), patrz przykład - rathishkumar.in/2017/08/how-to-store-ip-address-in-mysql.html
rathishDBA
6

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.

BillThor
źródło
2
Całkowicie się zgadzam, nadchodzi IPv6 i lepiej być na to przygotowanym niż czekać na niego jak Y2K: D
Jeff
Nie tylko nadchodzi, ale już tutaj na moich systemach.
BillThor,
6

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
jkj
źródło
Aby dowiedzieć się, które adresy IP znajdują się w sieci, wybierz * z testu GDZIE adres << '1.2.3.0/24'::inet;
jkj
4

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.

  1. Zużywa mniej pamięci (tylko 4 bajty)
  2. Najlepsze do sortowania i przeszukiwania zakresów adresów IP, szczególnie jeśli szukasz kraju pochodzenia użytkowników.

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.

Oko
źródło
Imponujące, +1 dla Ciebie !!! Używanie 4 bajtów bez znaku, aby pokonać manipulację ciągiem każdego dnia.
RolandoMySQLDBA
-1, adresy IP są do 128 bitów, a największy typ liczb całkowitych obsługiwany przez MySQL to 64 bity.
Hendrik Brummermann
3
nhnb, IPv6 jest 128-bitowy, ale rozmowa dotyczy IPv4, który jest 32-bitowy. Nie musisz komentować każdego komentarza / odpowiedzi, nalegając na swoją wiedzę.
Eye
Twoja odpowiedź nie wspomina, że ​​dotyczy tylko starego protokołu internetowego, podczas gdy pytanie wyraźnie wymienia IPv6 na końcu. Biorąc pod uwagę, że ostatni burmistrz (przynajmniej w moim kraju) będzie obsługiwał IPv6 przed końcem tego roku, bardzo źle jest zaprojektować strukturę bazy danych, która nie może sobie z tym poradzić.
Hendrik Brummermann
1

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.

RolandoMySQLDBA
źródło
Maksymalna długość adresu IP wynosi 45 znaków.
Hendrik Brummermann
Czy CHAR nie wypełni go spacjami?
Gajusz
0

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

RVS
źródło