Cara terbaik untuk menyinkronkan data antara dua database yang berbeda

24

Saya harus menerapkan sinkronisasi data antara dua database besar yang memiliki struktur yang sama sekali berbeda. Pada dasarnya, saya perlu menjepret beberapa data tentang produk dalam tabel yang berbeda di database pertama dan mengaturnya kembali untuk tabel lain di database kedua.

Menciptakan produk saya pada saat pertama tidak terlalu rumit. Tetapi saya sedang mencari cara untuk memperbarui beberapa data spesifik - tidak semua data - tentang setiap produk.

Jelas, ada beberapa masalah yang membuat ini rumit.

  • Saya tidak diizinkan melakukan apa pun pada basis data sumber selain kueri pemilihan.
  • Pada database target, saya dapat melakukan query biasa (pilih, perbarui, sisipkan, buat) tetapi saya tidak bisa memodifikasi struktur / tabel yang ada.
  • Target dan sumber db memiliki struktur yang sama sekali berbeda, tabel tidak sama sekali, oleh karena itu data harus disusun ulang - tabel perbandingan tidak akan berfungsi.
  • Basis data target menggunakan server MySQL - sumber mungkin DB2.
  • Tidak ada bidang "waktu yang diperbarui" di mana pun.

Jadi seluruh proses perlu dilakukan dalam satu skrip Python (idealnya).

Saya berpikir tentang membuat hash untuk setiap produk, berdasarkan bidang untuk memperbarui dalam database target: md5 (kode + deskripsi + pemasok + sekitar 10 bidang lainnya). Hash baru berdasarkan data yang sama akan dibuat setiap hari dari basis data sumber. Saya akan menyimpan semua hash dalam satu tabel (kode item, current_hash, old_hash) untuk tujuan pertunjukan. Kemudian bandingkan dan perbarui produk jika hash baru berbeda dari yang lama.

Ada sekitar 500.000 produk jadi saya agak khawatir tentang penampilan.

Apakah ini cara yang baik untuk pergi?

Neow
sumber
2
Apakah mereka ingin Anda melakukannya dengan mata tertutup juga? Itu masalah saya sekarang ...
Kapten Hypertext
1
@ Sekarang, Bagaimana hasilnya? Adakah saran yang bisa Anda tawarkan sekarang?
Edwin Evans
4
@ EdwinEvans pada dasarnya saya tetap dengan ide pertama saya, tetapi terutama karena kendala yang saya miliki. Script saya membuat hash md5 berdasarkan data kunci untuk semua item. Lalu saya membandingkan dengan hash sebelumnya. Jika hash berbeda, maka memuat semua data untuk item dan memperbarui semuanya. Tidak yakin apakah ini cara terbaik, tetapi berjalan pada malam hari dan penampilannya bagus.
Sekitar

Jawaban:

9

Ini cukup banyak apa yang telah saya lakukan atau hidup beberapa tahun terakhir, dan insting saya adalah bahwa waktu untuk membaca 500.000 item dari sumber database dan sinkronisasi di tujuan tidak akan mengambil banyak waktu seperti yang mungkin dipikirkan orang dan waktu yang dibutuhkan untuk membaca bidang "kunci", menghitung hash MD5, dan mengecek silang dengan meja Anda untuk menghindari sinkronisasi item yang tidak berubah tidak akan menghemat banyak waktu dan bahkan mungkin berjalan lebih lama. Saya cukup membaca semua dan memperbarui semua. Jika itu menghasilkan runtime yang terlalu panjang, maka saya akan memampatkan runtime dengan membuat ETL muti-threaded, dengan masing-masing thread hanya beroperasi pada segmen tabel tetapi bekerja secara paralel.

Penting untuk memastikan bahwa basis data tujuan Anda memiliki indeks kunci utama atau indeks unik. Jika tidak, setiap pembaruan / sisipan Anda dapat mengunci seluruh tabel. Ini akan menjadi buruk jika Anda mengambil pendekatan multithreaded, tetapi penting bahkan jika Anda tetap single-threaded karena pekerjaan Anda bisa mengunci tabel DB tujuan dan mengganggu aplikasi yang naik di atas DB itu.

Anda mengatakan sumber DB "mungkin DB2". Ketika Anda mengatakan "mungkin" itu menyiratkan bahwa DB masih dirancang / direncanakan? DB2 9 atau di atasnya memang memiliki pelacakan built-in dari waktu pembaruan terakhir, dan kemampuan untuk query dan mendapatkan kembali hanya item yang telah berubah sejak titik waktu. Mungkin ini sebabnya DB dirancang untuk tidak memiliki kolom yang menunjukkan waktu terakhir diperbarui, misalnya:

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

Batas waktu stempel untuk kueri di atas akan menjadi stempel waktu terakhir yang dijalankan oleh sinkronisasi Anda.

