การรักษาความสมบูรณ์ของ Referential ระหว่างไคลเอนต์มือถือและเซิร์ฟเวอร์


21

ดังนั้นฉันจึงมีระบบที่ค่อนข้างเรียบง่าย ลูกค้าโทรศัพท์มือถือสร้างบันทึกในฐานข้อมูล SQLite ที่ผมอยากจะได้ซิงค์กับเซิร์ฟเวอร์ระยะไกล SQL (ที่ใช้ร่วมกันกับลูกค้ามือถืออื่น ๆ ) ดังนั้นเมื่อฉันสร้างระเบียนใหม่ในตาราง sqlite ของโทรศัพท์ฉันจะผลักดันการเปลี่ยนแปลงไปยังบริการระยะไกลของฉันผ่าน RESTful API ปัญหาที่ฉันมีคือฉันจะสั่งซื้อคีย์หลักอย่างไรเพื่อไม่ให้เกิดการชนกันของข้อมูล (เช่นบันทึกในโทรศัพท์มีคีย์หลักเดียวกันกับระเบียนที่แตกต่างกันโดยสิ้นเชิงบนเซิร์ฟเวอร์) "แนวปฏิบัติที่ดีที่สุดสำหรับการอ้างอิงระเบียนบนไคลเอนต์คืออะไรและสำหรับการอ้างอิงระเบียนเดียวกันบนเซิร์ฟเวอร์?


1
แนวคิดที่เกินความเป็นไปได้คือไคลเอนต์ทำหน้าที่เป็นแคชสำหรับเว็บเซิร์ฟเวอร์โดยมีการเปลี่ยนแปลงที่สร้างขึ้นในไคลเอนต์จากนั้นส่งไปยังเว็บเซิร์ฟเวอร์
JoeCortopassi

คำตอบ:


22

การปฏิบัติปกติคือการจัดโครงสร้างฐานข้อมูลของคุณด้วยuniqueidentifierคีย์ (บางครั้งเรียกว่า UUID หรือ GUID) คุณสามารถสร้างพวกเขาในสองแห่งโดยไม่ต้องกลัวการชนกัน

ถัดไปแอพมือถือของคุณต้องซิงค์ตาราง "ข้อเท็จจริง" จากเซิร์ฟเวอร์ก่อนที่คุณจะสามารถสร้างแถวใหม่ได้ เมื่อคุณสร้างแถวใหม่คุณจะทำแบบโลคัลและเมื่อคุณซิงค์อีกครั้งแถวใหม่จะถูกเพิ่มไปยังเซิร์ฟเวอร์ คุณสามารถทำสิ่งเดียวกันกับการอัปเดตและลบได้เช่นกัน

ในการติดตามส่วนแทรกคุณต้องมีการประทับเวลาที่สร้างบนแถวของคุณ ในการติดตามการอัพเดทคุณต้องติดตามการประทับเวลา LastUpdate ในแถวของคุณ ในการติดตามการลบคุณต้องมีตารางหินหลุม

โปรดทราบว่าเมื่อคุณทำการซิงค์คุณต้องตรวจสอบเวลาออฟเซ็ตระหว่างเซิร์ฟเวอร์และอุปกรณ์มือถือและคุณต้องมีวิธีในการแก้ไขข้อขัดแย้ง ส่วนแทรกไม่ใช่เรื่องใหญ่ (ไม่ควรขัดแย้ง) แต่การอัปเดตอาจขัดแย้งและการลบอาจขัดแย้งกับการอัปเดต

มีกรอบที่จะจัดการกับชนิดของสิ่งนี้เช่นไมโครซอฟท์ซิงค์ Framework


เฟรมเวิร์กการซิงค์ยังมีชีวิตอยู่
Sadaquat

7

ฉันเดิมพันว่าคุณอย่างแน่นอนโดยไม่มีคำถามไม่สามารถมีความสมบูรณ์ของการอ้างอิงระหว่างสอง ผู้ใช้ของคุณคาดหวังว่าแอปพลิเคชันมือถือจะทำงานเมื่อถูกตัดการเชื่อมต่อหรือไม่

มีสองวิธีปฏิบัตินี้:

