복붙노트

[SQL] 클라이언트 - 서버 데이터베이스를 동기화

SQL

클라이언트 - 서버 데이터베이스를 동기화

나는 항상 온라인 아닌 클라이언트 응용 프로그램과 중앙 서버에 데이터를 동기화하기위한 일반적인 전략을 찾고 있어요.

내 특정 경우에, 나는 sqlite가 데이터베이스와 MySQL 데이터베이스와 PHP 웹 응용 프로그램과 안드로이드 폰 응용 프로그램이 있습니다.

사용자는 전화 응용 프로그램과 웹 응용 프로그램에서 편집 정보를 추가 할 수 있습니다. 내가 변경 한 곳을 만들어 전화가 즉시 서버와 통신 할 수없는 경우에도 사방에 반영되어 있는지 확인해야합니다.

나는 반대 서버 또는 그에게 전화에서 데이터를 전송하는 방법에 관심 있지 않다. 내가 사용할 수없는 경우에만 있기 때문에, 예를 들어, 복제가 MySQL을 사용할 수 있습니다 내 특정 기술을 언급하고있다.

등 기사, 책, 기사, - - 문제를 처리하기위한 패턴에 대한 필자는 클라이언트 - 서버 데이터 동기화 문제가 길고 긴 시간 동안 주변되었습니다 및 정보를 원하는 것을 알고있다. 나는 강점, 약점 및 장단점을 비교하기 위해 동기화를 처리하기위한 일반적인 전략에 대해 알고 싶습니다.

