약 8 년 전에 앱용으로 이와 같은 시스템을 구축했으며 앱 사용이 증가함에 따라 발전한 몇 가지 방법을 공유 할 수 있습니다.
모든 장치의 모든 변경 (삽입, 업데이트 또는 삭제)을 "기록"테이블에 기록하여 시작했습니다. 예를 들어 누군가가 "contact"테이블에서 전화 번호를 변경하면 시스템은 contact.phone 필드를 편집하고 action = update, field = phone, record = [contact ID], value = [새 전화 번호]. 그런 다음 장치가 동기화 될 때마다 마지막 동기화 이후 기록 항목을 다운로드하여 로컬 데이터베이스에 적용합니다. 위에서 설명한 "트랜잭션 복제"패턴처럼 들립니다.
한 가지 문제는 다른 장치에서 항목을 만들 수있을 때 ID를 고유하게 유지하는 것입니다. 나는 이것을 시작할 때 UUID에 대해 몰랐기 때문에 자동 증가 ID를 사용하고 중앙 서버에서 실행되는 복잡한 코드를 작성하여 장치에서 업로드 된 새로운 ID를 확인하고 충돌이있는 경우 고유 ID로 변경합니다. 소스 장치가 로컬 데이터베이스에서 ID를 변경하도록 지시하십시오. 새 레코드의 ID를 변경하는 것만 큼 나쁘지는 않지만 연락처 테이블에 새 항목을 만든 다음 이벤트 테이블에 새 관련 항목을 만들면 외래 키도 있습니다. 확인하고 업데이트하십시오.
결국 UUID가 이것을 피할 수 있다는 것을 알았지 만 그때까지 내 데이터베이스가 상당히 커지고 전체 UUID 구현으로 인해 성능 문제가 발생할 것을 두려워했습니다. 따라서 전체 UUID를 사용하는 대신 무작위로 생성 된 8 자의 영숫자 키를 ID로 사용하기 시작했으며 충돌을 처리하기 위해 기존 코드를 그대로 두었습니다. 내 현재 8 문자 키와 UUID의 36 문자 사이에 불필요한 부풀림없이 충돌을 제거 할 수있는 스위트 스팟이 있어야하지만 이미 충돌 해결 코드가 있으므로 실험 해 보는 것이 우선 순위가 아닙니다. .
다음 문제는 히스토리 테이블이 나머지 데이터베이스 전체보다 약 10 배 크다는 것입니다. 이로 인해 스토리지가 비싸고 히스토리 테이블의 유지 보수가 어려울 수 있습니다. 전체 테이블을 유지하면 사용자가 이전 변경 사항을 롤백 할 수 있지만 과도하게 느껴지기 시작했습니다. 따라서 장치를 마지막으로 다운로드 한 기록 항목이 기록 테이블에 더 이상 존재하지 않으면 서버가 최근 기록 항목을 제공하지 않고 대신 모든 데이터를 포함하는 파일을 제공하는 루틴을 동기화 프로세스에 추가했습니다. 그 계정. 그런 다음 90 일보다 오래된 기록 항목을 삭제하기 위해 cronjob을 추가했습니다. 즉, 사용자는 90 일 미만의 변경 사항을 계속 롤백 할 수 있으며 90 일마다 한 번 이상 동기화하면 업데이트가 이전과 같이 증분됩니다. 하지만 90 일 이상 기다리면
이 변경으로 인해 히스토리 테이블의 크기가 거의 90 % 줄었으므로 이제 히스토리 테이블을 유지 보수하면 데이터베이스가 10 배가 아닌 2 배만 커집니다. 이 시스템의 또 다른 장점은 필요한 경우 기록 테이블 없이도 동기화를 계속 수행 할 수 있다는 것입니다. 또는 다른 가격대의 계정에 대해 다른 롤백 기간을 제공 할 수 있습니다. 다운로드 할 때까지 90 일이 지난 후에도 전체 파일이 증분 형식보다 효율적입니다.
오늘 다시 시작한 경우 ID 충돌 검사를 건너 뛰고 경우에 따라 일종의 오류 검사와 함께 충돌을 제거하기에 충분한 키 길이를 목표로합니다. 그러나 최근 업데이트에 대한 기록 테이블과 증분 다운로드 조합 또는 필요할 때 전체 다운로드가 제대로 작동했습니다.