Que tipo de dados devo escolher para armazenar um endereço IP em um SQL Server?
Ao selecionar o tipo de dados correto, seria fácil filtrar por endereço IP?
Que tipo de dados devo escolher para armazenar um endereço IP em um SQL Server?
Ao selecionar o tipo de dados correto, seria fácil filtrar por endereço IP?
Respostas:
A forma tecnicamente correta de armazenar IPv4 é binária (4), já que é o que realmente é (não, nem mesmo um INT32 / INT (4), a forma textual numérica que todos nós conhecemos e amamos (255.255.255.255) sendo justa a conversão de exibição de seu conteúdo binário).
Se você fizer isso dessa forma, desejará que as funções sejam convertidas de e para o formato de exibição textual:
Veja como converter a forma de exibição textual em binária:
E aqui está como converter o binário de volta para a forma de exibição textual:
Aqui está uma demonstração de como usá-los:
Finalmente, ao fazer pesquisas e comparações, sempre use a forma binária se quiser poder alavancar seus índices.
ATUALIZAR:
Eu queria adicionar que uma maneira de resolver os problemas de desempenho inerentes de UDFs escalares no SQL Server, mas ainda manter a reutilização de código de uma função, é usar um iTVF (função com valor de tabela embutida). Veja como a primeira função acima (string para binário) pode ser reescrita como um iTVF:
Aqui está o exemplo:
E aqui está como você o usaria em um INSERT
fonte
Você pode usar varchar. O comprimento do IPv4 é estático, mas o do IPv6 pode ser altamente variável.
A menos que você tenha um bom motivo para armazená-lo como binário, use um tipo de string (textual).
fonte
Aqui está algum código para converter IPV4 ou IPv6 no formato varchar para binário (16) e vice-versa. Esta é a menor forma que eu poderia pensar. Ele deve indexar bem e fornecer uma maneira relativamente fácil de filtrar em sub-redes. Requer SQL Server 2005 ou posterior. Não tenho certeza se é totalmente à prova de balas. Espero que isto ajude.
fonte
fn_ConvertIpAddressToBinary
. Veja a resposta de C.Plock e a minha .Como desejo lidar com
IPv4
eIPv6
, estou usandoVARBINARY(16)
as seguintesSQL CLR
funções para converter atext
apresentação do endereço IP em bytes e vice-versa:fonte
Para pessoas que usam .NET, podem usar a classe IPAddress para analisar a string IPv4 / IPv6 e armazená-la como um
VARBINARY(16)
. Pode usar a mesma classe para converterbyte[]
em string. Se quiser converter oVARBINARY
em SQL:fonte
sys.dm_exec_connections
usa varchar (48) após o SQL Server 2005 SP1. Parece bom o suficiente para mim, especialmente se você quiser usá-lo para comparar com o seu valor.Realisticamente, você ainda não verá o IPv6 como mainstream por um tempo, então eu prefiro a rota 4 tinyint. Dito isso, estou usando varchar (48) porque tenho que usar
sys.dm_exec_connections
...De outra forma. A resposta de Mark Redman menciona uma questão anterior do
debate doSO .fonte
Obrigado RBarry. Estou montando um sistema de alocação de bloco de IP e armazenar como binário é o único caminho a percorrer.
Estou armazenando a representação CIDR (ex: 192.168.1.0/24) do bloco IP em um campo varchar e usando 2 campos calculados para manter a forma binária do início e do final do bloco. A partir daí, posso executar consultas rápidas para ver se um determinado bloco já foi alocado ou está livre para atribuir.
Modifiquei sua função para calcular o endereço IP final da seguinte forma:
fonte
Eu geralmente uso uma filtragem VARCHAR simples e antiga para um endereço IP funciona bem.
Se você quiser filtrar por intervalos de endereço IP, dividirei em quatro números inteiros.
fonte
Gosto das funções do SandRock. Mas encontrei um erro no código de dbo.fn_ConvertIpAddressToBinary . O parâmetro de entrada de @ipAddress VARCHAR (39) é muito pequeno quando você concata o @delim a ele.
Você pode aumentar para 40. Ou melhor ainda, usar uma nova variável maior e usá-la internamente. Dessa forma, você não perde o último par em grandes números.
fonte
A seguinte resposta é baseada nas respostas de M. Turnhout e Jerry Birchler a esta pergunta, mas com as seguintes melhorias:
sys.fn_varbintohexsubstring
,fn_varbintohexstr
)CONVERT()
por estilos bináriosCAST('' as xml).value('xs:hexBinary())
)CONVERT()
por estilos bináriosfn_ConvertIpAddressToBinary
(conforme apontado por C.Plock )O código foi testado no SQL Server 2014 e SQL Server 2016 (consulte os casos de teste no final)
IPAddressVarbinaryToString
Converte valores de 4 bytes em IPV4 e valores de 16 bytes em representações de string IPV6 . Observe que esta função não encurta endereços.
Casos de teste:
IPAddressStringToVarbinary
Converte representações de string IPV4 e IPV6 em valores binários de 4 bytes e 16 bytes, respectivamente. Observe que esta função é capaz de analisar a maioria (todas as comumente usadas) das representações de endereço abreviado (por exemplo, 127 ... 1 e 2001: db8 :: 1319: 370: 7348). Para forçar a função fina a sempre retornar valores binários de 16 bytes, remova o comentário da concatenação de 0s inicial no final da função.
Casos de teste
Casos válidos
Casos inválidos
fonte
Estou usando
varchar(15)
até agora tudo está funcionando para mim. Inserir, atualizar, selecionar. Acabei de iniciar um aplicativo que tem endereços IP, embora ainda não tenha feito muito trabalho de desenvolvimento.Aqui está a declaração de seleção:
fonte