Risposte:
Non archiviare come stringa. Utilizzare una int unsigned
colonna e archiviare / recuperare con INET_ATON()
e INET_NTOA()
rispettivamente. AFAIK mysql non supporta INET_ * per ipv6.
MODIFICA come da commento
L'uso della funzione integrata per convertire gli IP in / da numeri interi (e quindi la memorizzazione di tali numeri interi nel database) ha l'effetto collaterale di convalidare automaticamente tali IP. Supponi di archiviare un IP come VARCHAR (16), devi assicurarti di non archiviare IP non validi (come 999.999.999.999 come esempio) con una convalida personalizzata. Le funzioni INET_ * se ne occupano.
È probabilmente il momento di iniziare a considerare IPv6. MySQL non ha metodi per convertire gli indirizzi IPv6 in formato binario. Una stringa di quaranta caratteri gestirà tutti gli indirizzi IPv6 normali. Esiste un formato che potrebbe superare i 40 caratteri, considererei quelli che difficilmente potrebbero verificarsi.
È possibile calcolare la dimensione da allora informazioni che ci saranno al massimo 8 quattro gruppi di caratteri con 7 caratteri di separazione. Il formato anomalo sostituisce gli ultimi due gruppi con un indirizzo in formato IPv4. Senza compressione dell'indirizzo sostituisce gli ultimi 9 caratteri con un massimo di 15 caratteri.
Se si memorizzano blocchi, l'indicazione della dimensione del blocco può contenere 4 caratteri anziché i 3 caratteri richiesti per IPv4.
Dovresti assicurarti che la formattazione che ottieni sia coerente, ma tutto il software che ho visto offre formati coerenti per gli indirizzi.
Suggerirei la migrazione a PostgreSQL e l'uso di tipi di dati INET o 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
Ecco la migliore risposta fatta in una delle mailing list di MySQL. Leggi migliore FieldType per memorizzare l'indirizzo IP in corso ... .
In breve suggerisce, che io secondo, di usare INT (10) UNSIGNED.
Quindi, usando 192.168.10.50:
(192 * 2 ^ 24) + (168 * 2 ^ 16) + (10 * 2 ^ 8) + 50 = 3232238130 (risultati in 192.168.10.50)
In MySQL, puoi usare direttamente
SELECT INET_ATON('192.168.10.50');
per ottenere3232238130
.
O
192 + (168 * 2 ^ 8) + (10 * 2 ^ 16) + (50 * 2 ^ 24) = 839559360 (Indietro, risultati in 50.10.168.192)
In MySQL, è possibile utilizzare direttamente
SELECT INET_NTOA(3232238130);
per tornare192.168.10.50
indietro.
A partire da MySQL v5.6.3 hanno aggiunto il supporto INET6_ATON
e INET6_NOTA
che si occuperà degli indirizzi IPv4 e IPv6. Ma non lo memorizzano più come numero intero. IPv6 restituisce a varbinary(16)
e IPv4 restituisce a varbinary(4)
.
http://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_inet6-aton
È possibile memorizzare fino a 15 caratteri. Non utilizzare VARCHAR (15) perché è di 16 byte (il primo byte gestisce la lunghezza della stringa e quindi il recupero e l'archiviazione più lenti). Usa CHAR (15) sempre su qualcosa come un indirizzo IP.
Siamo spiacenti, non posso commentare le risposte. C'è una domanda al riguardo su StackOverflow. E sono totalmente d'accordo con la risposta selezionata: usare 2xBIGINT è probabilmente il modo migliore per ipv6 al momento.
Suggerirei di scegliere 2 * BIGINT, ma assicurati che siano UNSIGNED. Esiste una sorta di divisione naturale al limite dell'indirizzo / 64 in IPv6 (poiché a / 64 è la dimensione del blocco di rete più piccola) che si allineerebbe perfettamente con quella.
È anche possibile archiviare ipv4 su queste origini - contrassegnandone uno NULL o utilizzando il formato V4COMPAT