FLOAT і DOUBLE зберігають числа у двійковій формі з плаваючою комою. Більшість десяткових дробів так точно не записати: 0.1 + 0.2 дає 0.30000000000000004. На мільйонах операцій копійки «губляться», а сума в звіті не сходиться з сумою платежів.
Два правильні варіанти:
NUMERIC/DECIMAL- точний десятковий тип:
amount NUMERIC(12, 2) NOT NULL
- Ціле число в найменших одиницях - копійках чи центах (
BIGINT). Так роблять Stripe та більшість платіжних систем: 1 999 копійок замість 19.99 грн.
Що ще важливо:
- Валюта поруч із сумою.
100без валюти нічого не означає. Окрема колонкаcurrency CHAR(3)(ISO 4217). - У PHP теж не
float: суму тримають якintу копійках або як рядок і рахують черезbcmathчи бібліотеки на кшталтbrick/money. - Округлення - явне й в одному місці. Розподіл 100 грн на три частини має дати 33.34 + 33.33 + 33.33, а не загубити копійку.
- Тип
moneyу PostgreSQL не радять: його формат залежить від налаштувань локалі сервера.