Ich muss die IP-Adresse aller registrierten Benutzer in der Datenbank speichern. Ich frage mich, wie viele Zeichen ich für eine solche Spalte deklarieren soll.
Sollte ich auch IPv6 unterstützen? Wenn ja, wie lang ist die maximale Länge der IP-Adresse?
Nicht als Zeichenfolge speichern. Verwenden Sie eine Spalte int unsigned
Und speichern/rufen Sie mit INET_ATON()
bzw. INET_NTOA()
ab. AFAIK mysql unterstützt INET_ * für ipv6 nicht.
EDIT gemäß Kommentar
Die Verwendung der integrierten Funktion zum Konvertieren von IPs in/von Ganzzahlen (und das Speichern dieser Ganzzahlen in der Datenbank) hat den Nebeneffekt, dass diese IPs automatisch überprüft werden. Angenommen, Sie speichern eine IP als VARCHAR (16). Sie müssen sicherstellen, dass keine ungültigen IPs (wie z. B. 999.999.999.999) mit einer benutzerdefinierten Validierung gespeichert werden. Dafür sorgen INET_ * -Funktionen.
Ich würde die Migration zu 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
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 mit vierzig Zeichen verarbeitet alle normalen IPv6-Adressen. Es gibt ein Format, das 40 Zeichen überschreiten kann. Ich würde diese als unwahrscheinlich betrachten.
Sie können die Größe anhand der Informationen berechnen, dass es höchstens 8 vier Zeichengruppen mit 7 Trennzeichen gibt. Das abnormale Format ersetzt die letzten beiden Gruppen durch eine Adresse im IPv4-Format. Ohne Adresskomprimierung werden die letzten 9 Zeichen durch bis zu 15 Zeichen ersetzt.
Wenn Sie Blöcke speichern, kann die Blockgrößenanzeige 4 Zeichen anstelle der für IPv4 erforderlichen 3 Zeichen enthalten.
Sie sollten sicherstellen, dass die Formatierung, die Sie erhalten, konsistent ist, aber die gesamte Software, die ich gesehen habe, bietet konsistente Formate für die Adressen.
Hier ist die beste Antwort in einer der MySQL-Mailinglisten. Lesen Sie Bester Feldtyp zum Speichern der IP-Adresse ... .
Kurz schlägt es vor, INT (10) UNSIGNED zu verwenden.
Verwenden Sie also 192.168.10.50:
(192 * 2 ^ 24) + (168 * 2 ^ 16) + (10 * 2 ^ 8) + 50 = 3232238130 (Ergebnisse in 192.168.10.50)
In MySQL können Sie direkt
SELECT INET_ATON('192.168.10.50');
verwenden, um3232238130
Zu erhalten.
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
SELECT INET_NTOA(3232238130);
direkt verwenden, um192.168.10.50
Zurückzubekommen.
Ab MySQL v5.6.3 wurde die Unterstützung für INET6_ATON
Und INET6_NOTA
Hinzugefügt, die sich um IPv4- und IPv6-Adressen kümmern. Sie speichern es jedoch nicht mehr als Ganzzahl. IPv6 gibt ein varbinary(16)
und IPv4 ein varbinary(4)
zurück.
http://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_inet6-aton
Sie können bis zu 15 Zeichen speichern. Verwenden Sie VARCHAR (15) nicht, da dies 16 Byte sind (das erste Byte verwaltet die Zeichenfolgenlänge 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 ein Frage daz zum Stapelüberlauf. Und ich stimme der ausgewählten Antwort voll und ganz 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. Es gibt eine Art natürliche Aufteilung an der/64-Adressgrenze in IPv6 (da a/64 die kleinste Netzblockgröße ist), die gut dazu passt.
Es ist auch möglich, ipv4 auf diesen Bigints zu speichern - entweder indem Sie eines davon als NULL markieren oder indem Sie das V4COMPAT-Format verwenden