Jika ini masalahnya, itu akan menyelesaikan masalah Anda. Tetapi, solusi Anda pada akhirnya terikat erat dengan DB2 dan di masa depan mereka mungkin ingin pindah ke platform DB lain dan berharap pekerjaan sinkronisasi Anda tidak perlu dikunjungi kembali. Jadi, penting untuk memastikan semua orang yang tepat tahu bahwa produk Anda akan bergantung pada sisa pada DB2, atau jika mereka berencana untuk bermigrasi bahwa migrasi akan mencakup restrukturisasi DB untuk memiliki kolom "stempel waktu perubahan terakhir", dan membuat apa pun perubahan yang diperlukan di tingkat aplikasi untuk mengisi bidang itu.

Thomas Carlisle
sumber
apakah ada solusi serupa untuk mysql juga?
Fardin Behboudi
5

Sinkronisasi data akan jauh lebih baik dan lebih cepat, jika dapat dilakukan atas dasar semacam pengidentifikasi atau tanda delta. Pada dasarnya, Anda harus memperbarui baris data target db hanya ketika tidak sinkron dengan sumber db.

Dalam SQL server db, Anda dapat mengambil bantuan Checksum fn juga untuk membangun pengidentifikasi berbasis delta.

Anda harus mengembangkan pekerjaan berbasis SQL untuk dipanggil pada waktu tertentu siang atau malam hari untuk mendapatkan logika sql ini dipecat. Lebih baik menjalankannya sebagai pekerjaan SQL malam, ketika penggunaan db sangat rendah. Jika delta sumber dan catatan target db tidak cocok, maka tarik catatan itu saja. Tetapi downside akan menghitung checksum dari baris data sumber setiap kali dan kemudian membandingkannya dengan data target.

Jika Anda memiliki kolom seperti "LastModifiedDate" di tabel sumber db, maka Anda dapat melewati pendekatan checksum. Dengan cara ini, evaluasi Anda akan dilaksanakan pada kolom berdasarkan tanggal dan membutuhkan waktu lebih sedikit dibandingkan dengan pendekatan checksum.

Karan
sumber
Terima kasih tetapi saya tidak yakin solusi Anda dapat bekerja - lihat hasil edit saya di bagian "masalah".
Sekarang
Karena tidak ada bidang waktu yang diperbarui dalam basis data sumber, maka kita dibiarkan menarik baris data yang berkualitas berdasarkan pada checksum atau hash.
Karan
Karena sumber Anda adalah db2. Bagaimana Anda bermaksud mengambil data dari dalamnya? melalui beberapa layanan web atau API ..
Karan
Dsn telah diatur menggunakan driver odbc. Saya bisa terhubung dan melakukan query menggunakan pyodbc untuk Python.
Sekarang
Baiklah ini bagus, karena Anda dapat melakukan kueri menggunakan alat yang disebut PyODBC ke DB jarak jauh. Anda dapat melakukan satu hal lagi. Anda dapat menarik data produk langsung dalam format yang sama seperti itu ke "tabel Staging" baru di DB target Anda tanpa pemeriksaan atau validasi. Dengan cara ini Anda akan mendapatkan data langsung dalam satu tembakan di target db Anda di bawah tabel panggung. Kemudian di langkah kedua, Anda dapat melakukan operasi checksum dan memperbarui data tabel target transaksi. Ini akan mencegah hash atau evaluasi checksum dengan sumber data db secara real time.
Karan
1

Menggunakan hash adalah ide yang bagus. Karena keamanan bukan tujuan dalam kasus ini, pilih fungsi hash yang cepat (md5 baik-baik saja).

Kecuali jika Anda berencana untuk membagi perhitungan hash di beberapa utas / proses, Anda tidak benar-benar perlu menyimpan nilai hash saat ini di database. Jika proses Anda adalah skrip tunggal, Anda hanya akan memiliki hash saat ini dalam memori, dan akan menuliskannya ke database sebagai hash lama setelah Anda memperbarui data dalam database baru.

Kent A.
sumber
-1

Anda harus membuat layanan windows yang akan berjalan pada waktu tertentu kapan pun Anda mau dan itu akan menemukan perubahan dalam basis data sumber Anda dan menyisipkan perubahan itu dalam basis data tujuan Anda.

manish kumar
sumber
-1 (tidak benar-benar downvote, tetapi;) hanya saran untuk windows. jangan mengandalkan arsitektur tertentu ketika mengembangkan perangkat lunak itu hanya berarti bahwa hanya sedikit orang yang dapat menggunakan barang-barang Anda. satu-satunya yang konstan adalah perubahan dan oleh karena itu lebih baik untuk tidak bergantung pada platform tertentu sejauh yang membuat hal-hal mudah dipertahankan untuk diri sendiri dan untuk pengguna
pythonian29033
1
@manish kumar bagian "itu akan menemukan perubahan dalam database sumber Anda" adalah yang paling sulit!
Narvalex