Найкращий тип даних для зберігання значень валюти в базі даних MySQL


212

Який найкращий тип даних SQL для значень валюти? Я використовую MySQL, але віддаю перевагу незалежному типу даних.


Відповіді:


227

Щось подібне Decimal(19,4)зазвичай працює досить добре в більшості випадків. Ви можете налаштувати масштаб та точність відповідно до потреб чисел, які потрібно зберігати. Навіть у SQL Server я, як правило, не використовую " money", оскільки це нестандартно.


52
Точка щодо розміру: згідно з MSDN ( msdn.microsoft.com/en-us/library/ms187746.aspx ), десяткові (10,4) та десяткові (19,4) обидва використовують 9 байт пам’яті, добре весна для цих додаткових 9 цифр шкали.
Адам Нофсінгер

1
Стаття MSDN стосується SQL Server, але питання про MySQL. (Я зустрів розробників, які вважають, що обидва однакові, тому найкраще зрозуміти.)
cja

5
Яку користь використовувати (19,4)замість (19,2)?
ryvantage

1
Моя вигода полягала в цьому .. Мені потрібні були всі мої ряди столів, щоб дорівнювати певній кількості грошей. Скажімо, ця сума становить 10,00 доларів. Оскільки нові рядки додаються, кожна кількість змін змінюється. Якщо в таблиці є 3 ряди. 10/3 = 3,3333333333 ... але, маючи лише 2 десяткові дроби, вони зберігаються як 3,33. Отже, коли ви підсумуєте ці показники, 3,33 + 3,33 + 3,33 = 9,99. Ми втратили копійки! Отримує ще гірше на більшій кількості даних. Зберігайте в 19,4 і підсумовуйте підсумки, а тоді округніть вихід до 19,2 ..
Рік

49

Єдине, на що потрібно стежити - це якщо ви переходите з однієї бази даних до іншої, ви можете виявити, що DECIMAL (19,4) і DECIMAL (19,4) означають різні речі

( http://dev.mysql.com/doc/refman/5.1/uk/precision-math-decimal-changes.html )

    БАДА: 10,5 (10 цілих чисел, 5 знаків після коми)
    MYSQL: 15,5 (15 цифр, 10 цілих (15-5), 5 десяткових)

На жаль, посилання тепер мертва.
Marco Aurélio Deleu

1
@ MarcoAurélioDeleu - я змінив посилання, щоб вказати на сторінку на машині Wayback, тому ви можете побачити її так, як оглянувся в 2009 році.
Тоні

17

Також важливо розробити, скільки десяткових знаків може знадобитися для ваших розрахунків.

Я працював над заявкою на ціну акцій, яка вимагала розрахунку ціни на мільйон акцій. Пропоновану ціну акцій потрібно було зберігати до 7 цифр точності.


7
Це добре - особливо у фінансових додатках, "ціна", звичайно, не означає "гроші"
Майк Вудхаус

17

Відповідь Ассафа о

Залежить від того, скільки грошей ви отримали ...

звучить легковажно, але насправді це актуально.

Лише сьогодні у нас виникла проблема, коли запис не вдалося вставити в нашу таблицю оцінок, оскільки одна з колонок (GrossRate) встановлена ​​на десяткові (11,4), а наш відділ продуктів щойно отримав договір на приміщення на якомусь дивовижному курорті в Бора-Борі, які продають за кілька мільйонів тихоокеанських франків за ніч ... те, що ніколи не було антикопійовано, коли схема баз даних була розроблена 10 років тому.


2
Ось чому я рекомендував десятковий (19,4). Це може здатися непосильним, але ви ніколи не знаєте, коли вам потрібно буде зберігати дійсно велику кількість у цьому полі.
Кіббі

2
@Kibbee: Я б не погодився з вами щодо наших вимог до сьогодні. (Протягом 6 років (11,4) було прекрасно ...)
Скотт Фергюсон

@Kibbee Це звучить як 640 Kb meme :)
Микита Босик

13

Для облікових програм дуже часто зберігати значення як цілі числа (деякі навіть йдуть так далеко, щоб сказати, що це єдиний шлях). Щоб отримати ідею, візьміть суму транзакцій (припустимо, $ 100,23) та кратну на 100, 1000, 10000 тощо, щоб отримати необхідну точність. Тож якщо вам потрібно лише зберігати центи і можете сміливо округляти вгору чи вниз, просто помножте на 100. У моєму прикладі це зробить 10023 як ціле число для зберігання. Ви заощадите простір у базі даних, а порівняння двох цілих чисел набагато простіше, ніж порівняння двох плавців. Мої 0,02 долара.


Як ви зберігаєте 6.125 (6 1/8)?
PeterToTheThird

Я здогадуюсь, він би зберігав це як ціле число 6125.
Джиммі Кнут

2
Як би це було краще, ніж DECIMAL? Вам потрібно бути дуже обережними, коли завжди переводите копійки, млини або мілли в долари у відповідний час.

Я читав, що ефективність, як правило, швидша з INT, ніж DECIMAL, навіть в останніх версіях MySQL. Це також простіше, коли вам потрібно ввести ці значення в PHP або щось подібне і порівняти значення.
Дейн Бендіксен

9

супер пізній запис, але GAAP є хорошим правилом.

