ประเภทข้อมูลที่ดีที่สุดสำหรับการจัดเก็บค่าสกุลเงินในฐานข้อมูล 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 หลัก
Adam Nofsinger

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 ..
Rick

49

สิ่งเดียวที่คุณต้องระวังคือถ้าคุณย้ายจากฐานข้อมูลหนึ่งไปอีกฐานข้อมูลคุณอาจพบว่า DECIMAL (19,4) และ DECIMAL (19,4) หมายถึงสิ่งที่แตกต่างกัน

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

    DBASE: 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

Assaf ตอบสนองของ

ขึ้นอยู่กับจำนวนเงินที่คุณได้รับ ...

ฟังดูเยือกเย็น แต่จริงๆแล้วมันเป็นเรื่องถาวร

เฉพาะวันนี้เรามีปัญหาที่บันทึกไม่สามารถแทรกลงในตารางอัตราของเราเพราะหนึ่งในคอลัมน์ (GrossRate) ถูกกำหนดเป็นทศนิยม (11,4) และแผนกผลิตภัณฑ์ของเราเพิ่งได้รับสัญญาสำหรับห้องพักในรีสอร์ทที่น่าตื่นตาตื่นใจ ใน Bora Bora ขายได้หลายล้านฟรังก์แปซิฟิกต่อคืน ... สิ่งที่ไม่เคยคาดเดามาก่อนเมื่อสคีมาฐานข้อมูลถูกออกแบบเมื่อ 10 ปีที่แล้ว


2
นี่คือเหตุผลที่ฉันแนะนำทศนิยม (19,4) อาจฟังดูเหมือน overkill แต่คุณไม่มีทางรู้ว่าคุณจะต้องจัดเก็บจำนวนมากในเขตข้อมูลนั้น
Kibbee

2
@Kibbee: ฉันจะไม่เห็นด้วยกับคุณสำหรับความต้องการของเราจนถึงวันนี้ (สำหรับ 6 ปี (11,4) เป็นสมบูรณ์ดี ... )
สกอตต์เฟอร์กูสัน

@Kibbee ฟังดูเหมือน 640 Kb meme :)
Nikita Bosik

13

สำหรับแอปพลิเคชันการบัญชีเป็นเรื่องธรรมดามากที่จะเก็บค่าเป็นจำนวนเต็ม (บางคนถึงกับบอกว่ามันเป็นวิธีเดียวเท่านั้น ) ในการรับแนวคิดให้ใช้จำนวนการทำธุรกรรม (สมมติว่า $ 100.23) และทวีคูณด้วย 100, 1,000, 10,000 เป็นต้นเพื่อให้ได้ความแม่นยำที่คุณต้องการ ดังนั้นถ้าคุณต้องการเก็บเซนต์และสามารถปัดขึ้นหรือลงได้อย่างปลอดภัยเพียงคูณด้วย 100 ในตัวอย่างของฉันนั่นจะทำให้ 10023 เป็นจำนวนเต็มในการจัดเก็บ คุณจะสามารถประหยัดพื้นที่ในฐานข้อมูลและการเปรียบเทียบจำนวนเต็มสองจำนวนเป็นมากง่ายกว่าเปรียบเทียบสองลอย ฉัน $ 0.02


คุณเก็บ 6.125 (6 1/8) ได้อย่างไร?
PeterToTheThird

ฉันเดาว่าเขาจะเก็บมันเป็นจำนวนเต็ม
6125

2
มันจะดีกว่านี้DECIMALอย่างไร คุณจะต้องระมัดระวังเป็นอย่างมากเกี่ยวกับการแปลเพนนีโรงสีหรือ millrays เป็นดอลลาร์ในเวลาที่เหมาะสม

ฉันอ่านแล้วว่าโดยทั่วไปประสิทธิภาพจะเร็วขึ้นด้วย INT มากกว่า DECIMAL แม้แต่ใน MySQL เวอร์ชันล่าสุด นอกจากนี้ยังง่ายขึ้นเมื่อคุณต้องการนำค่าเหล่านี้มาไว้ใน PHP หรือบางอย่างและเปรียบเทียบค่า
Dane Bendixen

9

การมาสายช้า แต่ GAAP เป็นกฎที่ดี

หากแอปพลิเคชันของคุณต้องการจัดการกับค่าเงินสูงถึงหนึ่งล้านล้านนี่ควรใช้งานได้: 13,2 ถ้าคุณจำเป็นต้องปฏิบัติตาม GAAP (หลักการบัญชีที่ยอมรับโดยทั่วไป) ให้ใช้: 13,4

โดยปกติคุณควรรวมมูลค่าเงินของคุณที่ 13,4 ก่อนที่จะปัดเศษผลลัพธ์เป็น 13,2

ที่มา: ประเภทข้อมูลที่ดีที่สุดในการจัดเก็บค่าเงินใน MySQL


5

คุณสามารถใช้บางอย่างเช่นDECIMAL(19,2)โดยค่าเริ่มต้นสำหรับค่าเงินทั้งหมดของคุณ แต่ถ้าคุณเพียงเก็บค่าต่ำกว่า $ 1,000 นั่นเป็นเพียงการเสียพื้นที่ฐานข้อมูลที่มีค่า

สำหรับการนำไปใช้งานส่วนใหญ่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) ด้วยการจัดเก็บข้อมูลเดียวกัน แต่ข้อ จำกัด ประเภทข้อมูลเป็นกลไกการตรวจสอบในตัวที่มีคุณค่า

ทำไม (M, 4)

  • มีสกุลเงินที่แบ่งออกเป็นพันเพนนี
  • มีรายการเทียบเท่าเงินเช่น "Unidad de Fermento", "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)
    • คุณไม่เคยรู้เมื่อระบบต้องการเก็บดอลลาร์ซิมบับเว

กันยายน 2558 รัฐบาลซิมบับเวระบุว่าจะแลกเปลี่ยนดอลลาร์ซิมบับเวเป็นดอลลาร์สหรัฐในอัตรา 1 ดอลลาร์สหรัฐเป็น 35 พันล้านล้านดอลลาร์ซิมบับเว5

เรามักจะพูดว่า "ใช่แน่นอน ... ฉันไม่ต้องการตัวเลขบ้าคลั่ง" ซิมบับเวก็เคยพูดเช่นกัน เมื่อไม่นานมานี้

ลองจินตนาการว่าคุณต้องบันทึกการทำธุรกรรมจำนวน 1 ล้านเหรียญสหรัฐในดอลลาร์ซิมบับเว (อาจจะเป็นไปได้ยากในวันนี้ แต่ใครจะรู้ว่าสิ่งนี้จะมีลักษณะอย่างไรใน 10 ปีจากนี้?)

  1. (1 mln USD) * (35 Quadrylion 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 เมื่อทำงานกับเงินจำนวนมากและอัตราแลกเปลี่ยน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.