วิธีที่ดีที่สุดในการซิงโครไนซ์ข้อมูลระหว่างสองฐานข้อมูลที่แตกต่างกัน


24

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

การสร้างผลิตภัณฑ์ของฉันในครั้งแรกนั้นไม่ซับซ้อนมาก แต่ฉันกำลังมองหาวิธีการอัปเดตข้อมูลเฉพาะบางอย่าง - ไม่ใช่ข้อมูลทั้งหมด - เกี่ยวกับแต่ละผลิตภัณฑ์

เห็นได้ชัดว่ามีบางประเด็นที่ทำให้เรื่องนี้ยุ่งยาก

  • ฉันไม่ได้รับอนุญาตให้ทำสิ่งใดในฐานข้อมูลต้นฉบับนอกเหนือจากแบบสอบถามแบบใช้เลือกข้อมูล
  • บนฐานข้อมูลเป้าหมายฉันสามารถทำการสืบค้นตามปกติ (เลือกอัปเดตแทรกสร้าง) แต่ฉันไม่สามารถแก้ไขโครงสร้าง / ตารางที่มีอยู่ได้
  • Target และ source db มีโครงสร้างที่แตกต่างกันโดยสิ้นเชิงตารางไม่เหมือนกันเลยดังนั้นข้อมูลจะต้องถูกจัดเรียงใหม่จริง ๆ การเปรียบเทียบตารางจะไม่ทำงาน
  • ฐานข้อมูลเป้าหมายใช้เซิร์ฟเวอร์ MySQL - ซอร์สอาจเป็น DB2
  • ไม่มีฟิลด์ "เวลาที่อัปเดต" ที่ใดก็ได้

ดังนั้นกระบวนการทั้งหมดจะต้องทำในสคริปต์ Python (นึกคิด) เดียว

ฉันคิดเกี่ยวกับการสร้างแฮชสำหรับแต่ละผลิตภัณฑ์โดยอิงตามฟิลด์เพื่ออัปเดตในฐานข้อมูลเป้าหมาย: md5 (รหัส + คำอธิบาย + ผู้จำหน่าย + ประมาณ 10 สาขาอื่น ๆ ) แฮชใหม่ที่ใช้ข้อมูลเดียวกันจะถูกสร้างขึ้นทุกวันจากฐานข้อมูลต้นทาง ฉันจะเก็บแฮชทั้งหมดไว้ในตารางเดียว (รหัสรายการ, current_hash, old_hash) เพื่อการแสดง จากนั้นเปรียบเทียบและอัปเดตผลิตภัณฑ์หากแฮชใหม่นั้นแตกต่างจากของเก่า

มีสินค้าประมาณ 500,000 รายการดังนั้นฉันกังวลเล็กน้อยเกี่ยวกับการแสดง

มันเป็นวิธีที่ดีที่จะไป?


2
พวกเขาต้องการให้คุณปิดตาด้วยหรือไม่ นั่นเป็นปัญหาของฉันในตอนนี้ ...
กัปตันไฮเปอร์เท็กซ์

1
@ ใหม่มันเป็นยังไงบ้าง? คำแนะนำใด ๆ ที่คุณสามารถนำเสนอในขณะนี้?
Edwin Evans

4
@EdwinEvans โดยทั่วไปฉันอยู่กับความคิดแรกของฉัน แต่โดยเฉพาะอย่างยิ่งเนื่องจากข้อ จำกัด ที่ฉันมี สคริปต์ของฉันสร้าง md5 hashes โดยใช้ข้อมูลสำคัญสำหรับทุกรายการ จากนั้นฉันเปรียบเทียบกับแฮชก่อนหน้านี้ หากแฮชแตกต่างกันจะโหลดข้อมูลทั้งหมดสำหรับรายการและอัปเดตทุกอย่าง ไม่แน่ใจว่านี่เป็นวิธีที่ดีที่สุดหรือเปล่า แต่มันทำงานตอนกลางคืนและมีการแสดงที่ดี
Neow

คำตอบ:


9

นี่เป็นสิ่งที่ฉันทำหรือใช้ชีวิตในช่วงไม่กี่ปีที่ผ่านมาและสัญชาตญาณของฉันก็คือเวลาที่อ่าน 500,000 รายการจากฐานข้อมูลต้นทางและการซิงค์ในปลายทางจะไม่ใช้เวลามากเท่าที่คิดและ เวลาในการอ่านฟิลด์ "คีย์" คำนวณแฮช MD5 และการตรวจสอบแบบข้ามกับตารางของคุณเพื่อหลีกเลี่ยงการซิงค์รายการที่ไม่ได้เปลี่ยนจะไม่สิ้นสุดประหยัดเวลามากเกินไปและอาจทำงานได้นานขึ้น ฉันแค่อ่านทั้งหมดและอัปเดตทั้งหมด หากผลลัพธ์นั้นอยู่ในรันไทม์ที่ยาวเกินไปฉันจะบีบอัดรันไทม์ด้วยการทำให้ ETL muti-threaded โดยที่แต่ละเธรดจะทำงานบนเซ็กเมนต์ของตาราง แต่ทำงานในแบบคู่ขนาน

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

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