Якщо у вашій програмі потрібно обробляти кошти до трильйона, це має спрацювати: 13,2 Якщо вам потрібно дотримуватися GAAP (Загальноприйняті принципи бухгалтерського обліку), тоді використовуйте: 13,4

Зазвичай ви повинні підсумовувати свої кошти на рівні 13,4, перш ніж округлювати результат до 13,2.

Джерело: Найкращий тип даних для зберігання грошової вартості в MySQL


5

Ви можете використовувати щось на кшталт DECIMAL(19,2)за замовчуванням для всіх ваших грошових цінностей, але якщо ви коли-небудь зберігатимете значення, менші ніж 1000 доларів, це просто втратить цінний простір бази даних.

Для більшості реалізацій DECIMAL(N,2)було б достатньо, коли значення Nстановить принаймні кількість цифр до .найбільшої суми, яку ви коли-небудь очікуєте зберегти в цьому полі + 5. Тож якщо ви ніколи не розраховуєте зберігати значення, які перевищують 999999,99, їх DECIMAL(11,2)має бути більш ніж достатньо (доки очікування не зміниться).

Якщо ви хочете бути сумісними з GAAP , ви можете піти з тим DECIMAL(N,4), де значення Nстановить щонайменше кількість цифр до .найбільшої суми, яку ви коли-небудь очікуєте зберегти у цьому полі + 7.


3

Це залежить від характеру даних. Вам потрібно заздалегідь обміркувати це.

Моя справа

  • десятковий (13,4), не підписаний для запису грошових операцій
    • ефективне зберігання (4 байти в кожній стороні десяткової крапки) 1
    • Сумісність із GAAP
  • десяткові (19,4) не підписані для агрегатів
    • нам потрібно більше місця для сукупності декількох багатомільярдних транзакцій
    • напіввідповідність типу даних MS Currency не зашкодить 2
    • це займе більше місця на запис (11 байт - 7 ліворуч і 4 праворуч), але це нормально, оскільки є менше записів для агрегатів 1
  • десяткова (10,5) для обмінних курсів
    • вони, як правило, цитуються разом із 5 цифрами, щоб ви могли знайти такі значення, як 1.2345 та 12.345, але не 12345.67890
    • це широко розповсюджена конвенція, але не кодифікований стандарт (принаймні, до моїх знань швидкого пошуку)
    • ви можете зробити це десятковою (18,9) з однаковим сховищем, але обмеження типу даних є цінним вбудованим механізмом перевірки

Чому (М, 4)?

  • є валюти, які розбиваються на тисячу копійок
  • є грошові еквіваленти, такі як "Унідад де Ферменто", "CLF", виражені 4 значними десятковими знаками 3 , 4
  • це сумісно з GAAP

Компроміс

  • нижча точність:
    • менша вартість зберігання
    • швидші розрахунки
    • нижчий ризик помилки обчислення
    • швидше резервне копіювання та відновлення
  • більш висока точність:
    • майбутня сумісність (цифри мають тенденцію до зростання)
    • економія часу на розробку (вам не доведеться перебудовувати половину системи, коли ліміти будуть дотримані)
    • нижчий ризик відмови виробництва через недостатню точність зберігання

Сумісний екстремальний

Хоча MySQL дозволяє використовувати десятковий (65,30), 31 для шкали та 30 для точності, здається, наші обмеження, якщо ми хочемо залишити варіант передачі відкритим.

Максимальний масштаб і точність у найбільш поширених RDBMS:

            Точність шкали
Oracle 31 31
T-SQL 38 38
MySQL 65 30
PostgreSQL 131072 16383

6 , 7 , 8 , 9

Розумний Екстрім

  1. Чому (27,4)?
    • ви ніколи не знаєте, коли в системі потрібно зберігати зімбабвійські долари

Вересень 2015 Уряд Зімбабве заявив, що обміняє зімбабвійські долари на долари США за курсом від 1 долара до 35 квадрильйонів зимбабвійських доларів 5

Ми схильні говорити "так, точно ... мені не потрібні ці шалені цифри". Що ж, про це казали і Зімбабвійці. Не давно.

Давайте уявимо, що вам потрібно записати транзакцію в 1 мільйон доларів США в зимбабвійських доларах (можливо, це навряд чи сьогодні, але хто знає, як це буде виглядати через 10 років?).

  1. (1 млн. Дол. США) * (35 квадриліон ZWL) = (10 ^ 6) * (35 * 10 ^ 15) = 35 * 10 ^ 21
  2. нам потрібно:
    • 2 цифри для зберігання "35"
    • 21 цифра для зберігання нулів
    • 4 цифри праворуч від десяткової коми
  3. це робить десятковим (27,4), що коштує нам 15 байт за кожен запис
  4. ми можемо додавати ще одну цифру зліва без грошей - у нас десятковий (28,4) на 15 байт
  5. Тепер ми можемо зберігати трансакцію в 10 мільйонів доларів США, виражену в зімбабвійських доларах, або захистити від чергової страйку гіперінфляції, яка, сподіваємось, не відбудеться

0

Хоча це може бути пізно, але це буде корисно комусь іншому. З мого досвіду та досліджень я дізнався і приймаю десятковий (19, 6). Це під час роботи з php та mysql. при роботі з великою сумою грошей і курсом валют

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.