Cách tốt nhất để đồng bộ hóa dữ liệu giữa hai cơ sở dữ liệu khác nhau


24

Tôi phải thực hiện đồng bộ hóa dữ liệu giữa hai cơ sở dữ liệu lớn có cấu trúc hoàn toàn khác nhau. Về cơ bản, tôi cần phải grap một số dữ liệu về các sản phẩm trong các bảng khác nhau trong cơ sở dữ liệu đầu tiên và sắp xếp lại chúng cho các bảng khác trong cơ sở dữ liệu thứ hai.

Tạo sản phẩm của tôi lần đầu tiên không phức tạp lắm. Nhưng tôi đang tìm cách cập nhật một số dữ liệu cụ thể - không phải tất cả dữ liệu - về từng sản phẩm.

Rõ ràng, có một vài vấn đề làm cho điều này khó khăn.

  • Tôi không được phép làm bất cứ điều gì trên cơ sở dữ liệu nguồn ngoài các truy vấn chọn.
  • Trên cơ sở dữ liệu đích, tôi có thể thực hiện các truy vấn thông thường (chọn, cập nhật, chèn, tạo) nhưng tôi không thể sửa đổi cấu trúc / bảng hiện có.
  • Db mục tiêu và nguồn có cấu trúc hoàn toàn khác nhau, các bảng hoàn toàn không giống nhau, do đó dữ liệu thực sự phải được sắp xếp lại - so sánh các bảng sẽ không hoạt động.
  • Cơ sở dữ liệu đích sử dụng máy chủ MySQL - nguồn có thể là DB2.
  • Không có trường "cập nhật thời gian" ở bất cứ đâu.

Vì vậy, toàn bộ quá trình cần phải được thực hiện trong một tập lệnh Python (lý tưởng).

Tôi nghĩ về việc tạo một hàm băm cho mỗi sản phẩm, dựa trên các trường để cập nhật trong cơ sở dữ liệu đích: md5 (mã + mô tả + nhà cung cấp + khoảng 10 trường khác). Một hàm băm mới dựa trên cùng một dữ liệu sẽ được tạo ra hàng ngày từ cơ sở dữ liệu nguồn. Tôi sẽ lưu trữ tất cả các giá trị băm trong một bảng duy nhất (mã mục, current_hash, old_hash) cho mục đích biểu diễn. Sau đó so sánh và cập nhật sản phẩm nếu hàm băm mới khác với băm cũ.

Có khoảng 500 000 sản phẩm nên tôi hơi lo lắng về hiệu suất.

Đó có phải là cách tốt để đi?


2
Họ có muốn bạn làm điều đó bịt mắt quá không? Đó là vấn đề của tôi ngay bây giờ ...
Thuyền trưởng Hypertext

1
@Neow, nó đã đi như thế nào? Bất kỳ lời khuyên bạn có thể cung cấp bây giờ?
Edwin Evans

4
@EdwinEvans về cơ bản tôi đã ở lại với ý tưởng đầu tiên của mình, nhưng đặc biệt là do những hạn chế mà tôi có. Kịch bản của tôi tạo ra băm md5 dựa trên dữ liệu chính cho tất cả các mục. Sau đó, tôi so sánh với các băm trước đó. Nếu các giá trị băm khác nhau, thì nó sẽ tải tất cả dữ liệu cho mục đó và cập nhật mọi thứ. Không chắc đây có phải là cách tốt nhất không, nhưng nó chạy vào ban đêm và màn trình diễn rất tuyệt.
Neow

Câu trả lời:


9

Đây là khá nhiều những gì tôi đã làm hoặc sống trong vài năm qua và bản năng ruột của tôi là thời gian để đọc 500.000 mục từ cơ sở dữ liệu nguồn và đồng bộ hóa ở đích sẽ không mất nhiều thời gian như mọi người nghĩ và mất nhiều thời gian để đọc các trường "khóa", tính toán băm MD5 và kiểm tra chéo với bảng của bạn để tránh đồng bộ hóa các mục không thay đổi sẽ không tiết kiệm quá nhiều thời gian và thậm chí có thể chạy lâu hơn. Tôi chỉ đơn giản là đọc tất cả và cập nhật tất cả. Nếu điều đó dẫn đến thời gian chạy quá dài, thì tôi sẽ nén thời gian chạy bằng cách tạo luồng đột biến ETL, với mỗi luồng chỉ hoạt động trên một đoạn của bảng nhưng hoạt động song song.

Điều quan trọng là phải đảm bảo rằng cơ sở dữ liệu đích của bạn có chỉ mục khóa chính hoặc chỉ mục duy nhất. Mặt khác, mỗi bản cập nhật / chèn của bạn có thể khóa toàn bộ bảng. Điều này sẽ rất tệ nếu bạn đang thực hiện phương pháp đa luồng, nhưng quan trọng ngay cả khi bạn vẫn duy trì một luồng vì công việc của bạn có thể khóa bảng DB đích và can thiệp vào ứng dụng chạy trên DB đó.

Bạn nói DB nguồn "có thể là DB2". Khi bạn nói "có thể", điều đó có nghĩa là DB vẫn đang được thiết kế / lên kế hoạch? DB2 9 trở lên không có theo dõi tích hợp về thời gian cập nhật mới nhất và khả năng truy vấn và chỉ lấy lại các mục đã thay đổi kể từ thời điểm đó. Có lẽ đây là lý do tại sao DB được thiết kế để không có cột cho biết thời gian cập nhật cuối cùng, ví dụ:

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

Ngưỡng dấu thời gian cho truy vấn trên sẽ là dấu thời gian cuối cùng mà đồng bộ hóa của bạn chạy.

