Comment stocker une adresse compatible IPv6 dans une base de données relationnelle

StackOverflow https://stackoverflow.com/questions/420680

  •  05-07-2019
  •  | 
  •  

Question

Comment je fais ça?

Pour l'instant, IPv6 ne sera pas utilisé, mais je dois concevoir l'application pour la rendre compatible IPv6. Il est nécessaire de stocker les adresses IP et les blocs CIDR (également BGP NLRI, mais ceci est une autre histoire) dans une base de données MySQL. J'ai toujours utilisé un INT pour IPv4 + un TINYINT pour masklen, mais IPv6 est de 128 bits.

Quelle approche sera la meilleure pour cela? 2xBIGINT ? CHAR (16) pour le stockage binaire? CHAR (39) pour le stockage de texte? 8xSMALLINT dans une table dédiée?

Que recommanderiez-vous?

Était-ce utile?

La solution

Je ne sais pas quelle est la bonne réponse pour MySQL, car il ne prend pas encore en charge les formats d’adresse IPv6 de manière native (bien que " WL n ° 798: prise en charge de MySQL IPv6 , ce qui laisse supposer que cela se ferait dans MySQL v6.0, la documentation actuelle ne le fait pas. ne recule pas ça).

Cependant, parmi ceux que vous avez proposés, je vous suggère d’opter pour 2 * BIGINT, mais assurez-vous qu’ils ne sont pas signés. Dans IPv6, il existe une sorte de séparation naturelle à la limite d’adresse / 64 dans IPv6 (puisque a / 64 est la plus petite taille de bloc réseau) qui s’alignerait parfaitement avec cela.

Autres conseils

Notez que la longueur maximale d'une adresse IPv6, identificateur de portée comprise, est de 46 octets, telle que définie par INET6_ADDRSTRLEN dans les en-têtes C standard. Pour utiliser Internet, vous devriez pouvoir ignorer l’ identificateur de zone (% 10, # eth0, etc), mais sachez que getaddrinfo renvoie un résultat plus long que prévu.

Si vous penchez vers le caractère (16), utilisez plutôt binaire (16). binary (n) n'a pas de concept de collation ou de jeu de caractères (ou plutôt, c'est un caractère (n) avec un jeu de caractères / collation de 'binary'). Le caractère par défaut de char dans mysql est latin1_swedish_ci, ce qui signifie qu'il tentera un tri et des comparaisons sans distinction de casse pour les valeurs d'octet qui sont des points de code valides dans latin1, ce qui vous causera toutes sortes de problèmes inattendus.

Une autre option consiste à utiliser decimal (39, 0) zerofill unsigned, pas tout à fait aussi efficace que deux bigints (decimal utilisera 4 octets par neuf chiffres dans les versions actuelles de mysql), mais vous permettra de tout conserver en un. colonne et imprimez bien.

Je choisirais les 39 caractères " standard " format imprimé: -

"2001:0db8:85a3:0000:0000:8a2e:0370:7334"

40 avec un terminateur nul.

Il s'agit du format utilisé par les outils de ligne de commande * nix et le format dans lequel une adresse IPV6 est normaly (?) est indiqué dans.

L'adresse IP va-t-elle être utilisée par un programme pour lequel le binaire a du sens? Ou seriez-vous mieux de stocker une représentation textuelle? De plus, avec IPv6, vous êtes moins susceptible d’utiliser l’adresse en général et plus probablement d’utiliser des noms d’hôte. Que cela soit pertinent ou non dépend de l'application, en partie. CHAR (16) serait un mauvais choix. char est pour les données de caractères et n'aimera pas les gros flux de zéro octet qui prévalent dans les adresses IPv6. 2 x BIGINT serait inconfortable - deux champs qui sont vraiment un (plus est la valeur stockée big-endian ou little-endian?). J'avais utilisé un type BINARY de taille fixe ou, si ce n'est pas disponible, un type de blob.

Je travaille avec un projet de correspondance du préfixe le plus long. Je divise donc l'adresse en 4 entiers pour les adresses IPv4. Ça marche bien. J'étendrais cela aux adresses IPv6.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top