Pergunta

Estou trabalhando no esquema de refatoração de banco de dados (SQL Server 2008) e reunindo argumentos para alterar NCHAR(1) colunas (que mantêm Y|N valores) para BIT.Todos entendem que isso é necessário e não sabem por que isso acontece, mas essa mudança afeta o banco de dados de produção, portanto são necessários argumentos de peso.Tabela mantém catálogo de endereços (até 1m de registros).

Primeiro argumento que encontrei - cada campos nchar pegue 2 bytes, cada 8 campos de bits - 1 byte (próximos 8 - 1 byte adicional).

Qual é o próximo?Talvez alguns problemas de desempenho de índices?

Foi útil?

Solução

Um campo de bits ajuda sua lógica ao impor automaticamente o que atualmente é uma regra de negócios implícita (ou seja, esta coluna só pode conter 'Y' ou 'N').Se você estiver aplicando essa regra programaticamente, poderá economizar eliminando essa sobrecarga.Indexar uma coluna de bits por si só tem pouco valor devido à baixa cardinalidade, mas pode ser útil como parte de um índice composto.

Veja também:

Outras dicas

Eu hesitaria em fornecer quaisquer argumentos para tal mudança, a menos que você tivesse um bom motivo para fazer essa mudança.ou sejavocê precisa equilibrar o custo de uma mudança com o que você pessoalmente faria/preferiria, versus o custo de realmente implementá-la e os benefícios.

Você verificou se o uso de nchar(1) está prejudicando o desempenho ou está caindo na armadilha da otimização prematura?Você está falando apenas de 1 milhão de registros aqui.

Para o menor custo de armazenamento/E/S que você acha que está incorrendo, considere o total de horas de trabalho para alterar, testar novamente e atualizar o sistema * taxa horária versus custo de apenas comprar um disco mais rápido.Suspeito que o disco será muito mais barato - além de beneficiar todos os aspectos do sistema.

Um motivo comum para encontrar NCHAR(1) em vez de bit é que o Oracle não suportava um tipo de bit.Se você tivesse um desenvolvedor Oracle ou treinado em Oracle, ou um banco de dados que costumava rodar em Oracle, você verá muito isso.No SQL Server, realmente não há necessidade disso.

No entanto, descobri que na maioria dos lugares onde tenho um campo de bits (ou NCHAR(1) no Oracle) o que eu realmente Want é uma data e hora que indica não tanto o valor do sinalizador, mas exatamente quando ele se tornou verdadeiro.Nem sempre é esse o caso, mas quando penso no código antigo que escrevi, acho que 4 em cada 5 vezes que usei um campo de bits, deveria ter usado uma data e hora.

Crie o campo de bits, adicione uma coluna computada que emule o nchar(1) por enquanto.

O que não usar nchar:

  • Y contra y contra alguns unicode Y
  • Despesas gerais de verificação de Y ou N
  • Não é nativamente "true" ou "false" (por exemplo, não mapeia diretamente para .net booleano)
  • Y e N são ingleses.Ja/Nein, Oui/Não etc.

Você não deve indexar isso de qualquer maneira, portanto, tudo se resume a armazenamento e uso eficientes.Pouco é

  • menor
  • tipo de dados seguro (por exemplo, não é necessário CHECK)
  • mapeia diretamente para o significado do cliente
  • independente da região

Dizendo isso, usamos um campo smalldatetime "WhenInactive" como substituto do campo "IsActive".NULO = ativo.

Se você estiver usando LINQ2SQL ou Entity Framework, um BIT coluna se traduzirá em um bool, mas NCHAR(1) se traduzirá em um string.

O campo é amplamente utilizado em consultas Where fld = 'Y'?

Nesse caso, consideraria fazer um teste para ver se alterá-lo para pouco afeta ou não o desempenho.

Mudá-lo agora só porque deveria ser um campo de bits, já que você está armazenando valores booleanos em uma tabela de mais de 1 milhão de registros também não parece uma boa ideia para mim e eu usaria a resposta de @Andrew.

Usar bit:

  • Representação lógica/expressividade da intenção - uma vez que os estados booleanos nem sempre podem ser expressos de forma consistente como Yes or No, o que significaria que você precisaria ser inconsistente na modelagem de bits ou não intuitivo, por exemplo. True/False (T/F), On/Off (?O/F), Open/Closed(O/C) etc.

  • Integridade referencial - o bit não anulável pode ser restrito apenas a 0 or 1.A menos que você adicione restrições, seu *char(1) poderia ser Y,N, X ou .

  • Os bits podem ser embalados, então poderia ter armazenamento menor.

  • Ré:Desempenho :A indexação de colunas de bits (ou CHAR de poucos estados) geralmente é um desperdício, a menos que haja alta seletividade de 0 ou 1 nos dados.Neste caso, um índice filtrado no valor seletivo seria uma boa ideia.

(Migrado de resposta excluída aqui)

Tive algumas ocasiões em que queríamos um campo de bits, mas não tínhamos certeza de que nunca haveria necessidade de um terceiro ou quarto valor nesse campo.Portanto, o estruturamos como um campo de string contendo Y ou N.É claro que só fizemos isso em situações muito singulares.

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