sql >> Databáze >  >> RDS >> PostgreSQL

Údaje o penězích na PostgreSQL pomocí Javy

NUMERIC /DECIMAL

Jak řekl Joachim Isaksson , chcete použít NUMERIC /DECIMAL typu jako libovolný přesný typ.

Dva důležité body o NUMERIC /DECIMAL :

  • Přečtěte si dokument pečlivě, abyste zjistili, že byste měli určit měřítko, abyste se vyhnuli výchozímu měřítku 0, což znamená celočíselné hodnoty, kde je desetinný zlomek odříznut. I když toto je jedno z míst, kde se Postgres odchyluje od standardního SQL (což vám dává jakékoli měřítko až do limitu implementace). Takže neuvedení měřítka je špatná volba.
  • Typy SQL NUMERIC &DECIMAL jsou blízké, ale nejsou totožné podle standardu SQL. V SQL:92 , vámi zadaná přesnost pro NUMERIC je respektováno, zatímco pro DECIMAL databázovému serveru je povoleno přidat další přesnost nad rámec toho, co jste zadali. Zde se Postgres opět trochu vymyká standardu, s oběma NUMERIC &DECIMAL zdokumentováno jako ekvivalent.

Podmínky:

  • Přesnost je celkový počet číslic v čísle.
  • Měřítko je počet číslic napravo od desetinné čárky (desetinný zlomek).
  • ( Přesnost – Měřítko ) =Počet číslic nalevo od desetinné čárky (celá část).

Ujasněte si specifikace vašeho projektu pro přesnost a měřítko:

  • Velký
    Přesnost musí být dostatečně velká, aby zvládla větší čísla, která mohou být v budoucnu zapotřebí. To znamená... Možná, že vaše aplikace dnes funguje v řádech tisíců USD, ale v budoucnu musí provádět souhrnné přehledy, které skončí v milionech.
  • Malý
    Pro některé účetní účely možná budete muset uložit zlomek nejmenší částky v měně. To znamená… Více než 3 nebo 4 desetinná místa namísto 2 potřebných pro cent v USD .

Vyhněte se MONEY typ

Postgres nabízí MONEY typ také. To může znít správně, ale pravděpodobně to není nejlepší pro většinu účelů. Jedna nevýhoda je, že s MONEY škála je nastavena nastavením konfigurace pro celou databázi na základě místního prostředí . Toto nastavení se tedy může nebezpečně snadno měnit, když přepínáte servery nebo provádíte jiné změny. Kromě toho nemůžete toto nastavení ovládat pro konkrétní sloupce, zatímco můžete nastavit měřítko pro každý sloupec NUMERIC typ. Nakonec MONEY není standardní SQL, jak je uvedeno v tomto seznamu standardních dat SQL typy . Postgres zahrnuje MONEY pro pohodlí lidí, kteří přenášejí data z jiných databázových systémů.

Přesuňte desetinnou čárku

Další alternativou, kterou někteří používají, je přesunutí desetinné čárky a uložení ve velkém celočíselném datovém typu.

Pokud například ukládáte USD dolarů na cent, vynásobte libovolné dané zlomkové číslo 100, přetypujte na typ celé číslo a pokračujte. Například 123,45 $ se stane celým číslem 12 345.

Výhodou tohoto přístupu je rychlejší provedení. Operace jako sum jsou velmi rychlé při provádění na celá čísla. Další výhodou celých čísel je menší využití paměti.

Tento přístup mi připadá otravný, matoucí a riskantní. Nepříjemné, protože počítače by měly fungovat pro nám, ne proti nám. Riskantní, protože některý programátor nebo uživatel může zanedbávat násobení/dělení, aby převedl zpět na zlomkové číslo, což dává nesprávné výsledky. Pokud pracujete v systému bez dobré podpory přesných zlomkových čísel, může být tento přístup přijatelným řešením.

Nevidím žádnou výhodu v posunutí desetinné čárky, když máme DECIMAL /NUMERIC v SQL a BigDecimal v Javě.

Zaokrouhlení a NaN

Při programování vaší aplikace a také při jakýchkoli výpočtech prováděných na straně serveru Postgres buďte velmi opatrní a uvědomte si zaokrouhlování a zkracování v desetinném zlomku. A test na neúmyslné NaN vyskakující.

Na obou stranách, v aplikaci i v Postgresu, se vždy vyhněte plovoucí desetinná čárka datové typy pro práci s penězi. Plovoucí desetinná čárka je navržena pro rychlost výkonu , ale za náklady na přesnost . Výpočty mohou mít za následek zdánlivě šílené další číslice v desetinném zlomku. Není vhodné pro finanční/peněžní účely nebo jiné účely, kde záleží na přesnosti.

BigDecimal

Ano, v Javě chcete BigDecimal jako váš libovolný typ přesnosti. BigDecimal je pomalejší a využívá více paměti, ale přesně uloží vaše peněžní částky. SQL NUMERIC /DECIMAL by se měl namapovat na BigDecimal jak je uvedeno zde a na StackOverflow .

BigDecimal je jedna z nejlepších věcí na Javě. Nevím o žádné jiné platformě s podobnou třídou, zvláště o tak dobře implementované a vypilované s velkými vylepšeními a opravami provedenými v průběhu let.

Pomocí BigDecimal je rozhodně pomalejší než použití typů Java s plovoucí desetinnou čárkou , float &double . Ale v aplikacích v reálném světě pochybuji, že vaše výpočty peněz budou překážkou. A kromě toho, co vy nebo vaši zákazníci chcete:nejrychlejší výpočty peněz nebo přesné výpočty peněz? 😉

Vždy jsem myslel na BigDecimal jako největší funkce spánku v Javě, nejdůležitější výhoda používání platformy Java oproti mnoha jiným platformám, které postrádají tak sofistikovanou podporu pro zlomková čísla.

Podobná otázka:Nejlepší datový typ pro měnu



  1. Jak vypočítám plochu polygonu v databázi MySQL, když jsou body polygonu Lat Longs?

  2. Jak napsat dotaz MySQL, který vrátí dočasný sloupec obsahující příznaky, zda položka související s tímto řádkem existuje v jiné tabulce

  3. Jak mohu provést tento agregát?

  4. Jak nainstalovat ArangoDB na Ubuntu 20.04