Python >> Tutoriel Python >  >> Python Tag >> MySQL

Comment stocker une IP dans mySQL

Je suggérerais de regarder quel type de requêtes vous exécuterez pour décider du format que vous adopterez.

Ce n'est que si vous avez besoin d'extraire ou de comparer des octets individuels que vous devrez envisager de les diviser en champs distincts.

Sinon, stockez-le sous la forme d'un entier de 4 octets. Cela a également l'avantage de vous permettre d'utiliser le INET_ATON() intégré à MySQL et INET_NTOA() fonctions.

Performances par rapport à l'espace

Stockage :

Si vous ne supportez que les adresses IPv4, votre type de données dans MySQL peut être un UNSIGNED INT qui n'utilise que 4 octets de stockage.

Pour stocker les octets individuels, vous n'auriez besoin que d'utiliser UNSIGNED TINYINT types de données, pas SMALLINTS , ce qui utiliserait 1 octet chacun de stockage.

Les deux méthodes utiliseraient un stockage similaire avec peut-être un peu plus pour des champs séparés pour certains frais généraux.

Plus d'informations :

  • Présentation des types numériques
  • Types entiers (valeur exacte) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT

Performances :

L'utilisation d'un seul champ donnera de bien meilleures performances, il s'agit d'une seule comparaison au lieu de 4. Vous avez mentionné que vous n'exécuterez des requêtes que sur l'intégralité de l'adresse IP, il ne devrait donc pas être nécessaire de séparer les octets. Utilisation du INET_* Les fonctions de MySQL feront la conversion entre le texte et les représentations entières une fois pour la comparaison.


Un BIGINT est 8 octets en MySQL .

Pour stocker IPv4 adresses, un UNSINGED INT est suffisant, et je pense que c'est ce que vous devriez utiliser.

Je ne peux pas imaginer un scénario où 4 octets gagneraient plus de performances qu'un seul INT , et ce dernier est beaucoup plus pratique.

Notez également que si vous allez émettre des requêtes comme celle-ci :

SELECT  *
FROM    ips
WHERE   ? BETWEEN start_ip AND end_ip

, où start_ip et end_ip sont des colonnes dans votre tableau, les performances seront médiocres.

Ces requêtes permettent de savoir si un IP donné se trouve dans une plage de sous-réseaux (généralement pour l'interdire).

Pour rendre ces requêtes efficaces, vous devez stocker toute la plage sous la forme d'un LineString objet avec un SPATIAL indexez-le et interrogez comme ceci :

SELECT  *
FROM    ips
WHERE   MBRContains(?, ip_range)

Voir cette entrée dans mon blog pour plus de détails sur la façon de le faire :

  • Bannir les adresses IP

Utilisez PostgreSQL, il existe un type de données natif pour cela.

Plus sérieusement, je tomberais dans le camp "un entier 32 bits". Une adresse IP n'a de sens que lorsque les quatre octets sont considérés ensemble, il n'y a donc aucune raison de stocker les octets dans des colonnes séparées dans la base de données. Stockeriez-vous un numéro de téléphone en utilisant trois champs différents (ou plus) ?


Prochain article