ในฐานะ Senior Architect ที่ต้องออกแบบระบบการเงินและบัญชี ความแม่นยำของข้อมูล (Data Integrity) คือรากฐานที่ห้ามประนีประนอม การเลือกใช้ประเภทข้อมูล (Data Type) ในฐานข้อมูลจึงไม่ใช่แค่การบันทึกค่า แต่คือการรับประกันความถูกต้องทางคณิตศาสตร์ที่ต้องไม่มีข้อผิดพลาดแม้แต่จุดทศนิยมเดียว หากเลือกใช้ประเภทข้อมูลที่ผิดพลาด อาจนำไปสู่ปัญหาที่เรียกว่า Floating Point Error ซึ่งส่งผลกระทบต่อยอดคงเหลือและรายงานทางการเงินได้อย่างร้ายแรง
หลักการเลือก Data Type สำหรับงานการเงินด้วย PostgreSQL
เมื่อทำงานกับระบบที่เกี่ยวข้องกับการเงิน เราต้องแยกแยะประเภทข้อมูลออกเป็น 3 กลุ่มหลัก คือ ตัวเลขจำนวนเต็ม, ตัวเลขทศนิยมความแม่นยำสูง, และตัวเลขประมาณค่า
1. สำหรับตัวเลขทศนิยม (Money/Currency): DECIMAL หรือ NUMERIC (The Golden Standard)
สำหรับงานการเงิน ห้ามใช้ FLOAT หรือ REAL เด็ดขาด เพราะประเภทเหล่านี้ใช้การคำนวณแบบเลขฐานสอง (Binary Floating Point) ซึ่งทำให้เกิดข้อผิดพลาดในการปัดเศษ (Rounding Error) ที่เล็กน้อยแต่สะสมจนเป็นปัญหาใหญ่ได้
ทางออกที่ดีที่สุดคือการใช้ DECIMAL หรือ NUMERIC ใน PostgreSQL ซึ่งเป็นประเภทข้อมูลที่ให้ความแม่นยำแบบคงที่ (Fixed Precision) คุณต้องระบุความแม่นยำ (Precision) และจำนวนตำแหน่งทศนิยม (Scale) เสมอ
Syntax: NUMERIC(P, S) โดย P คือความแม่นยำรวม (Total Digits) และ S คือจำนวนตำแหน่งทศนิยม (Scale)
2. สำหรับตัวเลขจำนวนเต็ม (ID/Count): INT vs BIGINT
ประเภทเหล่านี้ใช้สำหรับเก็บค่าที่ไม่มีทศนิยม เช่น รหัส ID, จำนวนรายการ, หรือตัวนับ
- INT (Integer): เหมาะสำหรับค่าที่คาดการณ์ว่าไม่เกิน 2.1 พันล้าน (ประมาณ 4 ไบต์)
- BIGINT (Big Integer): ควรใช้เมื่อคาดว่าจำนวนรายการหรือรหัส ID จะมีขอบเขตที่กว้างกว่า 2.1 พันล้าน เพื่อป้องกันการเกิด Overflow ในอนาคต
ตัวอย่างการใช้งานใน PostgreSQL
นี่คือตัวอย่างการสร้างตารางที่ถูกต้องสำหรับระบบการเงิน โดยเน้นการใช้ NUMERIC สำหรับยอดเงิน และ BIGINT สำหรับรหัส:
SQL
CREATE TABLE financial_transactions (
transaction_id BIGSERIAL PRIMARY KEY, -- ใช้ BIGSERIAL เพื่อให้ได้ BIGINT อัตโนมัติ
account_id BIGINT NOT NULL, -- รหัสบัญชีที่อาจมีขนาดใหญ่
transaction_date DATE NOT NULL,
amount NUMERIC(19, 4) NOT NULL, -- ใช้ NUMERIC(19, 4) เพื่อความแม่นยำสูง (19 หลัก, 4 ตำแหน่งทศนิยม)
description VARCHAR(255)
);
ข้อควรระวังในการใช้งาน (The Pitfall)
หากคุณพยายามเก็บยอดเงินในรูปแบบ FLOAT จะเกิดข้อผิดพลาดทางคณิตศาสตร์ที่มองไม่เห็น:
SQL
-- ตัวอย่างการคำนวณที่ผิดพลาด (ห้ามใช้ในงานเงิน)
SELECT 0.1 + 0.2; -- ผลลัพธ์อาจไม่ใช่ 0.3 พอดีในฐานข้อมูลบางตัว
แต่เมื่อใช้ NUMERIC จะรับประกันความแม่นยำ:
SQL
-- ตัวอย่างการคำนวณที่แม่นยำ
SELECT NUMERIC(10, 2) FROM (SELECT 0.1 AS val UNION ALL SELECT 0.2) AS t; -- ผลลัพธ์ที่ถูกต้องคือ 0.30
บทสรุป: หลักการจำง่ายๆ
เพื่อสรุปสำหรับงานการเงินที่ต้องการความแม่นยำสูงสุด:
- เงิน/ยอดเงิน: ต้องใช้
NUMERIC(P, S)เสมอ - รหัส ID/ตัวนับ: ใช้
BIGINTเพื่อความปลอดภัยในระยะยาว - ห้ามใช้:
FLOATหรือREALในงานบัญชี
การยึดหลักการเหล่านี้จะช่วยให้ระบบของคุณมีความเสถียรทางข้อมูล (Data Stability) และความน่าเชื่อถือระดับ Senior Architect ได้อย่างสมบูรณ์