เมื่อพัฒนาระบบการชำระเงินหรืออีคอมเมิร์ซ คุณเคยคิดจะใช้ FLOAT หรือ DOUBLE สำหรับ ฟิลด์จำนวนเงินในฐานข้อมูล หรือไม่?
ถ้าเคย หยุดความคิดนั้นไว้เลย! ระบบของคุณอาจกำลังแอบทำเงินรั่วไหลอยู่
ทำไมระบบการเงินจึงห้ามใช้จุดทศนิยม (floating-point)? ข้อผิดพลาดด้านความแม่นยำ ที่ดูเหมือนจะเล็กน้อย เมื่อสะสมไปตามปริมาณธุรกรรมมหาศาลและเวลาที่ผ่านไป อาจนำไปสู่ความหายนะที่ไม่อาจแก้ไขได้
แล้วเราควรใช้อะไรในการจัดเก็บเงินกันแน่?
ทำไม FLOAT จึงเป็นอันตรายต่อระบบการเงิน?
ในโลกของคอมพิวเตอร์ ตัวเลขจะถูกแสดงในรูปแบบไบนารี FLOAT (จุดทศนิยม) เมื่อนำมาแสดงเศษส่วนทศนิยมบางค่า แท้จริงแล้วเป็นเพียง “ค่าประมาณ” เท่านั้น เปรียบเสมือนความพยายามที่จะตัดเค้กชิ้นประณีตด้วยเลื่อยไฟฟ้าที่หยาบกระด้าง ไม่ว่าคุณจะระมัดระวังแค่ไหน เศษเล็กเศษน้อยก็มักจะหลุดล่วงไปตามขอบเสมอ
ตัวอย่างที่คลาสสิกที่สุดคือ: 0.1 + 0.2 มักจะไม่เท่ากับ 0.3 ในคอมพิวเตอร์ หากคุณต้องประมวลผลธุรกรรมหลายล้านรายการ ข้อผิดพลาดเล็กๆ น้อยๆ ระดับ “0.00000000000000004” เหล่านี้จะสะสมไปเรื่อยๆ และบัญชีก็จะไม่มีวันตรงกัน โปรดจำไว้ว่า:
เมื่อเป็นเรื่องของเงิน การใช้ “ค่าประมาณ” ใดๆ ล้วนนำมาซึ่งความหายนะ
บัญชีรายรับรายจ่ายสุดประณีตของนักบัญชี: ข้อดีของ DECIMAL
หากคุณต้องการโซลูชันที่แม่นยำแบบ “เห็นอย่างไร ได้อย่างนั้น” DECIMAL คือ ตัวเลขทศนิยมแบบคงที่ (fixed-point number) ที่ฐานข้อมูลรองรับตั้งแต่ต้น และเป็นมาตรฐานของอุตสาหกรรม
DECIMAL เปรียบเสมือนบัญชีรายรับรายจ่ายสุดประณีตในมือของนักบัญชี มันแยกจำนวนเต็มและทศนิยมออกจากกันอย่างแม่นยำ มั่นใจได้ว่า 0.1 + 0.2 จะเท่ากับ 0.3 อย่างแน่นอน
สัดส่วนทองคำของอุตสาหกรรม: DECIMAL(19, 4)
โดยปกติเรามักจะแนะนำให้ใช้ DECIMAL(19, 4):
- 19: หมายถึงความสามารถในการรองรับตัวเลขทั้งหมด 19 หลัก (ความแม่นยำ)
- 4: หมายถึงการเก็บตัวเลขหลังจุดทศนิยม 4 หลัก
ทำไมต้องเก็บทศนิยม 4 ตำแหน่ง? เพราะในระหว่างการคำนวณดอกเบี้ย อัตราภาษี หรืออัตราแลกเปลี่ยน ขั้นตอนกลางมักจะให้ผลลัพธ์ที่มีทศนิยมมากกว่า 2 ตำแหน่ง การสำรองตัวเลขบัฟเฟอร์ไว้ 2 หลักจะช่วยเพิ่มความแม่นยำในการคำนวณ และคุณสามารถปัดเศษตามความต้องการทางธุรกิจในขั้นตอนสุดท้ายได้อย่างง่ายดาย
พื้นที่ความจุขนาดนี้ มากพอที่จะให้คุณซื้อ GDP ทั้งหมดของโลกได้หลายใบเลยทีเดียว!
เพียงพอสำหรับสถานการณ์ทางการเงินในโลกแห่งความเป็นจริงหรือไม่?
ยกตัวอย่าง DECIMAL(19, 4):
- ตัวเลขจำนวนเต็ม: 15 หลัก
- จำนวนเงินสูงสุด: 999,999,999,999,999
- แปลงเป็น USD: ประมาณ 999 ล้านล้านดอลลาร์สหรัฐ
| ข้อมูลอ้างอิง | จำนวนเงิน |
|---|---|
| GDP สหรัฐอเมริกา | ประมาณ 27 ล้านล้านดอลลาร์สหรัฐ |
| GDP โลกรวม | ประมาณ 105 ล้านล้านดอลลาร์สหรัฐ |
| ความมั่งคั่งโลกรวม | ประมาณ 454 ล้านล้านดอลลาร์สหรัฐ |
DECIMAL(19, 4) สามารถรองรับตัวเลขที่เกินกว่าความมั่งคั่งมวลรวมของโลกไปมาก ซึ่งเพียงพออย่างสมบูรณ์แบบสำหรับระบบการเงินส่วนใหญ่
ข้อจำกัดความแม่นยำ DECIMAL สูงสุดที่รองรับโดยฐานข้อมูลหลัก
| ฐานข้อมูล | ความแม่นยำสูงสุด (Precision) |
|---|---|
| MySQL / MariaDB | 65 |
| PostgreSQL | 131072 (หลักจำนวนเต็ม) + 16383 (หลักทศนิยม) |
| SQL Server | 38 |
| Oracle | 38 |
เครื่องเหรียญโทเค็นในอาเขต: วิธีหน่วยย่อยที่สุด BIGINT
หากคุณต้องการประสิทธิภาพขั้นสุด หรือระบบของคุณมีความต้องการทำงานพร้อมกันสูงมากอย่าง Stripe หรือ Alipay ดังนั้น BIGINT (วิธีการเก็บเป็นจำนวนเต็ม) อาจเป็นตัวเลือกที่ดีที่สุดของคุณ
วิธีการนี้เปรียบเสมือนเครื่องเหรียญโทเค็นในร้านเกมอาเขต: ไม่ว่าคุณจะใส่เงินเข้าไปเท่าไร เครื่องจะแปลงมันเป็น “หน่วยที่เล็กที่สุด” เพื่อใช้ในการจัดเก็บ ตัวอย่างเช่น:
- $100.50 USD → จัดเก็บเป็น
10050(เซนต์) - 100 TWD → จัดเก็บเป็น
100(ดอลลาร์)
ทำไมต้องเลือก BIGINT?
| เหตุผล | คำอธิบาย |
|---|---|
| ความเร็วสูงมาก | การบวกลบจำนวนเต็มคืองานที่ CPU ถนัด ประสิทธิภาพการคำนวณมักจะเร็วกว่า DECIMAL มาก |
| ประสิทธิภาพพื้นที่ | จัดสรรพื้นที่คงที่ 8 ไบต์ เหมาะอย่างยิ่งสำหรับฐานข้อมูลขนาดใหญ่พิเศษ |
อย่างไรก็ตาม ข้อเสียคือ อ่านยากกว่า เมื่อคุณเปิดฐานข้อมูลขึ้นมาและเห็นค่า 10050 คุณต้องรับหน้าที่หารด้วย 100 ภายในสมองของคุณ (หรือในโค้ดของคุณ) เองโดยอัตโนมัติ
บทสรุปสุดท้าย: ควรเลือกอย่างไร?
เพื่อตัดสินใจว่าจะใช้อะไร เราสามารถพิจารณาจาก “ความถี่ในการสืบค้นข้อมูล” และ “ขนาดของระบบ”:
| มิติการเปรียบเทียบ | DECIMAL | BIGINT |
|---|---|---|
| ความสามารถในการอ่าน | ยอดเยี่ยม (อ่านตัวเลขได้โดยตรง) | แย่กว่า (ต้องแปลงค่าด้วยตนเอง) |
| ความเร็วในการคำนวณ | ระดับปกติ | เร็วมาก |
| สถานการณ์การใช้งาน | ERP, ระบบการเงินภายใน, อีคอมเมิร์ซทั่วไป | การซื้อขายความถี่สูง (HFT), ไมโครเซอร์วิสขนาดใหญ่พิเศษ, API สไตล์ Stripe |
คำแนะนำในเชิงปฏิบัติ
| สถานการณ์การใช้งาน | ฟิลด์ที่แนะนำ |
|---|---|
| อีคอมเมิร์ซทั่วไป, ระบบรายงานข้อมูลภายในองค์กร ซึ่งนักบัญชีต้องรันคำสั่ง SQL เพื่อตรวจสอบบัญชีโดยตรง | DECIMAL(19, 4) |
| ระบบการซื้อขายความถี่สูง (HFT) หรือความต้องการด้านความสามารถในการขยายระบบสูงสุด | BIGINT |
บทสรุป
กล่าวสั้นๆ คือ ไม่ว่าคุณจะเลือกแบบใด ห้ามใช้ FLOAT ในการเก็บเงินโดยเด็ดขาดและถาวร! การเลือกประเภทฟิลด์ที่ถูกต้องจะรับประกันได้ว่าระบบของคุณยังคงมีความมั่นคงและแข็งแกร่งดั่งหินผาในการคำนวณทางการเงิน