หนึ่งคือการสร้างบันทึก "ชั่วคราว" บนไคลเอนต์และจากนั้นเมื่อคุณซิงค์พวกเขาไปยังเซิร์ฟเวอร์มีระบบกลางกำหนด ID ลูกค้าสามารถอัปเดตระเบียนท้องถิ่นเพื่อแสดงว่า

อีกวิธีหนึ่งคือคุณแจกจ่ายการสร้าง ID ในลักษณะที่ (โดยปกติน่าจะเป็น) อนุญาตให้ลูกค้าสร้าง ID โดยไม่มีการชนกัน

สำหรับสิ่งนั้นไปที่ UUIDs - v4 นั้นไม่น่าจะเกิดการชนได้

มิฉะนั้นให้พิจารณาบางสิ่งที่ทำให้รหัสอุปกรณ์เคลื่อนที่ที่ไม่ซ้ำกันในรหัสบันทึก ดังนั้นรหัสระเบียนของคุณอาจเป็น${imei}-${local sequence number}หรือบางอย่างที่ IMEI รับรองว่าไม่เหมือนใครและหมายเลขลำดับในเครื่องเป็นเพียง ID ฐานข้อมูลตามลำดับปกติ


2

นอกเหนือจากคำตอบของ Daniel Pittmanความเป็นไปได้อย่างหนึ่งคือเซิร์ฟเวอร์จะกำหนดรหัสลูกค้าที่ไม่ซ้ำกันให้ลูกค้าแต่ละรายและทำให้รหัสลูกค้าเป็นส่วนหนึ่งของคีย์หลัก


0

ฉันมีปัญหาเดียวกันกับโครงการที่ฉันทำงานอยู่การแก้ปัญหาในกรณีของฉันคือการสร้างเขตข้อมูล nullable พิเศษในตารางท้องถิ่นชื่อ remote_id เมื่อซิงโครไนซ์เร็กคอร์ดจากโลคัลฐานข้อมูลรีโมตหาก remote_id เป็นโมฆะหมายความว่าแถวนี้ไม่เคยถูกซิงโครไนซ์และต้องการส่งคืน id เฉพาะที่ตรงกับ id แถวรีโมต

Local Table            Remote Table

_id (used locally)
remote_id ------------- id
name      ------------- name

ในแอปพลิเคชันไคลเอนต์ฉันเชื่อมโยงตารางโดยฟิลด์ _id จากระยะไกลฉันใช้ฟิลด์รหัสระยะไกลเพื่อดึงข้อมูลเข้าร่วม ฯลฯ

ตัวอย่างในพื้นที่:

Local Client Table       Local ClientType Table      Local ClientType
                         _id
                         remote_id  
_id -------------------- client_id
remote_id                client_type_id -------------- _id
                                                      remote_id
name                    name                          name

ตัวอย่างจากระยะไกล:

Remote Client Table      Remote ClientType Table      Remote ClientType
id -------------------- client_id
                        client_type_id -------------- id
name                    name                          name

สถานการณ์นี้และไม่มีเหตุผลใด ๆ ในรหัสจะทำให้เกิดความล้มเหลวของข้อมูลเนื่องจากตาราง client_type อาจไม่ตรงกับรหัสจริงในตารางท้องถิ่นหรือตารางระยะไกลดังนั้นเมื่อใดก็ตามที่สร้าง remote_id มันจะส่งสัญญาณไปยังแอพพลิเคชันของลูกค้า ขอให้อัปเดตฟิลด์ _id ท้องถิ่นนี่เป็นการเรียกทริกเกอร์ที่สร้างไว้ก่อนหน้านี้ใน sqlite เพื่ออัปเดตตารางที่ได้รับผลกระทบ http://www.sqlite.org/lang_createtrigger.html

1- remote_id ถูกสร้างขึ้นในเซิร์ฟเวอร์

2- ส่งคืนสัญญาณให้กับลูกค้า

3- ไคลเอนต์อัพเดทฟิลด์ _id ของมันและยิงทริกเกอร์ที่อัพเดตตารางท้องถิ่นที่เข้าร่วมท้องถิ่น _id

แน่นอนฉันใช้ฟิลด์ last_updated เพื่อช่วยในการซิงโครไนซ์และเพื่อหลีกเลี่ยงการซิงค์ซ้ำ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.