Para birimi değerlerini bir MySQL veritabanında depolamak için en iyi veri türü


Yanıtlar:


227

Decimal(19,4)Çoğu durumda genellikle böyle bir şey oldukça iyi çalışır. Ölçeği ve hassasiyeti, saklamanız gereken sayıların gereksinimlerine uyacak şekilde ayarlayabilirsiniz. SQL Server'da bile moneystandart olmayan " " kullanmama eğilimindeyim .


52
Boyut hakkında bir nokta: MSDN'ye göre ( msdn.microsoft.com/en-us/library/ms187746.aspx ), Ondalık (10,4) ve Ondalık (19,4) her ikisi de 9 bayt depolama kullanır, bu nedenle ekstra 9 basamaklı ölçek için iyi yay.
Adam Nofsinger

1
MSDN makalesi SQL Server hakkında ama soru MySQL hakkında. (Her ikisinin de açık olmak için en iyi aynı olduğunu düşünen geliştiricilerle tanıştım.)
cja

5
Bunun (19,4)yerine kullanmanın yararı nedir (19,2)?
ryvantage

1
Benim yararım şuydu .. Tüm tablo satırlarımın belli bir paraya eşit olması gerekiyordu. Diyelim ki bu miktar 10,00 dolar. Yeni satırlar eklendikçe her satır miktarı değişir. Tabloda 3 satır varsa. 10/3 = 3.3333333333 ... ancak sadece 2 ondalık sayı ile 3.33 olarak saklanırlar. Bunları topladığınızda 3.33 + 3.33 + 3.33 = 9.99. Bir kuruş kaybettik! Daha büyük bir veri kümesinde daha da kötüleşir. 19,4'te saklayın ve toplamlarınızı toplayın, ardından çıktıyı 19,2'ye yuvarlayın.
Rick

49

Dikkat etmeniz gereken tek şey, bir veritabanından diğerine geçiş yaparsanız DECIMAL (19,4) ve DECIMAL (19,4) 'ün farklı şeyler ifade ettiğini görebilirsiniz.

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

    DBASE: 10,5 (10 tam sayı, 5 ondalık)
    MYSQL: 15,5 (15 basamak, 10 tam sayı (15-5), 5 ondalık)

Maalesef bağlantı artık öldü.
Marco Aurélio Deleu

1
@ MarcoAurélioDeleu - Bağlantıyı Wayback Machine'deki sayfaya işaret edecek şekilde değiştirdim, böylece 2009'da geriye baktığınızı görebilirsiniz.
Tony

17

Hesaplamalarınız için kaç ondalık basamağın gerekli olabileceğini bulmak da önemlidir.

Bir milyon hissenin fiyatının hesaplanmasını gerektiren bir hisse fiyatı uygulaması üzerinde çalıştım. Kote edilen hisse fiyatının 7 basamak doğrulukta depolanması gerekiyordu.


7
Bu iyi bir nokta - özellikle finansal uygulamalarda, "fiyat" kesinlikle "para" anlamına gelmez
Mike Woodhouse

17

Assaf'ın yanıtı

Ne kadar paranız olduğuna bağlı ...

kulağa ters geliyor, ama aslında uygun.

Yalnızca bugün Ücret tablosumuza bir kayıt eklenemediğinde bir sorun vardı, çünkü sütunlardan biri (GrossRate) Ondalık (11,4) olarak ayarlandı ve Ürün departmanımız bazı şaşırtıcı tesislerdeki odalar için bir sözleşme aldı Bora Bora'da gecelik birkaç milyon Pasifik Frangı satıyor ... veritabanı şeması 10 yıl önce tasarlandığında hiç beklenmeyen bir şey.


2
Bu yüzden ondalık basamak tavsiye ettim (19,4). Kulağa aşırı gelme gibi gelebilir, ancak bu alanda ne zaman gerçekten büyük miktarda depolamanız gerektiğini asla bilemezsiniz.
Kibbee