SELECT * FROM T1 WHERE ROW CHANGE TIMESTAMP FOR TAB t1 > current timestamp - 1 hours;

การตัดเวลาประทับสำหรับการสืบค้นด้านบนจะเป็นการประทับเวลาครั้งสุดท้ายที่การซิงค์ของคุณทำงาน

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


มีวิธีแก้ไขปัญหาที่คล้ายกันสำหรับ mysql ด้วยหรือไม่
Fardin Behboudi

5

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

ใน SQL เซิร์ฟเวอร์ db คุณสามารถใช้Checksum fnเพื่อสร้างตัวระบุที่ใช้เดลต้า

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

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


ขอบคุณ แต่ฉันไม่แน่ใจว่าวิธีการแก้ปัญหาของคุณสามารถใช้งานได้ - ดูการแก้ไขของฉันในส่วน "ปัญหา"
Neow

เนื่องจากไม่มีเขตเวลาที่อัปเดตในฐานข้อมูลต้นทางเราจึงเหลือที่จะดึงแถวข้อมูลที่มีคุณสมบัติตามการตรวจสอบหรือการแฮช
Karan

เนื่องจากแหล่งที่มาของคุณคือ db2 คุณตั้งใจจะดึงข้อมูลจากมันได้อย่างไร? ผ่านทางเว็บเซอร์บางส่วนหรือ API ..
คารา

ตั้งค่า dsn แล้วโดยใช้ไดรเวอร์ odbc ฉันสามารถเชื่อมต่อและทำการสืบค้นด้วย pyodbc สำหรับ Python
Neow

เอาล่ะนี่เป็นสิ่งที่ดีเนื่องจากคุณสามารถทำการสืบค้นโดยใช้เครื่องมือที่เรียกว่า PyODBC ในฐานข้อมูลระยะไกล คุณสามารถทำอีกสิ่งหนึ่ง คุณสามารถดึงข้อมูลผลิตภัณฑ์ได้โดยตรงในรูปแบบเดียวกับที่อยู่ใน "ตาราง Staging" ใหม่ในฐานข้อมูลเป้าหมายของคุณโดยไม่ต้องตรวจสอบหรือตรวจสอบความถูกต้อง วิธีนี้คุณจะได้รับข้อมูลสดในนัดเดียวในฐานข้อมูลเป้าหมายของคุณภายใต้ตารางเวที จากนั้นในขั้นตอนที่สองคุณสามารถดำเนินการตรวจสอบและอัปเดตข้อมูลตารางธุรกรรมที่เป็นเป้าหมายได้ สิ่งนี้จะป้องกันการแฮชหรือการประเมินผลการตรวจสอบด้วยข้อมูล db แหล่งที่มาในเวลาจริง
Karan

1

การใช้แฮชเป็นความคิดที่ดี เนื่องจากความปลอดภัยไม่ใช่เป้าหมายในกรณีนี้ให้เลือกฟังก์ชันแฮชที่รวดเร็ว (md5 ไม่เป็นไร)

นอกจากว่าคุณวางแผนที่จะแบ่งการคำนวณแฮชในหลายเธรด / กระบวนการคุณไม่จำเป็นต้องเก็บค่าแฮชปัจจุบันในฐานข้อมูล หากกระบวนการของคุณเป็นสคริปต์เดียวคุณจะมีแฮชปัจจุบันในหน่วยความจำและจะเขียนลงในฐานข้อมูลเป็นแฮชเก่าหลังจากคุณอัปเดตข้อมูลในฐานข้อมูลใหม่


-1

คุณควรสร้างบริการ windows ซึ่งจะทำงานในบางครั้ง speficif เมื่อใดก็ตามที่คุณต้องการและมันจะค้นหาการเปลี่ยนแปลงในฐานข้อมูลต้นทางของคุณและแทรกการเปลี่ยนแปลงนั้นในฐานข้อมูลปลายทางของคุณ


-1 (ไม่ได้ลงคะแนนจริงๆ แต่สำหรับ) ข้อเสนอแนะสำหรับ Windows เท่านั้น อย่าพึ่งสถาปัตยกรรมเฉพาะเมื่อพัฒนาซอฟต์แวร์มันหมายความว่ามีเพียงไม่กี่คนที่สามารถใช้สิ่งของของคุณได้ ค่าคงที่เท่านั้นที่มีการเปลี่ยนแปลงและดังนั้นจึงเป็นการดีกว่าที่จะไม่พึ่งพาแพลตฟอร์มเฉพาะใด ๆ ในระดับที่ทำให้สิ่งต่าง ๆ ง่ายต่อการบำรุงรักษาสำหรับตัวคุณเองและสำหรับผู้ใช้
pythonian29033

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