ดูเหมือนว่าMoney
ประเภทจะหมดกำลังใจตามที่อธิบายไว้ที่นี่
แอปพลิเคชันของฉันต้องการจัดเก็บสกุลเงินฉันจะใช้ประเภทข้อมูลใด ตัวเลขเงินหรือลอย?
ดูเหมือนว่าMoney
ประเภทจะหมดกำลังใจตามที่อธิบายไว้ที่นี่
แอปพลิเคชันของฉันต้องการจัดเก็บสกุลเงินฉันจะใช้ประเภทข้อมูลใด ตัวเลขเงินหรือลอย?
คำตอบ:
ตัวเลขที่มีความแม่นยำ 2 หน่วยบังคับ อย่าใช้ float หรือ float เหมือนประเภทข้อมูลเพื่อแสดงสกุลเงินเพราะถ้าคุณทำเช่นนั้นผู้คนจะไม่พอใจเมื่อตัวเลขด้านล่างของรายงานทางการเงินไม่ถูกต้องโดย + หรือ - ไม่กี่ดอลลาร์
ประเภทเงินเหลือเพียงเหตุผลทางประวัติศาสตร์เท่าที่ฉันสามารถบอกได้
scale - precision
numeric(3,2)
จะสามารถจัดเก็บได้สูงสุด9.99
3-2 = 1
แหล่งที่มาของคุณไม่เป็นทางการ มันเกิดขึ้นในปี 2011 และฉันจำผู้แต่งไม่ได้ด้วยซ้ำ หากประเภทเงินถูก "ท้อ" อย่างเป็นทางการ PostgreSQL จะบอกเช่นนั้นในคู่มือ - ซึ่งไม่ได้เป็นเช่นนั้น
สำหรับแหล่งข้อมูลที่เป็นทางการมากขึ้นโปรดอ่านหัวข้อนี้ใน pgsql-general (ตั้งแต่สัปดาห์นี้เท่านั้น!)พร้อมคำแถลงจากนักพัฒนาหลัก ได้แก่ D'Arcy JM Cain (ผู้เขียนต้นฉบับประเภทเงิน) และ Tom Lane:
คำตอบที่เกี่ยวข้อง (และความคิดเห็น!) เกี่ยวกับการปรับปรุงในรุ่นล่าสุด:
โดยทั่วไปmoney
มีการใช้งาน (จำกัด มาก) Postgres วิกิพีเดียให้เห็นส่วนใหญ่จะหลีกเลี่ยงได้ยกเว้นกรณีที่กำหนดไว้อย่างหวุดหวิดเหล่านั้น เปรียบที่เหนือกว่าnumeric
คือประสิทธิภาพการทำงาน
decimal
เป็นเพียงนามแฝงnumeric
ใน Postgres และใช้กันอย่างแพร่หลายสำหรับข้อมูลทางการเงินโดยเป็นประเภท "ความแม่นยำโดยพลการ" คู่มือ :
ประเภท
numeric
สามารถจัดเก็บตัวเลขที่มีจำนวนหลักได้มาก ขอแนะนำโดยเฉพาะอย่างยิ่งสำหรับการจัดเก็บจำนวนเงินและปริมาณอื่น ๆ ที่จำเป็นต้องมีความแน่นอน
โดยส่วนตัวแล้วฉันชอบเก็บสกุลเงินเป็นinteger
ตัวแทนของ Cents ถ้า Cents เศษส่วนไม่เคยเกิดขึ้น มีประสิทธิภาพมากกว่าตัวเลือกอื่น ๆ ที่กล่าวถึง
money
ประเภทนี้เลิกใช้งานแล้ว ปัญหาได้รับการแก้ไขแล้วและมีการเพิ่มประเภทกลับในเวอร์ชันที่ใหม่กว่า โดยส่วนตัวแล้วฉันชอบเก็บสกุลเงินเป็นinteger
ตัวแทนเซ็นต์
ทางเลือกของคุณคือ:
bigint
: จัดเก็บจำนวนเงินเป็นเซ็นต์ นี่คือสิ่งที่ธุรกรรม EFTPOS ใช้decimal(12,2)
: จัดเก็บจำนวนเงินด้วยทศนิยมสองตำแหน่ง นี่คือสิ่งที่ซอฟต์แวร์บัญชีแยกประเภททั่วไปส่วนใหญ่ใช้float
: ความคิดที่แย่มาก - ความแม่นยำไม่เพียงพอ นี่คือสิ่งที่นักพัฒนาไร้เดียงสาใช้ตัวเลือกที่ 2 เป็นวิธีที่ใช้กันทั่วไปและง่ายที่สุด ทำให้ความแม่นยำ (12 ในตัวอย่างของฉันหมายถึงตัวเลข 12 หลัก) ให้ใหญ่หรือเล็กที่สุดเท่าที่จะทำได้ดีที่สุดสำหรับคุณ
โปรดทราบว่าหากคุณรวมธุรกรรมหลายรายการที่เป็นผลมาจากการคำนวณ (เช่นเกี่ยวข้องกับอัตราแลกเปลี่ยน) ให้เป็นมูลค่าเดียวที่มีความหมายทางธุรกิจความแม่นยำควรสูงกว่าเพื่อให้ได้ค่ามหภาคที่ถูกต้อง พิจารณาใช้สิ่งที่ต้องการdecimal(18, 8)
เพื่อให้ผลรวมมีความถูกต้องและสามารถปัดเศษค่าแต่ละค่าให้เป็นค่าความแม่นยำกลางสำหรับการแสดงผลได้
numeric(15,4)
หรือnumeric(15,6)
เป็นความคิดที่ดี
ฉันเก็บช่องทางการเงินทั้งหมดไว้เป็น:
numeric(15,6)
ดูเหมือนว่าจะมีตำแหน่งทศนิยมมากเกินไป แต่หากมีโอกาสน้อยที่สุดที่คุณจะต้องจัดการกับหลายสกุลเงินคุณจะต้องมีความแม่นยำมากในการแปลง ไม่ว่าฉันจะนำเสนอผู้ใช้อะไรฉันก็เก็บเป็นดอลลาร์สหรัฐเสมอ ด้วยวิธีนี้ฉันสามารถแปลงเป็นสกุลเงินอื่นได้อย่างง่ายดายโดยพิจารณาจากอัตราการแปลงสำหรับวันที่เกี่ยวข้อง
หากคุณไม่เคยทำอะไรเลยนอกจากสกุลเงินเดียวสิ่งที่แย่ที่สุดคือคุณเสียพื้นที่เล็กน้อยเพื่อเก็บศูนย์
bigint
ฉันแนะนำให้ใช้ไมโครดอลลาร์ (หรือสกุลเงินหลักที่คล้ายกัน) ไมโครหมายถึง 1 ในล้านดังนั้น 1 ไมโครดอลล่าร์ = 0.000001 ดอลลาร์
numeric(15,6)
แนะนำมากกว่านี้ในคำตอบอื่น
bigint
น้อยกว่าค่าสูงสุด มีdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/…แต่มาพร้อมกับการสนับสนุนที่ จำกัด (สำหรับตอนนี้) และข้อควรระวัง (เช่นคุณไม่สามารถคูณด้วยการลอยตัวได้อย่างง่ายดายเมื่อทำการแปลงสกุลเงิน) . เนื่องจากจำนวนสูงสุดที่คุณสามารถจัดเก็บเป็นจำนวนเต็ม JS โดยใช้ไมโครดอลล่าร์คือ 9 พันล้านดอลลาร์ซึ่งอาจจะดีสำหรับกรณีส่วนใหญ่
ใช้BigInt
เพื่อเก็บสกุลเงินเป็นจำนวนเต็มบวกที่แสดงมูลค่าเงินในหน่วยสกุลเงินที่เล็กที่สุด (เช่น 100 เซ็นต์เพื่อเก็บ 1.00 ดอลลาร์หรือ 100 เพื่อเก็บ 100 เยน (เยนญี่ปุ่นเป็นสกุลเงินที่เป็นศูนย์ทศนิยม) นี่คือสิ่งที่ Stripe ทำ - หนึ่ง บริษัท ผู้ให้บริการทางการเงินที่สำคัญที่สุดสำหรับอีคอมเมิร์ซระดับโลก