Quel type de données dois-je choisir pour stocker une adresse IP dans un serveur SQL?
En sélectionnant le bon type de données, serait-il assez facile de filtrer par adresse IP alors?
sql-server
tsql
sql-server-2005
types
ip-address
Ou sinon
la source
la source
Réponses:
Le moyen techniquement correct de stocker IPv4 est binaire (4), puisque c'est ce qu'il est réellement (non, même pas un INT32 / INT (4), la forme textuelle numérique que nous connaissons et aimons tous (255.255.255.255) étant juste la conversion d'affichage de son contenu binaire).
Si vous procédez de cette façon, vous souhaiterez que les fonctions soient converties vers et à partir du format d'affichage textuel:
Voici comment convertir le formulaire d'affichage textuel en binaire:
Et voici comment reconvertir le binaire au format d'affichage textuel:
Voici une démonstration de leur utilisation:
Enfin, lorsque vous effectuez des recherches et des comparaisons, utilisez toujours la forme binaire si vous souhaitez pouvoir exploiter vos index.
METTRE À JOUR:
Je voulais ajouter qu'une façon de résoudre les problèmes de performances inhérents aux UDF scalaires dans SQL Server, tout en conservant la réutilisation du code d'une fonction, consiste à utiliser à la place un iTVF (fonction table en ligne). Voici comment la première fonction ci-dessus (chaîne en binaire) peut être réécrite en iTVF:
Voici dans l'exemple:
Et voici comment vous l'utiliseriez dans un INSERT
la source
Vous pouvez utiliser varchar. La longueur d'IPv4 est statique, mais celle d'IPv6 peut être très variable.
Sauf si vous avez une bonne raison de le stocker en tant que binaire, tenez-vous-en à un type de chaîne (textuel).
la source
Voici un code pour convertir IPV4 ou IPv6 au format varchar en binaire (16) et inversement. C'est la plus petite forme à laquelle je puisse penser. Il devrait bien indexer et fournir un moyen relativement simple de filtrer sur les sous-réseaux. Nécessite SQL Server 2005 ou version ultérieure. Pas sûr que ce soit totalement à l'épreuve des balles. J'espère que cela t'aides.
la source
fn_ConvertIpAddressToBinary
. Voir la réponse de C.Plock et la mienne .Comme je veux gérer à la fois
IPv4
etIPv6
, j'utiliseVARBINARY(16)
et lesSQL CLR
fonctions suivantes pour convertir latext
présentation de l'adresse IP en octets et inversement:la source
Les personnes utilisant .NET peuvent utiliser la classe IPAddress pour analyser la chaîne IPv4 / IPv6 et la stocker en tant que fichier
VARBINARY(16)
. Peut utiliser la même classe pour convertirbyte[]
en chaîne. Si vous voulez convertir leVARBINARY
en SQL:la source
sys.dm_exec_connections
utilise varchar (48) après SQL Server 2005 SP1. Cela me semble assez bien, surtout si vous voulez l'utiliser par rapport à votre valeur.En réalité, vous ne verrez pas encore IPv6 comme un courant dominant, alors je préférerais la route 4 tinyint. En disant cela, j'utilise varchar (48) car je dois utiliser
sys.dm_exec_connections
...Autrement. La réponse de Mark Redman mentionne une précédente question de
débat sur l'OS .la source
Merci RBarry. Je mets en place un système d'allocation de bloc IP et le stockage en tant que binaire est la seule voie à suivre.
Je stocke la représentation CIDR (ex: 192.168.1.0/24) du bloc IP dans un champ varchar et j'utilise 2 champs calculés pour contenir la forme binaire du début et de la fin du bloc. À partir de là, je peux exécuter des requêtes rapides pour voir si un bloc donné a déjà été alloué ou s'il est libre de l'attribuer.
J'ai modifié votre fonction pour calculer l'adresse IP de fin comme ceci:
la source
J'utilise généralement un ancien filtrage VARCHAR pour une adresse IP fonctionne très bien.
Si vous voulez filtrer sur des plages d'adresses IP, je le diviserais en quatre entiers.
la source
J'aime les fonctions de SandRock. Mais j'ai trouvé une erreur dans le code de dbo.fn_ConvertIpAddressToBinary . Le paramètre entrant de @ipAddress VARCHAR (39) est trop petit lorsque vous y concattez @delim.
Vous pouvez l'augmenter à 40. Ou mieux encore, utilisez une nouvelle variable plus grande et utilisez-la en interne. De cette façon, vous ne perdez pas la dernière paire sur de grands nombres.
la source
La réponse suivante est basée sur les réponses de M. Turnhout et Jerry Birchler à cette question, mais avec les améliorations suivantes:
sys.fn_varbintohexsubstring
,fn_varbintohexstr
) parCONVERT()
des styles binairesCAST('' as xml).value('xs:hexBinary())
) parCONVERT()
des styles binairesfn_ConvertIpAddressToBinary
(comme indiqué par C.Plock )Le code a été testé dans SQL Server 2014 et SQL Server 2016 (voir les cas de test à la fin)
IPAddressVarbinaryToString
Convertit les valeurs de 4 octets en IPV4 et les valeurs de 16 octets en représentations de chaîne IPV6 . Notez que cette fonction ne raccourcit pas les adresses.
Cas de test:
IPAddressStringToVarbinary
Convertit les représentations de chaîne IPV4 et IPV6 en valeurs binaires de 4 octets et 16 octets respectivement. Notez que cette fonction est capable d'analyser la plupart des représentations d'adresses abrégées (par exemple, 127 ... 1 et 2001: db8 :: 1319: 370: 7348) (toutes celles couramment utilisées). Pour forcer la fonction thins à toujours renvoyer des valeurs binaires de 16 octets, décommentez la concaténation de 0 à la fin de la fonction.
Cas de test
Cas valides
Cas invalides
la source
J'utilise
varchar(15)
jusqu'ici tout fonctionne pour moi. Insérer, mettre à jour, sélectionner. Je viens de démarrer une application avec des adresses IP, même si je n'ai pas encore fait beaucoup de travail de développement.Voici l'instruction select:
la source