NUMERIC
/DECIMAL
Seperti Joachim Isaksson berkata
, Anda ingin menggunakan NUMERIC
/DECIMAL
jenis, sebagai jenis presisi sewenang-wenang.
Dua poin penting tentang NUMERIC
/DECIMAL
:
- Baca dokumen hati-hati untuk mempelajari bahwa Anda harus menentukan skala untuk menghindari skala default 0, yang berarti nilai integer di mana pecahan desimal dipotong. Meskipun ini adalah salah satu tempat di mana Postgres menyimpang dari SQL standar (memberi Anda skala apa pun hingga batas implementasi). Jadi gagal menentukan skala adalah pilihan yang buruk.
- Ketik SQL
NUMERIC
&DECIMAL
dekat tapi tidak identik sesuai dengan Standar SQL. Di SQL:92 , presisi yang Anda tentukan untukNUMERIC
dihormati, sedangkan untukDECIMAL
server database diizinkan untuk menambahkan presisi tambahan di luar apa yang Anda tentukan. Di sini sekali lagi Postgres sedikit menyimpang dari standar, dengan keduanyaNUMERIC
&DECIMAL
didokumentasikan setara.
Syarat:
- Presisi adalah jumlah total digit dalam sebuah angka.
- Skala adalah jumlah digit di sebelah kanan titik desimal (pecahan desimal).
- ( Presisi - Skala ) =Jumlah digit di sebelah kiri titik desimal (bagian bilangan bulat).
Perjelas spesifikasi proyek Anda untuk presisi dan skala:
- Besar
Presisinya harus cukup besar untuk menangani jumlah yang lebih besar yang mungkin dibutuhkan di masa depan. Artinya… Mungkin aplikasi Anda hari ini berfungsi dalam jumlah ribuan USD, tetapi di masa mendatang harus melakukan multi-laporan yang berakhir dalam jutaan. - Kecil
Untuk beberapa tujuan akuntansi, Anda mungkin perlu menyimpan sebagian kecil dari jumlah mata uang terkecil. Artinya… Lebih dari 3 atau 4 tempat desimal daripada 2 yang dibutuhkan untuk satu sen di USD .
Hindari MONEY
ketik
Postgres menawarkan MONEY
ketik juga. Itu mungkin terdengar benar, tetapi mungkin bukan yang terbaik untuk sebagian besar tujuan. Satu kelemahannya adalah dengan MONEY
skala disetel oleh setelan konfigurasi seluruh basis data berdasarkan lokal
. Sehingga pengaturan tersebut dapat berubah-ubah dengan mudah ketika Anda berpindah server atau membuat perubahan lainnya. Selain itu, Anda tidak dapat mengontrol pengaturan tersebut untuk kolom tertentu, sementara Anda dapat mengatur skala pada setiap kolom NUMERIC
Tipe. Terakhir, MONEY
bukan SQL standar seperti yang ditunjukkan dalam daftar data SQL standar ini jenis
. Postgres termasuk MONEY
untuk kenyamanan orang-orang yang memindahkan data dari sistem basis data lain.
Pindahkan Titik Desimal
Alternatif lain yang digunakan oleh beberapa orang adalah memindahkan titik desimal, dan hanya menyimpan dalam tipe data integer besar.
Misalnya, Jika menyimpan USD dolar ke sen, kelipatan bilangan pecahan apa pun dengan 100, masukkan ke tipe bilangan bulat, dan lanjutkan. Misalnya, $123,45 menjadi bilangan bulat 12,345.
Manfaat dari pendekatan ini adalah waktu eksekusi yang lebih cepat. Operasi seperti sum
sangat cepat bila dilakukan pada bilangan bulat. Manfaat lain untuk bilangan bulat adalah penggunaan memori yang lebih sedikit.
Saya menemukan pendekatan ini menjengkelkan, membingungkan, dan berisiko. Mengganggu karena komputer seharusnya bekerja untuk kita, bukan melawan kita. Berisiko karena beberapa programmer atau pengguna mungkin lalai mengalikan/membagi untuk mengubah kembali ke bilangan pecahan, memberikan hasil yang salah. Jika bekerja dalam sistem tanpa dukungan yang baik untuk bilangan pecahan yang akurat, pendekatan ini mungkin merupakan solusi yang dapat diterima.
Saya tidak melihat keuntungan apa pun untuk memindahkan titik desimal ketika kita memiliki DECIMAL
/NUMERIC
dalam SQL dan BigDecimal
di Jawa.
Pembulatan &NaN
Dalam pemrograman aplikasi Anda, serta setiap perhitungan yang dibuat di sisi server Postgres, berhati-hatilah dan waspada terhadap pembulatan dan pemotongan dalam pecahan desimal. Dan uji untuk NaNs yang tidak disengaja bermunculan.
Di kedua sisi, aplikasi dan Postgres, selalu hindari floating point tipe data untuk pekerjaan uang. Titik mengambang dirancang untuk kecepatan kinerja , tetapi dengan biaya akurasi . Perhitungan dapat menghasilkan angka ekstra yang tampak gila dalam pecahan desimal. Tidak baik untuk keuangan/uang atau tujuan lain yang membutuhkan akurasi.
BigDecimal
Ya, di Java, Anda ingin BigDecimal
sebagai tipe presisi sewenang-wenang Anda. BigDecimal
lebih lambat dan menggunakan lebih banyak memori, tetapi akan secara akurat menyimpan jumlah uang Anda. SQL NUMERIC
/DECIMAL
harus dipetakan ke BigDecimal
seperti yang dibahas di sini
dan di StackOverflow
.
BigDecimal
adalah salah satu hal terbaik tentang Jawa. Saya tidak tahu platform lain dengan kelas serupa, terutama yang diimplementasikan dengan baik dan diasah dengan baik dengan peningkatan dan perbaikan besar yang dilakukan selama bertahun-tahun.
Menggunakan BigDecimal
jelas lebih lambat daripada menggunakan Jenis floating-point Java
, float
&double
. Tetapi dalam aplikasi dunia nyata saya ragu perhitungan uang Anda akan menjadi hambatan. Selain itu, mana yang Anda atau pelanggan Anda inginkan:tercepat perhitungan uang, atau akurat perhitungan uang?
Saya selalu memikirkan BigDecimal
sebagai fitur sleeper terbesar di Java, keuntungan terpenting menggunakan platform Java dibandingkan banyak platform lain yang tidak memiliki dukungan canggih untuk bilangan pecahan.
Pertanyaan serupa:Jenis Data Terbaik Untuk Mata Uang