2
@Kibbee: Bugüne kadar gereksinimlerimiz için seninle anlaşamazdım. (6 yıldır (11,4) mükemmel bir şekilde iyiydi ...)
Scott Ferguson

@Kibbee Bu ses 640 Kb meme gibi geliyor :)
Nikita Bosik

13

Muhasebe uygulamaları için değerleri tamsayı olarak saklamak çok yaygındır (bazıları bunun tek yol olduğunu söyleyecek kadar ileri gider ). Bir fikir edinmek için, ihtiyacınız olan doğruluğu elde etmek için işlem miktarını (100.23 $ diyelim) ve 100, 1000, 10000 vb. Yani sadece sentleri depolamanız gerekiyorsa ve güvenli bir şekilde yukarı veya aşağı yuvarlanabiliyorsanız, sadece 100 ile çarpın. Veritabanında yerden tasarruf edersiniz ve iki tamsayıyı karşılaştırmak iki kayan nokta karşılaştırmaktan daha kolaydır. Benim 0.02 $.


6.125'i (6 1/8) nasıl saklarsınız?
PeterToTheThird

Sanırım tamsayı 6125 olarak saklardı.
Jimmy Knoot

2
Bu nasıl daha iyi olurdu DECIMAL? Uygun zamanlarda her zaman kuruşları, değirmenleri veya milyarları dolarlara çevirmek konusunda çok dikkatli olmanız gerekir .

MySQL'in en son sürümlerinde bile performansın INT ile DECIMAL'den daha hızlı olduğunu okudum. Bu değerleri PHP'ye veya başka bir şeye dönüştürmeniz ve değerleri karşılaştırmanız gerektiğinde de daha kolaydır.
Dane Bendixen

9

süper geç giriş ama GAAP iyi bir kural.

Başvurunuzun bir trilyona kadar para değerlerini işlemesi gerekiyorsa, bunun çalışması gerekir: 13,2 GAAP (Genel Kabul Görmüş Muhasebe İlkeleri) ile uyumlu olmanız gerekiyorsa şunu kullanın: 13,4

Çıktının 13,2'ye yuvarlanmasından önce genellikle para değerlerinizi 13,4 olarak toplamalısınız.

Kaynak: Parasal değeri MySQL'de depolamak için en iyi veri türü


5

DECIMAL(19,2)Tüm parasal değerleriniz için varsayılan olarak benzer bir şey kullanabilirsiniz , ancak yalnızca 1.000 $ 'ın altındaki değerleri depolarsanız, bu sadece değerli veritabanı alanı kaybı olacaktır.

Çoğu uygulama için, DECIMAL(N,2)değeri, bu alanda depolanmasını beklediğiniz en büyük toplamdan Nönceki en az hane sayısı olduğunda yeterli olacaktır . Bu nedenle, 999999,99'dan daha büyük bir değer depolamayı beklemiyorsanız, (beklentiler değişene kadar) fazlasıyla yeterli olmalıdır..+ 5DECIMAL(11,2)

Eğer olmak istiyorsan GAAP sürekli uyumluluk, sen ile gidebiliriz DECIMAL(N,4)değeri nerede, Nönceki hane sayısı en az olan .hiç bu alanda depolanacak bekliyoruz büyük toplamının + 7.


3

Verilerin doğasına bağlıdır. Önceden düşünmeniz gerekiyor.

