Qual é o tipo de dados apropriado mais para armazenar um endereço IP no servidor SQL? [duplicado]

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

Pergunta

Esta questão já tem uma resposta aqui:

Qual deve ser o tipo de dados mais recomendado para armazenar um endereço IPv4 no servidor SQL?

Ou talvez alguém já criou um usuário SQL tipo de dados (Net montagem) para ele?

Eu não preciso de classificação.

Foi útil?

Solução

Armazenando um endereço IPv4 como um binary (4) é verdadeira ao que ele representa, e permite a fácil consulta de sub-rede de estilo máscara. No entanto, ele requer a conversão dentro e para fora se você está realmente depois de uma representação de texto. Nesse caso, você pode preferir um formato de string.

A função utilizada-little SQL Server que pode ajudar se você estiver armazenando como uma string é PARSENAME , pelo caminho. Não projetado para endereços IP, mas perfeitamente adequado para eles. A chamada abaixo retornará '14':

SELECT PARSENAME('123.234.23.14', 1)

(numeração é direita para a esquerda).

Outras dicas

Eu normalmente só usar varchar (15) para endereços IPv4 -. Mas classificá-los é uma dor a menos que você zeros almofada

Eu também armazenados-los como um INT no passado. System.Net.IPAddress tem um GetAddressBytes método que irá retornar o endereço IP como uma matriz dos 4 bytes que representam o endereço IP. Você pode usar o seguinte código C # para converter um IPAddress a um int ...

var ipAsInt = BitConverter.ToInt32(ip.GetAddressBytes(), 0);

Eu tinha usado isso porque eu tinha que fazer um monte de procura de endereços dupe, e queria que os índices para ser tão pequeno e rápido quanto possível. Em seguida, para puxar a volta endereço fora do int e em um IPAddress objeto no .NET, use o GetBytes método em BitConverter para obter o int como uma matriz de bytes. Passar essa matriz de bytes para o construtor para IPAddress que leva uma matriz de bytes, e você acaba de volta com o IPAddress que você começou com.

var myIp = new IPAddress(BitConverter.GetBytes(ipAsInt));

Em relação a este comentário em resposta aceite

classificá-los é uma dor a menos que você pad zeros.

Aqui está um truque para SQL Server 2008 (De Itzik Ben-Gan em este livro )

with ip_addresses as
(
SELECT '131.33.2.201' AS ip_address UNION ALL
SELECT '2.12.4.4' AS ip_address UNION ALL
SELECT '131.33.2.202' AS ip_address UNION ALL
SELECT '2.12.4.169' AS ip_address UNION ALL
SELECT '131.107.2.201' AS ip_address 
)
select ip_address
from ip_addresses
ORDER  BY CAST('/' + ip_address + '/' AS hierarchyid)

Retorna

ip_address
-------------
2.12.4.4
2.12.4.169
131.33.2.201
131.33.2.202
131.107.2.201

Uma das minhas favoritas artigos fala sobre por que você não deve usar expressões regulares para analisar os endereços IP. A maioria do que eles estão falando é realmente explicando por que você deve ter muito cuidado com as representações textuais de endereços IP. Eu sugiro que você lê-lo antes de decidir o tipo de dados para usar em seu banco de dados, e provavelmente também por qualquer manipulação seu aplicativo estará fazendo (mesmo que o artigo foi escrito sobre Perl, é útil para qualquer idioma).

Eu acho que, no final, um tipo de dados de 32 bits (ou quatro tipos de dados de 8 bits) seria a melhor escolha.

IPV4? int? ou tinyint x 4?

Ela realmente depende se é apenas armazenamento e recuperação ou se vai ser um critério de pesquisa à distância.

Não se esqueça de IPv6 - você precisa de muito mais espaço se você precisa armazená-los -. 128bits compara a IPv4 de 32

Eu iria para bigint, mas você vai precisar de algum código auxiliar para traduzir a versões amigáveis ??humanos.

Estou lendo um monte de perguntas semelhantes sobre aqui, e nenhuma das respostas em um presente mencionar o número de uma resposta nos outros: "Para os endereços IPv4, você pode querer armazená-los como um unsigned int e usar o INET_ATON () e inet_ntoa () para devolver o endereço IP do seu valor numérico, e vice-versa." Eu acho que isso é o que eu estou indo para ir com a minha db, a menos que eu decidir usar o php funções mencionadas acima.

A melhor maneira (quando não há necessidade triagem e outro controle sobre os IPs) é armazená-lo como int , armazenando-o como varchar etc. custaria muito mais desempenho do que apenas um int inocente simples.

Há uma propriedade IPAddress.Address mas é obsoleto, não sei por que, pois, se você não precisa de triagem ou controle sobre as classes IP, a melhor maneira é armazená-lo como inteiro sem sinal (que tem um valor máximo de 0xffffffff o que equivale a 255.255.255.255 em decimal representação.

Além disso, a classe IPAddress tem um construtor que aceita uma longa discussão.

E de acordo com VS depurador visualizador, que IPAddress própria classe armazena sua variável interna como um número (não array de bytes).

Leia mais em soluções de armazenamento uma unidade em MS SQL Server:

Para espaço de armazenamento eficiente e, quando os valores são para ser processado (correspondente ou em comparação com uma gama), que usa um int. O endereço IP é realmente apenas um valor de 32 bits.

Para uma solução simples, onde você só quer armazenar o valor para vê-lo, eu uso um varchar(15) para armazenar a representação de string do endereço IP.

Eu tive algum sucesso com fazer quatro smallint (ou qualquer pequeno número inteiro tipo de dados você preferir) colunas - uma para cada octeto. Então, você pode fazer um ponto de vista que lhes esmaga juntos como uma string char (para exibição) ou então você pode escrever operadores simples para determinar quem tudo está no que sub-rede etc.

É bastante rápido (desde que você faça a indexação adequada) e também permite muito fácil consulta (sem a manipulação de cadeia!).

Uma vez que um endereço IP tem 32 bits nele, você pode simplesmente usar um LONGO para armazenar o valor numérico?
Não seria como o espaço-desperdício como o uso de VARCHAR, mas então você teria que decodificá-lo de volta a um IP antes de usá-lo, cada vez, e o atraso ea sobrecarga que os custos podem não valer a pena.

O tipo de dados mais adequado para armazenar um endereço IPv4 em um banco de dados MSSQL, é um int. A única fiddly bits é convertê-lo de volta para a notação para exibição / classificação, portanto, eu recomendo que você criar uma exibição que automatiza esse para você.

Eu provavelmente ir com um varchar ou char.

E definir o tamanho para 15.

Citando este :

endereços loja IP em um CHAR (15) da coluna. Dependendo da quantidade de dados que você está armazenando, isso pode ser bastante dispendioso (por que precisamos para armazenar os pontos?). I

Estou novato @ php, sql, mas eu acho maneira mais rápida para armazenar algo em db sql é convertê-lo para o valor int e salvar como int.

Eu usei função em php -

function ip_convert() {
    $ip = $_SERVER['REMOTE_ADDR'];
    $intip = str_replace(".","0",$ip);
    return $intip;
}

E então eu apenas substituir todos os pontos com zeros. Então, se eu preciso usar esse ip de sql .. if ($ ip == ip_convert ())

Mas isso somente se você usar o PHP.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top