ฉันสร้างระบบเช่นนี้สำหรับแอพเมื่อประมาณ 8 ปีที่แล้วและฉันสามารถแบ่งปันสองสามวิธีที่มันมีการพัฒนาเมื่อการใช้งานแอพเพิ่มขึ้น
ฉันเริ่มต้นด้วยการบันทึกทุกการเปลี่ยนแปลง (แทรกอัปเดตหรือลบ) จากอุปกรณ์ใด ๆ ลงในตาราง "ประวัติ" ตัวอย่างเช่นหากมีคนเปลี่ยนหมายเลขโทรศัพท์ในตาราง "ผู้ติดต่อ" ระบบจะแก้ไขฟิลด์ contact.phone และเพิ่มบันทึกประวัติด้วย action = update, field = phone, record = [contact ID], value = [หมายเลขโทรศัพท์ใหม่] จากนั้นเมื่อใดก็ตามที่อุปกรณ์ทำการซิงค์อุปกรณ์จะทำการดาวน์โหลดรายการประวัติตั้งแต่การซิงค์ครั้งล่าสุดและนำไปใช้กับฐานข้อมูลท้องถิ่น ดูเหมือนว่ารูปแบบ "การจำลองแบบรายการ" ที่อธิบายไว้ข้างต้น
ปัญหาหนึ่งคือการรักษา ID ที่ไม่ซ้ำกันเมื่อสามารถสร้างรายการบนอุปกรณ์ที่แตกต่างกัน ฉันไม่รู้เกี่ยวกับ UUID เมื่อฉันเริ่มต้นใช้งานดังนั้นฉันจึงใช้ ID ที่เพิ่มขึ้นอัตโนมัติและเขียนรหัสที่ซับซ้อนที่รันบนเซิร์ฟเวอร์กลางเพื่อตรวจสอบ ID ใหม่ที่อัปโหลดจากอุปกรณ์เปลี่ยนเป็น ID เฉพาะหากมีข้อขัดแย้งและ บอกอุปกรณ์ต้นทางให้เปลี่ยน ID ในฐานข้อมูลโลคัล เพียงแค่เปลี่ยน ID ของบันทึกใหม่ก็ไม่ได้แย่ขนาดนั้น แต่ถ้าฉันสร้างตัวอย่างเช่นรายการใหม่ในตารางที่ติดต่อจากนั้นสร้างรายการที่เกี่ยวข้องใหม่ในตารางเหตุการณ์ตอนนี้ฉันมีกุญแจต่างประเทศที่ฉันต้อง ตรวจสอบและอัปเดต
ในที่สุดฉันก็ได้เรียนรู้ว่า UUID สามารถหลีกเลี่ยงปัญหานี้ได้ แต่จากนั้นฐานข้อมูลของฉันก็ค่อนข้างใหญ่และฉันก็กลัวว่าการติดตั้ง UUID แบบเต็มรูปแบบจะทำให้เกิดปัญหาเรื่องประสิทธิภาพ ดังนั้นแทนที่จะใช้ UUID เต็มรูปแบบฉันเริ่มใช้คีย์ตัวอักษรผสมตัวเลขที่สร้างขึ้นแบบสุ่ม 8 ตัวเป็น ID และฉันปล่อยรหัสที่มีอยู่ของฉันไว้เพื่อจัดการกับความขัดแย้ง อยู่ระหว่างคีย์ 8 ตัวอักษรปัจจุบันของฉันกับ 36 ตัวอักษรของ UUID จะต้องมีจุดหวานที่จะกำจัดความขัดแย้งโดยไม่ต้องขยายตัวที่ไม่จำเป็น แต่เนื่องจากฉันมีรหัสการแก้ปัญหาความขัดแย้งอยู่แล้ว .
ปัญหาต่อไปคือตารางประวัติมีขนาดใหญ่กว่าฐานข้อมูลที่เหลือทั้งหมดประมาณ 10 เท่า สิ่งนี้ทำให้การจัดเก็บมีราคาแพงและการบำรุงรักษาใด ๆ ในตารางประวัติอาจเจ็บปวด การรักษาทั้งตารางนั้นช่วยให้ผู้ใช้ย้อนกลับการเปลี่ยนแปลงก่อนหน้านี้ได้บ้าง ดังนั้นฉันจึงเพิ่มกิจวัตรประจำวันในกระบวนการซิงค์โดยที่หากรายการประวัติที่อุปกรณ์ดาวน์โหลดล่าสุดไม่มีอยู่ในตารางประวัติเซิร์ฟเวอร์จะไม่ให้รายการประวัติล่าสุด แต่ให้แฟ้มที่มีข้อมูลทั้งหมดแทน บัญชีนั้น จากนั้นฉันเพิ่ม cronjob เพื่อลบรายการประวัติที่เก่ากว่า 90 วัน ซึ่งหมายความว่าผู้ใช้ยังคงสามารถย้อนกลับการเปลี่ยนแปลงน้อยกว่า 90 วันและถ้าพวกเขาซิงค์อย่างน้อยหนึ่งครั้งในทุก ๆ 90 วันการปรับปรุงจะเพิ่มขึ้นตามเดิม แต่ถ้าพวกเขารอนานกว่า 90 วัน
การเปลี่ยนแปลงนั้นลดขนาดของตารางประวัติลงเกือบ 90% ดังนั้นตอนนี้การดูแลรักษาตารางประวัติจะทำให้ฐานข้อมูลใหญ่ขึ้นสองเท่าแทนที่จะใหญ่กว่าสิบเท่า ประโยชน์อีกอย่างของระบบนี้คือการซิงค์ยังคงทำงานได้โดยไม่ต้องมีตารางประวัติหากต้องการ - เช่นถ้าฉันต้องการทำการบำรุงรักษาบางอย่างที่ใช้งานออฟไลน์ชั่วคราว หรือฉันสามารถเสนอช่วงเวลาย้อนกลับที่แตกต่างกันสำหรับบัญชีที่มีจุดราคาต่างกัน และหากมีการเปลี่ยนแปลงมากกว่า 90 วันในการดาวน์โหลดไฟล์ที่สมบูรณ์มักจะมีประสิทธิภาพมากกว่ารูปแบบที่เพิ่มขึ้น
หากฉันเริ่มใหม่วันนี้ฉันจะข้ามการตรวจสอบความขัดแย้งของ ID และเพียงแค่กำหนดระยะเวลาที่สำคัญเพียงพอที่จะกำจัดข้อขัดแย้งด้วยการตรวจสอบข้อผิดพลาดบางประเภท แต่ตารางประวัติและการรวมกันของการดาวน์โหลดที่เพิ่มขึ้นสำหรับการอัปเดตล่าสุดหรือการดาวน์โหลดแบบเต็มเมื่อจำเป็นทำงานได้ดี