¿Qué tipo de datos debo elegir para almacenar una dirección IP en un servidor SQL?
Al seleccionar el tipo de datos correcto, ¿sería bastante fácil filtrar por dirección IP entonces?
¿Qué tipo de datos debo elegir para almacenar una dirección IP en un servidor SQL?
Al seleccionar el tipo de datos correcto, ¿sería bastante fácil filtrar por dirección IP entonces?
Respuestas:
La forma técnicamente correcta de almacenar IPv4 es binaria (4), ya que eso es lo que realmente es (no, ni siquiera INT32 / INT (4), la forma textual numérica que todos conocemos y amamos (255.255.255.255) es simplemente la conversión de visualización de su contenido binario).
Si lo hace de esta manera, querrá que las funciones se conviertan hacia y desde el formato de visualización textual:
A continuación, se explica cómo convertir la forma de visualización textual en binario:
Y aquí se explica cómo convertir el binario nuevamente al formato de visualización textual:
Aquí hay una demostración de cómo usarlos:
Por último, cuando realice búsquedas y comparaciones, utilice siempre la forma binaria si desea poder aprovechar sus índices.
ACTUALIZAR:
Quería agregar esa forma de abordar los problemas de rendimiento inherentes de las UDF escalares en SQL Server, pero aún así conservar el código: la reutilización de una función es usar una iTVF (función con valores de tabla en línea) en su lugar. Así es como la primera función anterior (cadena a binario) se puede reescribir como un iTVF:
Aquí está en el ejemplo:
Y así es como lo usaría en un INSERT
fuente
Puede usar varchar. La longitud de IPv4 es estática, pero la de IPv6 puede ser muy variable.
A menos que tenga una buena razón para almacenarlo como binario, quédese con un tipo de cadena (textual).
fuente
Aquí hay un código para convertir IPV4 o IPv6 en formato varchar a binario (16) y viceversa. Esta es la forma más pequeña que se me ocurre. Debería indexar bien y proporcionar una forma relativamente fácil de filtrar en subredes. Requiere SQL Server 2005 o posterior. No estoy seguro de que sea totalmente a prueba de balas. Espero que esto ayude.
fuente
fn_ConvertIpAddressToBinary
. Vea la respuesta de C.Plock y la mía .Como quiero manejar ambos
IPv4
yIPv6
, estoy usandoVARBINARY(16)
y las siguientesSQL CLR
funciones para convertir latext
presentación de la dirección IP a bytes y al revés:fuente
Las personas que usan .NET pueden usar la clase IPAddress para analizar la cadena IPv4 / IPv6 y almacenarla como
VARBINARY(16)
. Puede usar la misma clase para convertirbyte[]
a cadena. Si desea convertir elVARBINARY
en SQL:fuente
sys.dm_exec_connections
usa varchar (48) después de SQL Server 2005 SP1. Suena bastante bien para mí, especialmente si quieres usarlo en comparación con tu valor.Siendo realistas, todavía no verá IPv6 como la corriente principal por un tiempo, por lo que prefiero la ruta 4 tinyint. Dicho esto, estoy usando varchar (48) porque tengo que usar
sys.dm_exec_connections
...De otra manera. La respuesta de Mark Redman menciona una pregunta de
debate deSO anterior .fuente
Gracias RBarry. Estoy armando un sistema de asignación de bloques de IP y almacenar como binario es el único camino a seguir.
Estoy almacenando la representación CIDR (por ejemplo, 192.168.1.0/24) del bloque de IP en un campo varchar, y estoy usando 2 campos calculados para contener la forma binaria del inicio y el final del bloque. A partir de ahí, puedo ejecutar consultas rápidas para ver si un bloque dado ya ha sido asignado o es libre de asignar.
Modifiqué su función para calcular la dirección IP final así:
fuente
Por lo general, uso un filtro VARCHAR simple y simple para una dirección IP que funciona bien.
Si desea filtrar por rangos de direcciones IP, lo dividiría en cuatro números enteros.
fuente
Me gustan las funciones de SandRock. Pero encontré un error en el código de dbo.fn_ConvertIpAddressToBinary . El parámetro entrante de @ipAddress VARCHAR (39) es demasiado pequeño cuando le concatena el @delim.
Puede aumentarlo a 40. O mejor aún, use una nueva variable que sea más grande y úsela internamente. De esa manera no perderá el último par en números grandes.
fuente
La siguiente respuesta se basa en las respuestas de M. Turnhout y Jerry Birchler a esta pregunta, pero con las siguientes mejoras:
sys.fn_varbintohexsubstring
,fn_varbintohexstr
) conCONVERT()
por estilos binariosCAST('' as xml).value('xs:hexBinary())
) conCONVERT()
por estilos binariosfn_ConvertIpAddressToBinary
(como lo señaló C.Plock )El código se ha probado en SQL Server 2014 y SQL Server 2016 (consulte los casos de prueba al final)
IPAddressVarbinaryToString
Convierte valores de 4 bytes en IPV4 y valores de 16 bytes en representaciones de cadenas IPV6 . Tenga en cuenta que esta función no acorta las direcciones.
Casos de prueba:
IPAddressStringToVarbinary
Convierte representaciones de cadenas de IPV4 e IPV6 en valores binarios de 4 bytes y 16 bytes respectivamente. Tenga en cuenta que esta función puede analizar la mayoría (todas las de uso común) de las representaciones de direcciones abreviadas (por ejemplo, 127 ... 1 y 2001: db8 :: 1319: 370: 7348). Para forzar que la función Thins siempre devuelva valores binarios de 16 bytes, elimine el comentario de la concatenación de ceros iniciales al final de la función.
Casos de prueba
Casos válidos
Casos inválidos
fuente
Estoy usando
varchar(15)
hasta ahora todo está funcionando para mí. Insertar, actualizar, seleccionar. Acabo de iniciar una aplicación que tiene direcciones IP, aunque todavía no he hecho mucho trabajo de desarrollo.Aquí está la declaración de selección:
fuente