web-dev-qa-db-fra.com

Stockage de l'adresse IP

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?

26
Cleankod

Ne pas stocker sous forme de chaîne. Utilisez une colonne int unsigned 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 des 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.

27
Mr Shunz

Je suggère 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
7
jkj

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 des informations selon lesquelles il y aura au plus 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.

6
BillThor

Voici la meilleure réponse faite dans l'une des listes de diffusion MySQL. Lire Meilleur type de champ 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 récupérer 192.168.10.50.

4
Eye

Depuis MySQL v5.6.3, ils ont ajouté la prise en charge de INET6_ATON Et INET6_NOTA Qui prendront en charge les adresses IPv4 et IPv6. Mais ils ne le stockent plus comme un entier. IPv6 renvoie une varbinary(16) et et IPv4 renvoie une varbinary(4).

http://dev.mysql.com/doc/refman/5.6/en/miscundry-functions.html#function_inet6-aton

2
Vizjerai

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.

1
RolandoMySQLDBA

Désolé, impossible de commenter les réponses. Il y a 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

0
rvs