it-swarm.dev

Przechowywanie adresu IP

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?

26
Cleankod

Nie przechowuj jako łańcucha. Użyj kolumny int unsigned I zapisz/pobierz za pomocą odpowiednio INET_ATON() i INET_NTOA(). Mysql AFAIK nie obsługuje INET_ * dla ipv6.

EDYCJA 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_ *.

27
Mr Shunz

Sugerowałbym 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
7
jkj

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ą praktyki.

Na tej podstawie możesz obliczyć rozmiar, informując, ż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.

6
BillThor

Oto najlepsza odpowiedź na jednej z list mailingowych MySQL. Odczyt najlepszy typ pola do przechowywania adresu 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.

4
Eye

Począwszy od MySQL v5.6.3 dodali obsługę INET6_ATON I INET6_NOTA, Które zajmą się adresami IPv4 i IPv6. Ale nie przechowują go już jako liczby całkowitej. IPv6 zwraca varbinary(16), a IPv4 zwraca varbinary(4).

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

2
Vizjerai

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.

1
RolandoMySQLDBA

Przepraszamy, nie mogę komentować odpowiedzi. Istnieje pytanie na ten temat na stosie przepływu. 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. Istnieje 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

0
rvs