Nếu đây là trường hợp, điều đó sẽ giải quyết vấn đề của bạn. Tuy nhiên, giải pháp của bạn cuối cùng sẽ bị ràng buộc rất chặt chẽ với DB2 và trong tương lai họ có thể muốn chuyển sang nền tảng DB khác và hy vọng công việc đồng bộ hóa của bạn sẽ không cần phải truy cập lại. Vì vậy, điều quan trọng là phải đảm bảo tất cả những người phù hợp biết rằng sản phẩm của bạn sẽ phụ thuộc vào phần còn lại của DB2 hoặc nếu họ có kế hoạch di chuyển di chuyển đó sẽ bao gồm cơ cấu lại DB để có cột "dấu thời gian thay đổi cuối cùng" và thực hiện bất cứ điều gì thay đổi cần thiết ở cấp ứng dụng để điền vào trường đó.


Có bất kỳ giải pháp tương tự cho mysql quá?
Fardin Behboudi

5

Đồng bộ hóa dữ liệu sẽ tốt hơn và nhanh hơn nhiều, nếu nó có thể được thực hiện trên cơ sở một số loại định danh delta hoặc cờ. Về cơ bản, bạn chỉ nên cập nhật các hàng dữ liệu db đích khi nó không đồng bộ với db nguồn.

Trong db máy chủ SQL, bạn cũng có thể nhờ sự trợ giúp của Checksum fn để xây dựng mã định danh dựa trên delta.

Bạn nên phát triển một công việc dựa trên SQL để được gọi vào một thời điểm nhất định trong ngày hoặc đêm để loại bỏ logic sql này. Tốt hơn là chạy nó như một công việc SQL hàng đêm, khi mức sử dụng db rất thấp. Nếu delta của nguồn và các bản ghi db đích không khớp nhau, thì chỉ kéo các bản ghi đó. Nhưng nhược điểm sẽ là tính toán tổng kiểm tra của các hàng dữ liệu nguồn mỗi lần và sau đó so sánh nó với dữ liệu đích.

Nếu bạn có một cột như "LastModifiedDate" trong các bảng db nguồn, thì bạn có thể bỏ qua cách tiếp cận tổng kiểm tra. Bằng cách này, đánh giá của bạn sẽ được thực hiện trên cột dựa trên ngày và mất ít thời gian hơn so với phương pháp tổng kiểm tra.


Cảm ơn nhưng tôi không chắc giải pháp của bạn có thể hoạt động - xem phần chỉnh sửa của tôi trong phần "vấn đề".
Neow

Vì không có trường thời gian cập nhật trong cơ sở dữ liệu nguồn, nên chúng tôi còn lại để kéo các hàng dữ liệu đủ điều kiện dựa trên tổng kiểm tra hoặc hàm băm.
Karan

Vì nguồn của bạn là db2. Làm thế nào để bạn có ý định kéo dữ liệu từ nó? thông qua một số dịch vụ web hoặc API ..
Karan

Một DSN đã được thiết lập bằng trình điều khiển odbc. Tôi có thể kết nối và thực hiện các truy vấn bằng pyodbc cho Python.
Neow

Được rồi, điều này là tốt, vì bạn có thể thực hiện các truy vấn bằng cách sử dụng công cụ có tên PyODBC vào DB từ xa. Bạn có thể làm một điều nữa. Bạn có thể kéo thẳng dữ liệu sản phẩm theo cùng định dạng vào "Bảng phân tầng" mới trong DB mục tiêu của mình mà không cần kiểm tra hay xác nhận. Bằng cách này, bạn sẽ nhận được dữ liệu trực tiếp trong một lần chụp trong db mục tiêu của mình dưới các bảng giai đoạn. Sau đó, trong bước thứ hai, bạn có thể thực hiện các thao tác kiểm tra và cập nhật dữ liệu bảng giao dịch đích. Điều này sẽ ngăn việc băm hoặc đánh giá tổng kiểm tra với dữ liệu db nguồn tại thời điểm thực.
Karan

1

Sử dụng một hàm băm là một ý tưởng tốt. Vì bảo mật không phải là mục tiêu trong trường hợp này, hãy chọn hàm băm nhanh (md5 là tốt).

Trừ khi bạn có kế hoạch phân chia tính toán băm trên nhiều luồng / quy trình, bạn không thực sự cần lưu trữ giá trị băm hiện tại trong cơ sở dữ liệu. Nếu quy trình của bạn là một tập lệnh đơn, bạn sẽ chỉ có hàm băm hiện tại trong bộ nhớ và sẽ ghi nó vào cơ sở dữ liệu dưới dạng hàm băm cũ sau khi bạn đã cập nhật dữ liệu trong cơ sở dữ liệu mới.


-1

bạn nên tạo một dịch vụ windows sẽ chạy vào một số thời điểm bất kỳ khi nào bạn muốn và nó sẽ tìm thấy những thay đổi trong cơ sở dữ liệu nguồn của bạn và chèn những thay đổi đó vào cơ sở dữ liệu đích của bạn.


-1 (không thực sự downvote, nhưng;) chỉ đề xuất cho windows. chúng ta đừng dựa vào bất kỳ kiến ​​trúc cụ thể nào khi phát triển phần mềm, điều đó chỉ có nghĩa là chỉ một vài người có thể sử dụng công cụ của bạn. hằng số duy nhất là thay đổi và vì vậy tốt hơn hết là không nên dựa vào bất kỳ nền tảng cụ thể nào ở mức độ giúp mọi thứ dễ dàng duy trì cho chính bạn và cho người dùng
pythonia29033

1
@manish kumar phần "nó sẽ tìm thấy những thay đổi trong cơ sở dữ liệu nguồn của bạn" là phần khó nhất!
Narvalex
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.