해결법

  1. ==============================

    1.당신이 결정해야 할 첫 번째 일은면이 변경 충돌의 경우 "권위"로 간주되는 대한 일반적인 정책입니다.

    당신이 결정해야 할 첫 번째 일은면이 변경 충돌의 경우 "권위"로 간주되는 대한 일반적인 정책입니다.

    즉이 기록의 # 125 오후 10시 월 5 일 서버에서 변경과 같은 레코드가 전화 중 하나에 변경을 가정 .: 오후 11시 월 5 일에 (의는 A 클라이언트를 부르 자). 마지막 동기화는 월 3 일에 있었다. 1 월 8, 말에 다음 사용자 다시 연결합니다.

    무엇이든 만들거나 업데이트가 화해 할 마지막 동기화 요구하기 때문에 (더이에 대한 아래 참조) 때문에 변경에 필요한 사항을 확인하는 것은, 클라이언트와 서버가 마지막 동기화의 날짜를 알고 있다는 의미에서 "쉽게"입니다.

    그래서, 유일한 변경 기록 # 125이라고 가정하자. 당신도 두 자동으로 "승리"의 하나를 결정하고 덮어 다른하거나 사용자가 다른 덮어 버전 (서버 또는 클라이언트)는 올바른 결정 할 수있는 조정 '단계를 지원해야합니다.

    이 결정은 매우 중요합니다 당신은 클라이언트의 "역할"을 무겁게해야합니다. 잠재적 인 충돌이있는 경우에 특히뿐만 아니라 클라이언트와 서버 사이의,하지만 경우에 다른 클라이언트가 동일한 레코드 (들)을 변경할 수 있습니다.

    [# 125 번째 클라이언트에 의해 수정 될 수 있다는 가정 (클라이언트 B)는 아직 서로 연관되지 않은 클라이언트 B는, 이전 충돌 해결 논쟁을, 동일한 레코드의 또 다른 버전을 제공 할 가능성이 있습니다]

    은 "만들거나 업데이트"에 관한 위의 점 ... 그것이 클라이언트 (문제 도메인이 차종의 감각을 가정) 중 하나에서 유래 된 경우 어떻게 제대로 레코드를 식별 할 수 있습니까? 의 앱 비즈니스 연락처 목록을 관리하는 가정하자. 클라이언트 A는 새로 만든 존 스미스를 추가해야하고, 서버가 존 스미스는 클라이언트 D 어제 만들었습니다 ... 당신은 그들이 다른 사람 아니라는 것을 확신 할 수 없기 때문에 당신이 두 개의 레코드를 생성 할 말한다면? 당신도이 갈등을 조정하기 위해 사용자에게 것인가?

    클라이언트는 데이터의 부분 집합의 "소유권"이 있습니까? 즉 클라이언트 B는 5 A 클라이언트 수정 / 지역 # 5 여부에 대한 레코드를 생성 할 수 있습니다 지역 번호 데이터의 "권한"으로 설정 인 경우? (이것은 일부 분쟁 해결 쉽게,하지만 상황에 실행할 수 없게 증명할 수있다).

    이를 요약하면 주요 문제는 다음과 같습니다

    서지:

    (마지막 세 당신이 구성원 인 경우 ACM 디지털 도서관에서 아무 생각이 없거나 다른 채널을 통해 사람들을 얻을 수있는 경우).

    Dr.Dobbs 사이트에서 :

    arxiv.org에서 :

  2. ==============================

    2.난 당신이 모든 테이블에 타임 스탬프 열 및 삽입 또는 업데이트, 영향을받는 각 행의 타임 스탬프 값을 업데이트 할 때마다하는 것이 좋습니다 것입니다. 그리고, 타임 스탬프는 대상 데이터베이스에있는 것보다 최신 버전 인 경우 체크 모든 테이블을 통해 당신으로 반복합니다. 새로운 키우면 경우 삽입하거나 업데이트해야하는 경우, 다음 확인.

    난 당신이 모든 테이블에 타임 스탬프 열 및 삽입 또는 업데이트, 영향을받는 각 행의 타임 스탬프 값을 업데이트 할 때마다하는 것이 좋습니다 것입니다. 그리고, 타임 스탬프는 대상 데이터베이스에있는 것보다 최신 버전 인 경우 체크 모든 테이블을 통해 당신으로 반복합니다. 새로운 키우면 경우 삽입하거나 업데이트해야하는 경우, 다음 확인.

    관측 1 : 행이 소스 DB에서 삭제하고 서버 DB에서 동일한 작업을 수행해야하기 때문에 실제 삭제 인식. 이 물리적 삭제를 피하거나 타임 스탬프가있는 테이블의 모든 삭제를 기록 해결할 수 있습니다. 이런 식으로 뭔가 : DeletedRows = (아이디, TABLE_NAME, pk_column, pk_column_value, 타임 스탬프) 그래서, 당신은 모두에게 DeletedRows 테이블의 새 행을 읽고 TABLE_NAME, pk_column 및 pk_column_value를 사용하여 서버에 삭제를 실행해야합니다.

    관측 2 : 실패 할 수 있습니다 다른 테이블에 관련된 테이블 그거 ...에 데이터를 삽입 이후 FK 인식. 당신은 데이터 동기화하기 전에 모든 FK를 비활성화해야합니다.

  3. ==============================

    3.사람이 여러 안드로이드 기기에서 동기화 변화에 유사한 디자인의 문제와 요구를 처리하는 경우 I는 안드로이드 (GCM)에 대한 Google 클라우드 메시징을 확인하는 것이 좋습니다.

    사람이 여러 안드로이드 기기에서 동기화 변화에 유사한 디자인의 문제와 요구를 처리하는 경우 I는 안드로이드 (GCM)에 대한 Google 클라우드 메시징을 확인하는 것이 좋습니다.

    하나의 클라이언트에 변경된 사항이 다른 클라이언트에 전달해야 어디 하나 개의 솔루션에서 일하고 있습니다. 그리고 난 그냥 개념의 구현 (서버 및 클라이언트)의 증거를 구현하고 그것이 마치 마법처럼 작동합니다.

    기본적으로, 각 클라이언트는 서버에 델타 변경을 보냅니다. 예를 들면 자원 ID ABCD1234 99로 값 (100)로부터 변경되었다.

    서버는 데이터베이스에 대해 이러한 델타 변화를 확인하고 중 변경을 승인 (클라이언트가 동기화에) 및 데이터베이스를 업데이트하거나 (클라이언트가 동기화되지) 변화를 거부합니다.

    변경이 서버에 의해 승인되면, 서버는 GCM 통해 동일한 델타 변화 반송 멀티 캐스트 메시지를 전송한다 (델타 변화를 보낸 사람을 제외한) 다른 클라이언트에 통지한다. 클라이언트는이 메시지를 처리하고 자신의 데이터베이스를 업데이트합니다.

    쿨 것은 이러한 변화가 거의 즉시 전파된다는 것입니다! 이러한 장치는 온라인합니다. 그리고 나는 그 클라이언트에 어떤 폴링 메커니즘을 구현 할 필요가 없습니다.

    장치가 너무 오랫동안 오프라인 및 전달을 위해 GCM 큐에 대기중인 100 개 이상의 메시지가있는 경우, GCM 그 메시지를 무시하고 장치가 온라인으로 돌아 오면 특별한 메시지를 보낼 것이라는 점을 명심하십시오. 이 경우 클라이언트는 서버에 전체 동기화를 수행해야합니다.

    이 튜토리얼을 확인하는 CGM 클라이언트 구현을 시작합니다.

  4. ==============================

    4.자 마린 프레임 워크를 사용하는이 답변 개발자는 (https://stackoverflow.com/questions/40156342/sync-online-offline-data 참조)

    자 마린 프레임 워크를 사용하는이 답변 개발자는 (https://stackoverflow.com/questions/40156342/sync-online-offline-data 참조)

    자 마린 프레임 워크와이를 달성하기 아주 간단한 방법은 필요에 따라 서버에서 밀어 풀 데이터 수로 하늘빛의 오프라인 데이터 동기화를 사용하는 것입니다. 읽기 작업은 로컬에서 수행하고, 쓰기 작업이 요구에 밀려; 연결이 복구 될 때까지 네트워크 연결이 끊어 경우 쓰기 작업이 실행 된 후, 대기하고 있습니다.

    구현은 오히려 간단하다 :

    1) 푸른 포털에서 모바일 앱을 만드는 (당신은) 여기 https://tryappservice.azure.com/ 무료로 시도 할 수 있습니다

    2) 모바일 앱에 클라이언트를 연결합니다. https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-xamarin-forms-get-started/

    3) 설정 로컬 저장소에 코드 :

    const string path = "localrepository.db";
    
    //Create our azure mobile app client
    this.MobileService = new MobileServiceClient("the api address as setup on Mobile app services in azure");
    
    //setup our local sqlite store and initialize a table
    var repository = new MobileServiceSQLiteStore(path);
    
    // initialize a Foo table
    store.DefineTable<Foo>();
    
    // init repository synchronisation
    await this.MobileService.SyncContext.InitializeAsync(repository);
    var fooTable = this.MobileService.GetSyncTable<Foo>();
    

    4) 후 밀어서 우리가 최신 변경 사항을 확인하기 위해 데이터를 당겨 :

    await this.MobileService.SyncContext.PushAsync();
    await this.saleItemsTable.PullAsync("allFoos", fooTable.CreateQuery());
    

    https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-xamarin-forms-get-started-offline-data/

  5. ==============================

    5.난 당신이 또한 Symmetricds를 살펴 보시기 바랍니다. 그것은 안드로이드 시스템에 사용할 수있는 SQLite는 복제 라이브러리입니다. 당신은 내가 또한 각 클라이언트에 대한 서버에서 별도의 데이터베이스를하는 것이 좋습니다, 클라이언트 및 서버 데이터베이스를 동기화하는 데 사용할 수 있습니다. 하나의 MySQL 데이터베이스의 모든 사용자의 데이터를 보유하기 위해 노력하는 것은 항상 좋은 생각이 아니다. 특히 사용자 데이터가 빠르게 증가 할 것입니다 경우.

    난 당신이 또한 Symmetricds를 살펴 보시기 바랍니다. 그것은 안드로이드 시스템에 사용할 수있는 SQLite는 복제 라이브러리입니다. 당신은 내가 또한 각 클라이언트에 대한 서버에서 별도의 데이터베이스를하는 것이 좋습니다, 클라이언트 및 서버 데이터베이스를 동기화하는 데 사용할 수 있습니다. 하나의 MySQL 데이터베이스의 모든 사용자의 데이터를 보유하기 위해 노력하는 것은 항상 좋은 생각이 아니다. 특히 사용자 데이터가 빠르게 증가 할 것입니다 경우.

  6. ==============================

    6.CUDR 동기화 문제를 호출 할 수 있습니다 (내가 CRUD 좋아하지 않는다 - 만들기 때문에 / 업데이트 / 삭제가 쓰기하고 함께 짝을한다)

    CUDR 동기화 문제를 호출 할 수 있습니다 (내가 CRUD 좋아하지 않는다 - 만들기 때문에 / 업데이트 / 삭제가 쓰기하고 함께 짝을한다)

    문제는 쓰기 offliine - 첫 번째 또는 쓰기 온라인 최초의 관점에서 본 될 수 있습니다. 쓰기 - 오프라인 접근 방식은 고유 식별자 충돌 문제를 가지고 있으며, 또한 동일한 트랜잭션에 대해 여러 네트워크 호출 증가 위험 (또는 비용) ...

    나는 개인적으로 (- 다른 모든 것이 동기화되는 곳에서이 진리의 단일 원천이 될 수 있도록) 쓰기 온라인 첫 번째 방법보다 쉽게 ​​관리 할 찾을 수 있습니다. 쓰기 - 온라인 접근 방식은 사용자가 처음으로 오프라인 쓰기를 허용하지 않습니다 필요합니다 - 그들은 확인 응답 형태로 온라인 쓰기를 받고 오프라인으로 작성합니다.

    그는 제 빨리 네트워크를 사용할 수있게되면 오프라인 읽기 온라인에서 데이터를 가져오고 로컬 데이터베이스를 업데이트 한 다음 UI를 업데이트 할 수 있습니다 ....

    고유 식별자의 충돌을 방지하는 한 가지 방법은 여전히 ​​고유 사용자 ID + 테이블 이름 또는 (SQLite는에 의해 생성)에 나타난 ID + 열 번호의 조합을 사용하는 ... 후와 동기화 부울 플래그 열을 사용 ..하지만 것 등록은 다른 모든 ID가 생성됩니다되는 고유 ID를 얻기 위해 온라인을 먼저해야합니다 ... 여기에 문제는 시계가 동기화되지 않는 경우가 될 것이다 - 누군가가 위에서 언급 된 ...

  7. from https://stackoverflow.com/questions/3406891/synchronizing-client-server-databases by cc-by-sa and MIT license