ฉันกำลังเขียนคีสำหรับฐานข้อมูลธนาคารที่เรียบง่าย นี่คือคุณสมบัติพื้นฐาน:
- ฐานข้อมูลจะเก็บธุรกรรมกับผู้ใช้และสกุลเงิน
- ผู้ใช้ทุกคนมียอดดุลหนึ่งรายการต่อหนึ่งสกุลเงินดังนั้นแต่ละยอดดุลเป็นเพียงผลรวมของธุรกรรมทั้งหมดต่อผู้ใช้และสกุลเงิน
- ยอดคงเหลือต้องไม่ติดลบ
แอปพลิเคชันธนาคารจะสื่อสารกับฐานข้อมูลผ่านขั้นตอนการจัดเก็บ
ฉันคาดหวังว่าฐานข้อมูลนี้จะยอมรับการทำธุรกรรมใหม่หลายแสนรายการต่อวันรวมทั้งคำสั่งยอดคงเหลือในลำดับความสำคัญที่สูงขึ้น ในการให้บริการยอดคงเหลืออย่างรวดเร็วฉันต้องรวมไว้ล่วงหน้า ในเวลาเดียวกันฉันต้องรับประกันว่ายอดเงินจะไม่ขัดแย้งกับประวัติการทำธุรกรรม
ตัวเลือกของฉันคือ:
มี
balances
ตารางแยกต่างหากและทำสิ่งใดสิ่งหนึ่งต่อไปนี้:ใช้ธุรกรรมกับทั้ง
transactions
และbalances
ตาราง ใช้TRANSACTION
ตรรกะในเลเยอร์ของโพรซีเดอร์ที่เก็บไว้เพื่อให้แน่ใจว่ายอดคงเหลือและการทำธุรกรรมมีการซิงค์อยู่เสมอ (รองรับโดยแจ็ค )ใช้ธุรกรรมกับ
transactions
ตารางและมีทริกเกอร์ที่อัปเดตbalances
ตารางให้ฉันด้วยจำนวนธุรกรรมใช้ธุรกรรมกับ
balances
ตารางและมีทริกเกอร์ที่เพิ่มรายการใหม่ในtransactions
ตารางให้ฉันด้วยจำนวนธุรกรรม
ฉันต้องพึ่งพาวิธีการรักษาความปลอดภัยเพื่อให้แน่ใจว่าไม่มีการเปลี่ยนแปลงใด ๆ นอกกระบวนการที่เก็บไว้ มิฉะนั้นตัวอย่างเช่นกระบวนการบางอย่างสามารถแทรกธุรกรรมลงใน
transactions
ตารางโดยตรงและภายใต้โครงการ1.3
ยอดคงเหลือที่เกี่ยวข้องจะไม่ซิงค์กันมี
balances
มุมมองที่จัดทำดัชนีที่รวมการทำธุรกรรมอย่างเหมาะสม เครื่องมือเก็บข้อมูลรับประกันยอดคงเหลือเพื่อให้สอดคล้องกับการทำธุรกรรมของพวกเขาดังนั้นฉันไม่จำเป็นต้องพึ่งพาวิธีการรักษาความปลอดภัยเพื่อรับประกันสิ่งนี้ ในทางกลับกันฉันไม่สามารถบังคับยอดคงเหลือให้เป็นค่าที่ไม่เป็นลบได้อีกต่อไปนับตั้งแต่การดู - แม้แต่การดูที่มีการจัดทำดัชนี - ไม่สามารถมีCHECK
ข้อ จำกัด ได้ (สนับสนุนโดยDenny )มีเพียง
transactions
ตารางแต่มีคอลัมน์เพิ่มเติมเพื่อจัดเก็บยอดคงเหลือที่มีประสิทธิภาพหลังจากทำรายการนั้นแล้ว ดังนั้นบันทึกธุรกรรมล่าสุดสำหรับผู้ใช้และสกุลเงินจึงมียอดดุลปัจจุบัน (แนะนำโดยAndrewด้านล่าง; ตัวแปรที่เสนอโดยgarik )
ครั้งแรกที่ผมจัดการปัญหานี้ผมอ่านเหล่านี้ สอง2
การอภิปรายและการตัดสินใจในตัวเลือก สำหรับการอ้างอิงคุณสามารถดูการดำเนินงานที่เปลือยกระดูกของมันนี่
คุณออกแบบหรือจัดการฐานข้อมูลเช่นนี้ด้วยโปรไฟล์การโหลดสูงหรือไม่ คุณมีวิธีแก้ไขปัญหานี้อย่างไร
คุณคิดว่าฉันได้เลือกการออกแบบที่ถูกต้องหรือไม่? มีอะไรบ้างที่ฉันควรจำไว้?
ตัวอย่างเช่นฉันรู้ว่าการเปลี่ยนสคีมาใน
transactions
ตารางจะต้องมีการสร้างbalances
มุมมองใหม่ แม้ว่าฉันจะเก็บถาวรธุรกรรมเพื่อทำให้ฐานข้อมูลมีขนาดเล็ก (เช่นย้ายไปที่อื่นและแทนที่ด้วยธุรกรรมสรุป) การสร้างมุมมองใหม่จากการทำธุรกรรมหลายสิบล้านครั้งด้วยการปรับปรุง schema ทุกครั้งอาจหมายถึงการหยุดทำงานต่อการปรับใช้หากมุมมองที่จัดทำดัชนีเป็นวิธีที่จะไปฉันจะรับประกันได้อย่างไรว่าไม่มียอดคงเหลือติดลบ?
ธุรกรรมที่เก็บถาวร:
ให้ฉันอธิบายเพิ่มเติมเล็กน้อยเกี่ยวกับธุรกรรมการเก็บถาวรและ "ธุรกรรมสรุป" ที่ฉันได้กล่าวไว้ข้างต้น ก่อนอื่นการเก็บถาวรแบบปกติจะเป็นสิ่งจำเป็นในระบบโหลดสูงเช่นนี้ ฉันต้องการรักษาความสอดคล้องระหว่างยอดคงเหลือและประวัติธุรกรรมของพวกเขาในขณะที่อนุญาตให้ย้ายธุรกรรมเก่าไปที่อื่น ในการทำเช่นนี้ฉันจะแทนที่ธุรกรรมที่เก็บถาวรทุกชุดด้วยการสรุปจำนวนเงินต่อผู้ใช้และสกุลเงิน
ตัวอย่างเช่นรายการธุรกรรมนี้:
user_id currency_id amount is_summary
------------------------------------------------
3 1 10.60 0
3 1 -55.00 0
3 1 -12.12 0
ถูกเก็บถาวรออกไปและแทนที่ด้วยสิ่งนี้:
user_id currency_id amount is_summary
------------------------------------------------
3 1 -56.52 1
ด้วยวิธีนี้ดุลที่มีธุรกรรมที่เก็บถาวรจะรักษาประวัติธุรกรรมที่สมบูรณ์และสอดคล้องกัน