INT ou CHAR para um campo de tipo

19

Qual é o melhor design para uma tabela, um Typecampo que é intou char(1)? Em outras palavras, dado este esquema:

create table Car
(
    Name varchar(100) not null,
    Description varchar(100) not null,
    VehType .... not null
)

É mais eficiente (em termos de desempenho) VehTypeser um intou um char(1)? Digamos que você tenha cinco tipos de carros, use os valores incrementais de 0 a 4 ou caracteres para os tipos (digamos; 'v', 's', 'c', 't', 'm')?

Se for mais do que isso, eu usaria uma tabela Type separada e ter um relacionamento de chave estrangeira, mas não vejo a necessidade disso.

Percebo que a sys.objectsexibição do catálogo usa um caractere para o typecampo. Existe uma razão para isso? Estou apenas agarrando o nada aqui e é com o que me sinto mais confortável?

Thomas Stringer
fonte

Respostas:

20

Você normalmente usaria tinyint, que também tem 1 byte

  • char (1) será um pouco mais lento porque comparar comparações de usos

  • confusão: o que é S: SUV ou Saloon ou Sedan ou Sports?

  • o uso de uma letra o limita à medida que você adiciona mais tipos. Veja o último ponto.

  • todo sistema que eu vi tem mais de um cliente, por exemplo, relatórios. A lógica de transformar V, S em "Van", "SUV" etc precisará ser repetida. Usar uma tabela de pesquisa significa que é um JOIN simples

  • extensibilidade: adicione mais um tipo ("F" para " Carro voador "), você pode fazer uma linha em uma tabela de pesquisa ou alterar muitos códigos e restrições. E o código do seu cliente também, porque isso precisa saber o que V, S, F etc são

  • manutenção: a lógica está em 3 locais: restrição de banco de dados, código do banco de dados e código do cliente. Com uma pesquisa e uma chave estrangeira, ele pode estar em um só lugar

No lado positivo de usar uma única letra ... er, não vejo nenhuma

Nota: existe uma pergunta relacionada ao MySQL sobre Enums . A recomendação é usar uma tabela de pesquisa também.

gbn
fonte
2
ótimos pontos. Isso me faz pensar por que outras pessoas usam char (1) (como sys.objects).
Thomas Stringer
2
O sys.objects possui um legado que remonta ao Sybase e às versões anteriores do SQL Server en.wikipedia.org/wiki/Microsoft_SQL_Server#Genesis Se você olhar os objetos do sistema, poderá ver códigos, não IDs por todo o lado, mas menos nos novos DMVs. Quanto a outras pessoas, exceto MS? Pense em RDBMS e não em OO / Enums e faz sentido usar pesquisas.
gbn 20/10/11
1
OK, eu concordo. Obrigado por deixar isso claro. Portanto, é uma afirmação bastante precisa de que não há excesso de engenharia real com integridade relacional e tabelas de pesquisa? Quero dizer, nesse caso, ao armazenar um punhado de registros em uma tabela de pesquisa e referenciá-los em uma tabela consumidora, a declaração anterior seria precisa?
Thomas Stringer
1
@ onedaywhen: faz diferença se você olha para os diferentes tipos como dados ou como um conjunto estático de valores que nunca serão alterados. Se você usar uma tabela de tipos, poderá adicionar outro tipo à tabela sem a necessidade de alterar as regras de negócios no banco de dados e no aplicativo.
Guffa
1
@ MichaelKjörling: Correto, se fosse apenas uma chave. Mas o OP pretende que isso signifique algo como "v" ou "s". Observe que não falamos sobre auto-descrição e chaves naturais completas, como códigos de moeda (EUR, USD, GBP, CHF etc.).
gbn 20/10/11
3

Apenas como um complemento à grande resposta de gbn .

Talvez você possa criar algo assim:

create table dbo.VehicleType
(
    VehicleTypeId int not null primary key,
    Name varchar(50) not null,
    Code char(3) null
) 
go 

create table Car
(
    Name varchar(100) not null,
    Description varchar(100) not null,
    VehTypeId int not null ,
    foreign key FKTypeOfCar(VehTypeId) referenctes dbo.VehicleType (VehicleTypeId) 
)
go 

Assim, você pode fazer o que quiser com sua enumeração, mantendo a integridade relacional (usando uma chave estrangeira). Com a codecoluna, você pode usar seus códigos de caracteres à vontade, para que sejam documentados no banco de dados (e você pode extrair as informações do código diretamente do DB, sem uma transformação complicada no código do aplicativo para uma integração de sistemas).

Fabricio Araujo
fonte
Você quer permitir um nullcódigo?
Jack Douglas
Sim, o código é opcional para permitir representar um tipo de veículo que ainda não está codificado.
Fabricio Araujo 31/10
Por que as pessoas gostam de ficar excluindo comentários? É muito chato.
Fabricio Araujo 31/10
@FabricioAraujo - Se um comentário estiver obsoleto (por exemplo, "eu vou editar isso na minha resposta" e você realmente o fizer), é bom limpar os comentários que não se aplicam mais.
Nick Chammas
1
Eu sugeriria adicionar um tipo "Não classificado" à sua tabela de tipos e tornar o valor padrão do seu campo VehTypeId esse valor não classificado, em vez de permitir um valor nulo no campo de chave estrangeira. Geralmente, é uma prática ruim tornar "nulo" um significado comercial válido.
Michael Blackburn