Saya menggunakan kolom desimal untuk menyimpan nilai uang pada database, dan hari ini saya bertanya-tanya presisi dan skala apa yang digunakan.
Karena seharusnya kolom char dengan lebar tetap lebih efisien, saya berpikir hal yang sama bisa berlaku untuk kolom desimal. Apakah itu?
Dan presisi dan skala apa yang harus saya gunakan? Saya sedang berpikir presisi 24/8. Apakah itu berlebihan, tidak cukup atau ok?
Inilah yang saya putuskan untuk lakukan:
- Simpan kurs konversi (bila berlaku) dalam tabel transaksi itu sendiri, sebagai float
- Simpan mata uang di tabel akun
- Jumlah transaksi akan a
DECIMAL(19,4)
- Semua perhitungan menggunakan tingkat konversi akan ditangani oleh aplikasi saya jadi saya tetap mengendalikan masalah pembulatan
Saya tidak berpikir float untuk tingkat konversi adalah masalah, karena sebagian besar untuk referensi, dan saya akan tetap menggunakan desimal.
Terima kasih semua atas masukan berharga Anda.
DECIMAL(19, 4)
adalah pilihan yang populer periksa ini juga periksa di sini Format Mata Uang Dunia untuk memutuskan berapa banyak tempat desimal yang digunakan, semoga membantu.Jawaban:
Jika Anda mencari yang satu ukuran untuk semua, saya sarankan
DECIMAL(19, 4)
adalah pilihan yang populer (Google cepat menjelaskan ini). Saya pikir ini berasal dari tipe data VBA / Access / Jet Currency lama, menjadi tipe desimal titik tetap pertama dalam bahasa;Decimal
hanya datang dalam gaya 'versi 1.0' (yaitu tidak sepenuhnya diimplementasikan) di VB6 / VBA6 / Jet 4.0.Aturan praktis untuk penyimpanan nilai desimal titik tetap adalah menyimpan setidaknya satu tempat desimal lebih dari yang sebenarnya Anda perlukan untuk pembulatan. Salah satu alasan untuk memetakan
Currency
tipe lama di ujung depan untukDECIMAL(19, 4)
mengetik di ujung belakang adalah karenaCurrency
dipamerkan pembulatan bankir secara alami, sedangkanDECIMAL(p, s)
dibulatkan oleh pemotongan.Tempat desimal ekstra dalam penyimpanan untuk
DECIMAL
memungkinkan algoritme pembulatan kustom diterapkan daripada mengambil standar vendor (dan pembulatan bankir mengkhawatirkan, untuk sedikitnya, bagi desainer yang mengharapkan semua nilai yang diakhiri dengan 0,5 untuk memisahkan dari nol) .Ya,
DECIMAL(24, 8)
kedengarannya seperti berlebihan bagi saya. Sebagian besar mata uang dikutip ke empat atau lima tempat desimal. Saya tahu situasi di mana skala desimal 8 (atau lebih) berada diperlukan tetapi ini adalah di mana 'normal' jumlah moneter (mengatakan empat tempat desimal) telah pro rata'd, menyiratkan presisi desimal harus dikurangi sesuai (juga mempertimbangkan tipe floating point dalam keadaan seperti itu). Dan tidak ada yang memiliki banyak uang saat ini untuk membutuhkan ketepatan desimal 24 :)Namun, daripada pendekatan satu ukuran untuk semua, beberapa penelitian mungkin dilakukan. Tanyakan desainer atau pakar domain Anda tentang aturan akuntansi yang mungkin berlaku: GAAP, UE, dll. Saya secara samar-samar mengingat beberapa transfer intra-negara UE dengan aturan eksplisit untuk membulatkan ke lima tempat desimal, oleh karena itu digunakan
DECIMAL(p, 6)
untuk penyimpanan. Akuntan umumnya tampaknya menyukai empat tempat desimal.PS Hindari
MONEY
tipe data SQL Server karena memiliki masalah serius dengan akurasi ketika pembulatan, antara lain pertimbangan portabilitas dll. Lihat blog Aaron Bertrand .Microsoft dan perancang bahasa memilih pembulatan bankir karena perancang perangkat keras memilihnya [rujukan?]. Ini diabadikan dalam standar Institute of Electrical Engineers (IEEE), misalnya. Dan perancang perangkat keras memilihnya karena ahli matematika lebih menyukainya. Lihat Wikipedia ; untuk parafrase: Edisi 1906 Probabilitas dan Teori Kesalahan menyebut ini 'aturan komputer' ("komputer" yang berarti manusia yang melakukan perhitungan).
sumber
DECIMAL(19, 4)
lebih populer daripadaDECIMAL(19, 2)
? Sebagian besar mata uang dunia hanya dua tempat desimal.Kami baru-baru ini mengimplementasikan sistem yang perlu menangani nilai dalam berbagai mata uang dan mengkonversi di antara mereka, dan menemukan beberapa hal dengan cara yang sulit.
JANGAN PERNAH MENGGUNAKAN NOMOR TITIK FLOATING UNTUK UANG
Aritmatika titik mengambang memperkenalkan ketidakakuratan yang mungkin tidak diperhatikan sampai mereka mengacaukan sesuatu. Semua nilai harus disimpan sebagai bilangan bulat atau tipe desimal tetap, dan jika Anda memilih untuk menggunakan tipe desimal tetap maka pastikan Anda memahami dengan tepat apa yang dilakukan tipe di bawah tenda (yaitu, apakah secara internal menggunakan bilangan bulat atau titik mengambang Tipe).
Ketika Anda perlu melakukan perhitungan atau konversi:
Saat mengonversi angka floating point kembali ke integer pada langkah 3, jangan hanya melemparkannya - gunakan fungsi matematika untuk membulatkannya terlebih dahulu. Ini biasanya
round
, meskipun dalam kasus khusus bisafloor
atauceil
. Ketahui perbedaannya dan pilih dengan cermat.Simpan jenis angka di samping nilainya
Ini mungkin tidak sepenting bagi Anda jika Anda hanya menangani satu mata uang, tetapi penting bagi kami dalam menangani banyak mata uang. Kami menggunakan kode 3 karakter untuk mata uang, seperti USD, GBP, JPY, EUR, dll.
Bergantung pada situasinya, mungkin berguna juga untuk menyimpan:
Ketahui batas akurasi angka yang Anda hadapi
Untuk nilai nyata, Anda ingin setepat unit terkecil dari mata uang. Ini berarti Anda tidak memiliki nilai lebih kecil dari sen, sen, yen, fen, dll. Jangan menyimpan nilai dengan akurasi lebih tinggi dari itu tanpa alasan.
Secara internal, Anda dapat memilih untuk berurusan dengan nilai yang lebih kecil, dalam hal ini jenis nilai mata uang yang berbeda . Pastikan kode Anda tahu yang mana dan tidak mencampuradukkannya. Hindari menggunakan nilai floating point bahkan di sini.
Menambahkan semua aturan itu bersama-sama, kami memutuskan aturan berikut. Dalam menjalankan kode, mata uang disimpan menggunakan integer untuk unit terkecil.
Dalam database, nilai-nilai disimpan sebagai string dalam format berikut:
Itu menyimpan nilai $ 25,00. Kami dapat melakukan itu hanya karena kode yang berhubungan dengan mata uang tidak perlu berada di dalam lapisan basis data itu sendiri, sehingga semua nilai dapat dikonversi menjadi memori terlebih dahulu. Situasi lain tidak diragukan lagi akan memberikan solusi lain.
Dan jika saya tidak menjelaskan sebelumnya, jangan gunakan float!
sumber
bigint
jika Anda berniat mengurutkan berdasarkan jumlah. Dan jangan buang waktu Anda dengan PHP 32bit ketika berhadapan dengan bilangan bulat besar, tingkatkan ke 64bit atau Node.JS;)Saat menangani uang di MySQL, gunakan DECIMAL (13,2) jika Anda tahu ketepatan nilai uang Anda atau gunakan DOUBLE jika Anda hanya menginginkan nilai perkiraan cepat yang cukup bagus. Jadi, jika aplikasi Anda perlu menangani nilai uang hingga satu triliun dolar (atau euro atau pound), maka ini akan berhasil:
Atau, jika Anda harus mematuhi GAAP maka gunakan:
sumber
4 tempat desimal akan memberi Anda akurasi untuk menyimpan sub-unit mata uang terkecil di dunia. Anda dapat menurunkannya lebih jauh jika Anda membutuhkan akurasi pembayaran mikro (nanopayment ?!).
Saya juga lebih suka
DECIMAL
jenis uang spesifik DBMS, Anda lebih aman menjaga logika semacam itu dalam aplikasi IMO. Pendekatan lain di sepanjang garis yang sama adalah dengan menggunakan integer [panjang], dengan memformat menjadi ¤unit.subunit untuk keterbacaan manusia (¤ = simbol mata uang) yang dilakukan pada tingkat aplikasi.sumber
Jenis data uang pada SQL Server memiliki empat digit setelah desimal.
Dari SQL Server 2000 Books Online:
Data moneter menunjukkan jumlah uang positif atau negatif. Dalam Microsoft® SQL Server ™ 2000, data moneter disimpan menggunakan uang dan tipe data uang kecil. Data moneter dapat disimpan dengan akurasi empat tempat desimal. Gunakan tipe data uang untuk menyimpan nilai dalam kisaran dari -922.337.203.685.477.5808 hingga +922.333.2020.685.447.5807 (membutuhkan 8 byte untuk menyimpan nilai). Gunakan tipe data smallmoney untuk menyimpan nilai dalam kisaran dari -214.748,3648 hingga 214.748.3647 (membutuhkan 4 byte untuk menyimpan nilai). Jika lebih banyak tempat desimal diperlukan, gunakan tipe data desimal sebagai gantinya.
sumber
Kadang-kadang Anda harus pergi ke kurang dari satu sen dan ada mata uang internasional yang menggunakan demoniasi yang sangat besar. Misalnya, Anda mungkin menagih pelanggan Anda 0,088 sen per transaksi. Dalam database Oracle saya, kolom didefinisikan sebagai NUMBER (20,4)
sumber
Jika Anda akan melakukan segala macam operasi aritmatika di DB (mengalikan tarif penagihan dan sebagainya), Anda mungkin ingin lebih presisi daripada yang disarankan orang di sini, untuk alasan yang sama bahwa Anda tidak akan pernah ingin menggunakan apa pun yang kurang dari nilai floating point presisi ganda dalam kode aplikasi.
sumber
BigDecimal
), tetapi untuk waktu yang lama itu adalah presisi ganda (pikirkandouble
sebagai gantifloat
). Juga, ketepatan yang sewenang-wenang memiliki hukuman kinerja yang signifikan dalam beberapa kasus. Pengujian jelas merupakan pendekatan yang tepat.Jika Anda menggunakan IBM Informix Dynamic Server, Anda akan memiliki tipe MONEY yang merupakan varian minor pada tipe DECIMAL atau NUMERIC. Itu selalu merupakan tipe titik tetap (sedangkan DECIMAL dapat menjadi tipe titik mengambang). Anda dapat menentukan skala dari 1 hingga 32, dan presisi dari 0 hingga 32 (default ke skala 16 dan presisi 2). Jadi, tergantung pada apa yang perlu Anda simpan, Anda mungkin menggunakan DECIMAL (16,2) - masih cukup besar untuk menahan Defisit Federal AS, hingga sen terdekat - atau Anda mungkin menggunakan rentang yang lebih kecil, atau lebih banyak tempat desimal.
sumber
Saya akan berpikir bahwa sebagian besar kebutuhan Anda atau klien Anda harus menentukan presisi dan skala yang digunakan. Sebagai contoh, untuk situs web e-commerce saya sedang mengerjakan yang berurusan dengan uang hanya dalam GBP, saya telah diminta untuk menyimpannya hingga Desimal (6, 2).
sumber
Sebuah jawaban terlambat di sini, tapi saya sudah menggunakan
yang saya benar dalam berpikir harus memungkinkan hingga 99.999.999.999,99.
sumber