it-swarm.com.de

IP-Adresse speichern

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?

26
Cleankod

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.

27
Mr Shunz

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
7
jkj

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.

6
BillThor

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.

  1. Es benötigt weniger Speicher (nur 4 Bytes)
  2. Am besten zum Sortieren und Durchsuchen der IP-Bereiche, insbesondere wenn Sie nach dem Herkunftsland Ihrer Besucher suchen.

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, um 3232238130 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, um 192.168.10.50 Zurückzubekommen.

4
Eye

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

2
Vizjerai

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.

1
RolandoMySQLDBA

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

0
rvs