Parece que o Money
tipo é desencorajado conforme descrito aqui
Meu aplicativo precisa armazenar moeda, que tipo de dados devo usar? Numérico, Dinheiro ou FLUTUANTE?
Parece que o Money
tipo é desencorajado conforme descrito aqui
Meu aplicativo precisa armazenar moeda, que tipo de dados devo usar? Numérico, Dinheiro ou FLUTUANTE?
Respostas:
Numérico com precisão forçada de 2 unidades. Nunca use float ou float como tipo de dados para representar a moeda, pois, se o fizer, as pessoas ficarão descontentes quando o resultado final do relatório financeiro estiver incorreto em + ou - alguns dólares.
O tipo de dinheiro é deixado apenas por razões históricas, pelo que sei.
scale - precision
numeric(3,2)
poderá armazenar max9.99
3-2 = 1
Sua fonte não é oficial. Data de 2011 e eu nem reconheço os autores. Se o tipo de dinheiro fosse oficialmente "desencorajado", o PostgreSQL diria isso no manual - o que não acontece .
Para uma fonte mais oficial , leia este tópico no pgsql-general (a partir desta semana!) , Com declarações de desenvolvedores principais, incluindo D'Arcy JM Cain (autor original do tipo financeiro) e Tom Lane:
Resposta relacionada (e comentários!) Sobre melhorias em versões recentes:
Basicamente, money
tem seus usos (muito limitados). O Wiki do Postgres sugere evitá-lo em grande parte, exceto nos casos definidos de maneira restrita. O mais vantagem numeric
é o desempenho .
decimal
é apenas um apelido para numeric
no Postgres e amplamente usado para dados monetários, sendo um tipo de "precisão arbitrária". O manual :
O tipo
numeric
pode armazenar números com um número muito grande de dígitos. É especialmente recomendado para armazenar valores monetários e outras quantidades onde a exatidão é necessária.
Pessoalmente, eu gosto de guardar a moeda como integer
representando centavos se centavos fracionários nunca ocorrerem (basicamente onde o dinheiro faz sentido). Isso é mais eficiente do que qualquer outra opção mencionada.
money
tipo era, de fato, obsoleto. Os problemas foram corrigidos e o tipo foi adicionado novamente em versões posteriores. Pessoalmente, gosto de armazenar moeda como integer
representando centavos.
Suas escolhas são:
bigint
: armazene o valor em centavos. É isso que as transações EFTPOS usam.decimal(12,2)
: armazene o valor com exatamente duas casas decimais. É o que o software de contabilidade mais geral usa.float
: idéia terrível - precisão inadequada. É isso que desenvolvedores ingênuos usam.A opção 2 é a mais comum e mais fácil de trabalhar. Faça com que a precisão (12 no meu exemplo, que significa 12 dígitos ao todo) seja grande ou pequena, conforme for melhor para você.
Observe que, se você estiver agregando várias transações que resultaram de um cálculo (por exemplo, envolvendo uma taxa de câmbio) em um único valor com significado comercial, a precisão deve ser maior para fornecer um valor macro preciso; considere usar algo assim decimal(18, 8)
para que a soma seja precisa e os valores individuais possam ser arredondados para centavos de precisão para exibição.
numeric(15,4)
ou numeric(15,6)
é uma boa ideia.
Eu mantenho todos os meus campos monetários como:
numeric(15,6)
Parece excessivo ter tantas casas decimais, mas se houver a menor chance de você lidar com várias moedas, precisará de tanta precisão para a conversão. Não importa o que eu estou apresentando para um usuário, eu sempre guardo em dólares americanos. Dessa forma, eu posso facilmente converter para qualquer outra moeda, dada a taxa de conversão do dia envolvido.
Se você nunca fizer nada além de uma moeda, a pior coisa aqui é que você perdeu um pouco de espaço para armazenar alguns zeros.
bigint
Eu recomendo o uso de microdólares (ou moeda principal semelhante). Micro significa milionésimo, então 1 microdólar = US $ 0,000001.
numeric(15,6)
sugerido em outra resposta?
bigint
. Existe o developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…, mas ele vem com suporte limitado (por enquanto) e advertências (por exemplo, você não pode multiplicá-lo por um flutuador facilmente ao fazer conversão de moeda) . Dado que o máximo que você pode armazenar em um número inteiro JS usando micro-dólares é de US $ 9 bilhões, o que provavelmente ainda é bom para a maioria dos casos.
Use BigInt
para armazenar a moeda como um número inteiro positivo que representa o valor monetário na menor unidade monetária (por exemplo, 100 centavos para armazenar $ 1,00 ou 100 para armazenar ¥ 100 (iene japonês, uma moeda de zero decimal). É isso que o Stripe faz - um as empresas de serviços financeiros mais importantes para o comércio eletrônico global.