서로 다른 두 데이터베이스간에 데이터를 동기화하는 가장 좋은 방법


24

완전히 다른 구조를 가진 두 개의 큰 데이터베이스간에 데이터 동기화를 구현해야합니다. 기본적으로 첫 번째 데이터베이스의 다른 테이블에있는 제품에 대한 일부 데이터를 가져 와서 두 번째 데이터베이스의 다른 테이블에 대해 다시 정렬해야합니다.

처음으로 제품을 만드는 것은 그리 복잡하지 않습니다. 그러나 각 제품에 대한 일부 데이터 (모든 데이터가 아님)를 업데이트하는 방법을 찾고 있습니다.

분명히, 이것을 까다롭게 만드는 몇 가지 문제가 있습니다.

  • 소스 데이터베이스와 별도로 선택 쿼리를 수행하는 것은 허용되지 않습니다.
  • 대상 데이터베이스에서 일반적인 쿼리 (선택, 업데이트, 삽입, 작성)를 수행 할 수 있지만 기존 구조 / 테이블을 수정할 수 없습니다.
  • 대상과 소스 DB는 완전히 다른 구조를 가지고 있으므로 테이블이 전혀 같지 않으므로 데이터를 실제로 다시 정렬해야하므로 테이블을 비교할 수 없습니다.
  • 대상 데이터베이스는 MySQL 서버를 사용합니다. 소스는 DB2 일 수 있습니다.
  • "업데이트 된 시간"필드는 어디에도 없습니다.

따라서 전체 프로세스는 단일 Python (이상적으로) 스크립트로 수행해야합니다.

대상 데이터베이스에서 업데이트 할 필드를 기반으로 각 제품에 대한 해시를 만드는 것에 대해 생각합니다 .md5 (코드 + 설명 + 공급 업체 + 약 10 개의 다른 필드). 동일한 데이터를 기반으로하는 새로운 해시가 소스 데이터베이스에서 매일 생성됩니다. 성능을 위해 모든 해시를 단일 테이블 (항목 코드, current_hash, old_hash)에 저장합니다. 그런 다음 새 해시가 이전 해시와 다른 경우 제품을 비교하고 업데이트하십시오.

약 500,000 개의 제품이 있으므로 성능이 약간 걱정됩니다.

가는 것이 좋은 방법입니까?


2
그들은 당신도 그것을 눈가리개하기를 원합니까? 그건 지금 내 문제 야 ...
Captain Hypertext

1
@Now, 어땠어? 당신이 지금 제안 할 수있는 조언이 있습니까?
Edwin Evans

4
@ EdwinEvans 기본적으로 나는 첫 번째 아이디어를 유지했지만 특히 내가 가진 제약 때문에. 내 스크립트는 모든 항목의 주요 데이터를 기반으로 md5 해시를 만듭니다. 그런 다음 이전 해시와 비교합니다. 해시가 다르면 항목에 대한 모든 데이터를로드하고 모든 것을 업데이트합니다. 이것이 최선의 방법인지 확실하지 않지만 밤에 실행되며 공연은 괜찮습니다.
Neow

답변:


9

이것은 내가하고있는 일이나 지난 몇 년 동안의 삶이며, 직감은 소스 데이터베이스에서 500,000 개의 항목을 읽고 대상에서 동기화하는 데 생각하고 생각하는 데 많은 시간이 걸리지 않는다는 것입니다. "키"필드를 읽고 MD5 해시를 계산하고 변경되지 않은 항목의 동기화를 피하기 위해 테이블과 교차 점검하는 데 걸리는 시간이 너무 오래 걸리지 않고 더 오래 실행될 수도 있습니다. 나는 단순히 모든 것을 읽고 모든 것을 업데이트 할 것입니다. 그 결과 런타임이 너무 길면 ETL을 멀티 스레드로 만들어 런타임을 압축합니다. 각 스레드는 테이블 세그먼트에서만 작동하지만 병렬로 작동합니다.

대상 데이터베이스에 기본 키 인덱스 또는 고유 인덱스가 있는지 확인하는 것이 중요합니다. 그렇지 않으면 각 업데이트 / 삽입이 전체 테이블을 잠글 수 있습니다. 다중 스레드 방식을 사용하는 경우에는 좋지 않지만 작업이 대상 DB 테이블을 잠그고 해당 DB를 기반으로하는 애플리케이션을 방해 할 수 있기 때문에 단일 스레드 상태 인 경우에도 중요합니다.

소스 DB가 "DB2 일 수 있습니다"라고 말합니다. "may"라고 말하면 DB가 여전히 설계 / 계획되고있는 것입니까? DB2 9 이상에는 최종 갱신 시간에 대한 추적 기능이 내장되어 있으며, 특정 시점 이후 변경된 항목 만 조회하고 가져 오는 기능이 있습니다. 아마도 이것이 DB가 마지막 업데이트 시간을 나타내는 열을 갖지 않도록 설계된 이유 일 것입니다. 예 :

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

