Stockage de l'adresse IP

25

Je dois enregistrer l'adresse IP de tous les utilisateurs enregistrés dans la base de données. Je me demande, combien de caractères dois-je déclarer pour une telle colonne?

Dois-je également prendre en charge IPv6? Si oui, quelle est la longueur maximale de l'adresse IP?

Cleankod
la source

Réponses:

27

Ne pas stocker sous forme de chaîne. Utilisez une int unsignedcolonne et stockez / récupérez avec INET_ATON()et INET_NTOA()respectivement. AFAIK mysql ne prend pas en charge INET_ * pour ipv6.

MODIFIER selon le commentaire

L'utilisation de la fonction intégrée pour convertir les IP en / à partir d'entiers (et donc stocker ces entiers dans la base de données) a pour effet secondaire de valider automatiquement ces IP. Supposons que vous stockiez une IP en tant que VARCHAR (16), vous devez vous assurer de ne pas stocker d'IP invalides (comme 999.999.999.999 par exemple) avec une validation personnalisée. Les fonctions INET_ * s'en occupent.

M. Shunz
la source
1
-1, les adresses IP sont jusqu'à 128 bits et le plus grand type d'entier pris en charge par MySQL est 64 bits.
Hendrik Brummermann
3
IPv4 est de 32 bits. 128 bits est pour IPv6, qui, comme il l'a mentionné, ne prend pas en charge le contenu INET_ *.
Richard
1
Pour l'adresse IPv6, utilisez les fonctions INET6_ATON () et INET6_NTOA (), voir l'exemple - rathishkumar.in/2017/08/how-to-store-ip-address-in-mysql.html
rathishDBA
6

Il est probablement temps de commencer à envisager IPv6. MySQL ne dispose pas de méthodes pour convertir les adresses IPv6 au format binaire. Une chaîne de quarante caractères gérera toutes les adresses IPv6 normales. Il existe un format qui pourrait dépasser 40 caractères, je considérerais ceux peu susceptibles de se produire.

Vous pouvez calculer la taille à partir de cette information qu'il y aura au maximum 8 groupes de quatre caractères avec 7 caractères de séparation. Le format anormal remplace les deux derniers groupes par une adresse au format IPv4. Sans compression d'adresse, il remplace les 9 derniers caractères par 15 caractères maximum.

Si vous stockez des blocs, l'indication de taille de bloc peut prendre 4 caractères plutôt que les 3 caractères requis pour IPv4.

Vous devez vous assurer que la mise en forme que vous obtenez est cohérente, mais tous les logiciels que j'ai vus donnent des formats cohérents pour les adresses.

BillThor
la source
2
Je suis totalement d'accord, IPv6 arrive et il vaut mieux y être prêt que de l'attendre comme Y2K: D
Jeff
Non seulement à venir, mais déjà ici sur mes systèmes.
BillThor
6

Je suggérerais la migration vers PostgreSQL et l'utilisation de types de données INET ou 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
jkj
la source
Pour obtenir les adresses IP d'un réseau SELECT * FROM test WHERE address << '1.2.3.0/24'::inet;
jkj
4

Voici la meilleure réponse faite dans l'une des listes de diffusion MySQL. Lire Meilleur FieldType pour stocker l' adresse IP ... .

En bref, il suggère, que j'appuie, d'utiliser INT (10) UNSIGNED.

  1. Il utilise moins de mémoire (4 octets uniquement)
  2. Idéal pour trier et rechercher les plages d'adresses IP, surtout si vous recherchez le pays d'origine de vos visiteurs.

Donc, en utilisant 192.168.10.50:

(192 * 2 ^ 24) + (168 * 2 ^ 16) + (10 * 2 ^ 8) + 50 = 3232238130 (résultats en 192.168.10.50)

Dans MySQL, vous pouvez directement utiliser SELECT INET_ATON('192.168.10.50'); pour obtenir 3232238130.

Ou

192 + (168 * 2 ^ 8) + (10 * 2 ^ 16) + (50 * 2 ^ 24) = 839559360 (en arrière, résulte en 50.10.168.192)

Dans MySQL, vous pouvez directement utiliser SELECT INET_NTOA(3232238130); pour 192.168.10.50revenir.

Œil
la source
Impressionnant, +1 pour vous !!! L'utilisation de 4 octets non signés bat la manipulation des chaînes à tout moment.
RolandoMySQLDBA
-1, les adresses IP sont jusqu'à 128 bits et le plus grand type d'entier pris en charge par MySQL est 64 bits.
Hendrik Brummermann
3
nhnb, IPv6 est de 128 bits, mais la conversation porte sur IPv4 qui est de 32 bits. Pas besoin de commenter chaque commentaire / réponse en insistant sur vos connaissances.
Eye
Votre réponse ne mentionne pas qu'il ne traite que de l'ancien protocole Internet, alors que la question mentionne explicitement IPv6 à la fin. Étant donné que le dernier fournisseur Internet du maire (au moins dans mon pays) prendra en charge IPv6 avant la fin de cette année, c'est une très mauvaise idée de concevoir une structure de base de données qui ne peut pas le gérer.
Hendrik Brummermann
1

Vous pouvez stocker jusqu'à 15 caractères. Veuillez ne pas utiliser VARCHAR (15) car cela fait 16 octets (le premier octet gère la longueur de la chaîne et donc la récupération et le stockage plus lents). Utilisez CHAR (15) toujours sur quelque chose comme une adresse IP.

RolandoMySQLDBA
la source
La longueur maximale d'une adresse IP est de 45 caractères.
Hendrik Brummermann
CHAR ne le remplira-t-il pas d'espaces?
Gaius
0

Désolé, je ne peux pas commenter les réponses. Il y a une question à ce sujet sur stackoverflow. Et je suis totalement d'accord avec la réponse choisie: l'utilisation de 2xBIGINT est probablement le meilleur moyen pour ipv6 actuellement.

Je suggère d'aller pour 2 * BIGINT, mais assurez-vous qu'ils ne sont PAS SIGNÉS. Il y a une sorte de division naturelle à la limite d'adresse / 64 dans IPv6 (car a / 64 est la plus petite taille de bloc réseau) qui s'alignerait bien avec cela.

Il est également possible de stocker ipv4 sur ces bigints - soit en marquant l'un d'eux NULL soit en utilisant le format V4COMPAT

rvs
la source