Antworten:
Nicht als String speichern. Verwenden Sie eine int unsigned
Spalte und speichern bzw. laden Sie sie mit INET_ATON()
und INET_NTOA()
ab. AFAIK mysql unterstützt INET_ * für ipv6 nicht.
BEARBEITEN gemäß Kommentar
Die Verwendung der integrierten Funktion zum Konvertieren von IP-Adressen in / von Ganzzahlen (und das Speichern dieser Ganzzahlen in der Datenbank) hat den Nebeneffekt, dass diese IP-Adressen automatisch validiert werden. Angenommen, Sie speichern eine IP als VARCHAR (16), müssen Sie sicherstellen, dass Sie keine ungültigen IPs (wie 999.999.999.999 als Beispiel) mit einer benutzerdefinierten Validierung speichern. Dafür sorgen INET_ * -Funktionen.
Es ist wahrscheinlich an der Zeit, über IPv6 nachzudenken. MySQL verfügt nicht über Methoden zum Konvertieren von IPv6-Adressen in das Binärformat. Eine Zeichenfolge von vierzig Zeichen verarbeitet alle normalen IPv6-Adressen. Es gibt ein Format, das 40 Zeichen überschreiten könnte, ich würde davon ausgehen, dass diese in der Praxis kaum vorkommen.
Sie können die Größe aus dieser Information berechnen, dass es höchstens 8 vier Zeichengruppen mit 7 Trennzeichen geben wird. Das abnormale Format ersetzt die letzten beiden Gruppen durch eine IPv4-Formatadresse. Ohne Adressenkomprimierung werden die letzten 9 Zeichen durch bis zu 15 Zeichen ersetzt.
Wenn Sie Blöcke speichern, kann die Blockgrößenangabe 4 Zeichen anstelle der für IPv4 erforderlichen 3 Zeichen umfassen.
Sie sollten sicherstellen, dass die Formatierung, die Sie erhalten, konsistent ist, aber die gesamte Software, die ich gesehen habe, gibt konsistente Formate für die Adressen an.
Ich würde die Migration nach PostgreSQL und die Verwendung von INET- oder CIDR- Datentypen vorschlagen .
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
Hier ist die beste Antwort aus einer der MySQL-Mailinglisten. Lesen Bester Feldtyp speichern IP - Adresse ... .
In Kürze wird vorgeschlagen, INT (10) UNSIGNED zu verwenden.
Also mit 192.168.10.50:
(192 * 2 ^ 24) + (168 * 2 ^ 16) + (10 * 2 ^ 8) + 50 = 3232238130 (ergibt 192.168.10.50)
In MySQL können Sie direkt verwenden
SELECT INET_ATON('192.168.10.50');
, um zu erhalten3232238130
.
Oder
192 + (168 * 2 ^ 8) + (10 * 2 ^ 16) + (50 * 2 ^ 24) = 839559360 (rückwärts, ergibt 50.10.168.192)
In MySQL können Sie direkt verwenden
SELECT INET_NTOA(3232238130);
, um192.168.10.50
zurück zu gelangen .
Ab MySQL v5.6.3 fügten sie Unterstützung INET6_ATON
und INET6_NOTA
das wird von IPv4 und IPv6 - Adressen kümmern. Aber sie speichern es nicht länger als ganze Zahl. IPv6 gibt a varbinary(16)
und IPv4 gibt a zurück varbinary(4)
.
http://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_inet6-aton
Sie können bis zu 15 Zeichen speichern. Bitte verwenden Sie nicht VARCHAR (15), da dies 16 Byte sind (das erste Byte verwaltet die Länge der Zeichenfolge und damit das Abrufen und Speichern langsamer). Verwenden Sie CHAR (15) immer für eine IP-Adresse.
Antworten können leider nicht kommentiert werden. Es gibt eine Frage zum Stackoverflow. Und ich stimme der ausgewählten Antwort vollkommen zu: Die Verwendung von 2xBIGINT ist derzeit wahrscheinlich der beste Weg für ipv6.
Ich würde vorschlagen, 2 * BIGINT zu wählen, aber stellen Sie sicher, dass sie UNSIGNIERT sind. In IPv6 gibt es eine Art natürliche Aufteilung an der / 64-Adressgrenze (da a / 64 die kleinste Netzblockgröße ist), die sich gut darauf abstimmen würde.
Es ist auch möglich, ipv4 auf diesen Bigints zu speichern - entweder indem einer von ihnen als NULL markiert wird oder indem das V4COMPAT-Format verwendet wird