위 쿼리에 대한 타임 스탬프 컷오프는 동기화가 마지막으로 실행 된 타임 스탬프입니다.

이 경우 문제를 해결해야합니다. 그러나 솔루션은 DB2에 매우 밀접하게 연결되어 있으며 나중에 다른 DB 플랫폼으로 이동하여 동기화 작업을 다시 방문하지 않아도 될 수 있습니다. 따라서 모든 올바른 사람들이 귀하의 제품이 DB2에 남아있는 것에 의존 할 것임을 알도록하거나, 마이그레이션을 계획하는 경우 "마지막으로 변경된 타임 스탬프"열을 갖도록 DB를 재구성하는 것이 포함됩니다. 해당 필드를 채우려면 앱 수준에서 필요한 변경 사항


mysql에 대한 비슷한 솔루션이 있습니까?
Fardin Behboudi

5

데이터 동기화는 어떤 종류의 델타 식별자 또는 플래그를 기반으로 수행 할 수 있다면 훨씬 더 좋고 빠릅니다. 기본적으로 대상 db 데이터 행이 소스 db와 동기화되지 않은 경우에만 업데이트해야합니다.

SQL Server db에서는 Checksum fn 의 도움을 받아 델타 기반 식별자를 작성할 수도 있습니다.

이 SQL 논리를 실행하려면 밤낮의 특정 시간에 호출 되는 SQL 기반 작업 을 개발해야합니다 . DB 사용량이 매우 적을 때 야간 SQL 작업으로 실행하는 것이 좋습니다. 소스와 대상 DB 레코드의 델타가 일치하지 않으면 해당 레코드 만 가져 오십시오. 그러나 단점은 매번 소스 데이터 행의 체크섬을 계산 한 다음 대상 데이터와 비교하는 것입니다.

소스 db 테이블에 "LastModifiedDate"와 같은 열이 있으면 체크섬 방식을 건너 뛸 수 있습니다. 이런 식으로 평가는 날짜 기반 열에서 실행되며 체크섬 방식에 비해 시간이 덜 걸립니다.


감사하지만 솔루션이 작동하는지 잘 모르겠습니다. "문제"부분에서 내 수정 사항을 확인하세요.
Neow

소스 데이터베이스에 업데이트 된 시간 필드가 없으므로 체크섬 또는 해시를 기반으로 규정 된 데이터 행을 가져와야합니다.
Karan

소스는 db2이므로 데이터를 어떻게 가져 오려고합니까? 일부 웹 서비스 또는 API를 통해.
Karan

odbc 드라이버를 사용하여 dsn을 설정했습니다. pyodbc for Python을 사용하여 쿼리를 연결하고 수행 할 수 있습니다.
Neow

PyODBC라는 도구를 사용하여 원격 DB에 쿼리를 수행 할 수 있으므로 좋습니다. 한 가지 더 할 수 있습니다. 점검이나 검증없이 대상 DB의 새로운 "스테이징 테이블"에있는 그대로 동일한 형식으로 제품 데이터를 가져올 수 있습니다. 이렇게하면 스테이지 테이블 아래의 대상 DB에서 단일 샷으로 라이브 데이터를 얻을 수 있습니다. 그런 다음 두 번째 단계에서 체크섬 작업을 수행하고 대상 트랜잭션 테이블 데이터를 업데이트 할 수 있습니다. 이로 인해 소스 DB 데이터에 대한 해시 또는 체크섬 평가가 실시간으로 방지됩니다.
Karan

1

해시를 사용하는 것이 좋습니다. 이 경우 보안이 목표가 아니기 때문에 빠른 해시 함수를 선택하십시오 (md5는 좋습니다).

해시 계산을 여러 스레드 / 프로세스로 분할하지 않으면 실제로 데이터베이스에 현재 해시 값을 저장할 필요가 없습니다. 프로세스가 단일 스크립트 인 경우 현재 해시를 메모리에 저장하고 새 데이터베이스에서 데이터를 업데이트 한 후 기존 해시로 데이터베이스에 씁니다.


-1

필요할 때마다 특정 시간에 실행되는 Windows 서비스를 작성해야하며 소스 데이터베이스에서 변경 사항을 찾아서 대상 데이터베이스에 변경 사항을 삽입해야합니다.


창문에만 제안 -1 (실제로 downvote하지 않았지만;). 소프트웨어를 개발할 때 특정 아키텍처에 의존하지 마십시오. 단지 몇 사람 만이 귀하의 물건을 사용할 수 있음을 의미합니다. 유일한 상수는 변화하고 그래서 자신과 사용자를위한 유지하기 위해 쉽게 물건을 만드는 정도에 대한 특정 플랫폼에 의존하지 않는 더 나은
pythonian29033

1
@manish kumar "원본 데이터베이스의 변경 사항을 찾을 것"은 가장 어려운 부분입니다!
Narvalex
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.