Qual é o melhor tipo de dados para manter valores percentuais que variam de 0,00% a 100,00%?
Qual é o melhor tipo de dados para manter valores percentuais que variam de 0,00% a 100,00%?
Respostas:
Presumindo duas casas decimais em suas porcentagens, o tipo de dados que você usa depende de como você planeja armazenar suas porcentagens. Se você for armazenar seu equivalente fracionário (por exemplo, 100,00% armazenado como 1,0000), armazenarei os dados em um decimal(5,4)
tipo de dados com uma CHECK
restrição que garante que os valores nunca excedam 1,0000 (assumindo que é o limite) e nunca vão abaixo de 0 (assumindo que seja o chão). Se você for armazenar seu valor de face (por exemplo, 100,00% é armazenado como 100,00), então você deve usar decimal(5,2)
com uma CHECK
restrição apropriada . Combinado com um bom nome de coluna, torna claro para outros desenvolvedores o que são os dados e como os dados são armazenados na coluna.
decimal(5,2)
onde 2 denota o número de dígitos após o separador decimal?
decimal(5,2)
é o que deve ser capturado com uma restrição de verificação.
decimal(5,4)
e foi alterado para decimal(5,2)
após o comentário acima ... Acho que decimal(5,4)
seria a melhor definição - ou seja, você deseja armazenar 0 a 1 com 2 casas decimais, não 0 a 100. O motivo de ser uma porcentagem está fora de 100; então 100% é 100/100, que é 1. Fazer dessa forma faz mais sentido para a maioria dos casos (por exemplo 100% * 100% = 100%
, não 10000%
; 1 * 1 = 1
).
100.00
), você precisa decimal(5,2)
. Se os valores forem armazenados como frações (por exemplo 1.0000
), você precisará decimal(5,4)
. Irá atualizar o post.
decimal
.columnName decimal(precision, scale)
. A precisão diz o número total de dígitos que podem ser mantidos no número, a escala diz quantos deles estão após a casa decimal, então decimal(3,2)
é um número que pode ser representado como #.##
; decimal(5,3)
seria ##.###
. decimal
e numeric
são essencialmente a mesma coisa. No entanto, decimal
é compatível com ANSI, portanto, sempre use-o a menos que seja instruído de outra forma (por exemplo, pelos padrões de codificação de sua empresa).Cenários de Exemplo
decimal(5,4)
.decimal(3,2)
.Exemplo:
if object_id('Demo') is null
create table Demo
(
Id bigint not null identity(1,1) constraint pk_Demo primary key
, Name nvarchar(256) not null constraint uk_Demo unique
, SomePercentValue decimal(3,2) constraint chk_Demo_SomePercentValue check (SomePercentValue between 0 and 1)
, SomePrecisionPercentValue decimal(5,2) constraint chk_Demo_SomePrecisionPercentValue check (SomePrecisionPercentValue between 0 and 1)
)
Leitura adicional:
0 to 1
vs 0 to 100
: C #: Armazenando porcentagens, 50 ou 0,50?Eu concordo com o Thomas e eu escolheria a solução DECIMAL (5,4) pelo menos para aplicações WPF.
Dê uma olhada na String de formato numérico do MSDN para saber por quê: http://msdn.microsoft.com/en-us/library/dwhawy9k#PFormatString
O especificador de formato de porcentagem ("P") multiplica um número por 100 e o converte em uma string que representa uma porcentagem.
Então, você seria capaz de usar isso em seu código XAML:
DataFormatString="{}{0:P}"
Se 2 casas decimais for o seu nível de precisão, um "smallint" trataria disso no menor espaço (2 bytes). Você armazena a porcentagem multiplicada por 100.
EDIT: O tipo decimal é provavelmente uma correspondência melhor. Então você não precisa escalar manualmente. Leva 5 bytes por valor.
Use numérico (n, n) onde n tem resolução suficiente para arredondar para 1,00. Por exemplo:
declare @discount numeric(9,9)
, @quantity int
select @discount = 0.999999999
, @quantity = 10000
select convert(money, @discount * @quantity)