Benim olayım

  • para işlemlerini kaydetmek için ondalık (13,4) imzasız
    • depolama verimli (yine de ondalık noktasının her iki tarafı için 4 bayt) 1
    • GAAP uyumlu
  • toplamlar için ondalık (19,4) işaretsiz
    • toplam çoklu milyarlarca işlem için daha fazla alana ihtiyacımız var
    • MS Para Birimi veri türüne yarı uyumluluk zarar vermez 2
    • kayıt başına daha fazla yer kaplar (11 bayt - 7 sol ve 4 sağ), ancak toplama için daha az kayıt olduğu için bu iyi 1
  • döviz kurları için ondalık (10,5)
    • normalde 5 rakamla alıntılanırlar, böylece 1.2345 ve 12.345 gibi değerler bulabilirsiniz, ancak 12345.67890 değil
    • yaygın bir sözleşmedir, ancak kodlanmış bir standart değildir (en azından hızlı arama bilgime göre)
    • aynı depolama alanı ile ondalık (18,9) yapabilirsiniz, ancak veri türü kısıtlamaları değerli yerleşik doğrulama mekanizmasıdır

Neden (E, 4)?

  • bin kuruşa bölünmüş para birimleri var
  • "Unidad de Fermento", "CLF" gibi 4 önemli ondalık basamakla ifade edilen para eşdeğerleri vardır 3 , 4
  • GAAP uyumlu

Pazarlıksız

  • düşük hassasiyet:
    • daha az depolama maliyeti
    • daha hızlı hesaplamalar
    • düşük hesaplama hatası riski
    • daha hızlı yedekleme ve geri yükleme
  • yüksek hassasiyet:
    • gelecekteki uyumluluk (sayılar artma eğilimi gösterir)
    • geliştirme süresi tasarrufları (limitler karşılandığında yarım sistemin yeniden inşası gerekmez)
    • yetersiz depolama hassasiyeti nedeniyle daha düşük üretim hatası riski

Uyumlu Extreme

Her ne kadar MySQL ondalık (65,30) kullanmanıza izin verse de, transfer seçeneğini açık bırakmak istiyorsak ölçek için 31 ve hassasiyet için 30 sınırlarımız gibi görünüyor.

En yaygın RDBMS'de maksimum ölçek ve hassasiyet:

            Hassas ölçek
Oracle 31 31
T-SQL 38 38
MySQL 65 30
PostgreSQL 131072 16383

6 , 7 , 8 , 9

Makul Aşırı

  1. Neden (27,4)?
    • sistemin ne zaman Zimbabwe doları depolaması gerektiğini asla bilemezsiniz

Eylül 2015 Zimbabwe hükümeti Zimbabwe Doları'nı 1 ABD Doları ile 35 katrilyon Zimbabwe Doları karşılığında değiştireceğini açıkladı 5

"Evet, elbette ... O çılgın figürlere ihtiyacım olmayacak" diyoruz. Zimbabweans bunu da söylerdi. Çok uzun zaman önce değil.

Zimbabwe doları cinsinden 1 milyon dolarlık bir işlem kaydetmeniz gerektiğini düşünelim (belki bugün pek mümkün değil, ancak bundan 10 yıl sonra nasıl görüneceğini kim bilebilir?).

  1. (1 milyon USD) * (35 Quadrylion ZWL) = (10 ^ 6) * (35 * 10 ^ 15) = 35 * 10 ^ 21
  2. ihtiyacımız var:
    • "35" depolamak için 2 hane
    • Sıfırları saklamak için 21 basamak
    • Ondalık noktasının sağındaki 4 basamak
  3. bu, her giriş için bize 15 bayta mal olan ondalık sayı (27,4) yapar
  4. sol tarafa ücretsiz olarak bir rakam daha ekleyebiliriz - 15 bayt için ondalık (28,4) var
  5. Şimdi Zimbabwe doları cinsinden ifade edilen 10 milyon dolarlık işlemi saklayabiliriz veya umarız olmayacak olan başka bir hiperinflasyon grevinden koruyabiliriz

0

Bu geç olabilir, ancak başka birine yardımcı olacaktır.Tecrübelerim ve araştırmalarımdan itibaren ondalık olduğunu bilip kabul ediyorum (19, 6). Php ve mysql ile çalışırken. büyük miktarda para ve döviz kuru ile çalışırken

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.