1. ホーム
  2. sql

[解決済み] クライアントとサーバーのデータベースを同期させる

2023-05-30 22:28:06

質問

常にオンラインではないクライアント アプリケーションと中央サーバー上のデータを同期させるための一般的な方法を探しています。

私の特定のケースでは、SQLiteデータベースを持つアンドロイド携帯電話アプリケーションと、MySQLデータベースを持つPHPウェブアプリケーションがあります。

ユーザーは、電話アプリケーションとウェブアプリケーションで情報を追加および編集することができます。携帯電話がサーバーとすぐに通信できない場合でも、1つの場所で行われた変更がどこでも反映されることを確認する必要があります。

私は、携帯電話からサーバーへ、またはその逆へデータを転送する方法には関心がありません。私が特定のテクノロジーについて言及するのは、たとえば MySQL で利用可能なレプリケーション機能を使用できないからです。

クライアントとサーバーのデータ同期の問題が長い間存在していたことは知っていますが、この問題を扱うためのパターンについての情報 (記事、書籍、アドバイスなど) が欲しいのです。長所、短所、トレードオフを比較するために、同期を扱うための一般的な戦略について知りたいのです。

どのように解決するのですか?

最初に決めなければならないのは、変更が衝突した場合に、どちらの側が "authoritative"と見なされるかという一般的な方針です。

例: Record #125 が 1 月 5 日の午後 10 時にサーバー上で変更され、同じレコードが 1 月 5 日の午後 11 時に電話機 (クライアント A と呼ぶことにします) で変更されたとします。 最後の同期は1月3日でした。その後、ユーザーはたとえば 1 月 8 日に再接続します。

クライアントとサーバーの両方が最後の同期の日付を知っているという意味で、変更する必要があるものを特定するのは簡単です。 作成または更新された (これについては以下を参照してください) が作成または更新された場合、それを調整する必要があります。

そこで、唯一の変更レコードが #125 だとします。 2 つのうちどちらかが自動的に勝利し、もう一方を上書きすると決定するか、ユーザーがどちらのバージョン (サーバーまたはクライアント) が正しいかを決定し、もう一方を上書きできるよう、照合フェーズをサポートする必要があります。

この決定は非常に重要であり、クライアントの "役割" を重み付けする必要があります。特に、クライアントとサーバーの間だけでなく、異なるクライアントが同じレコードを変更できる場合に、潜在的な競合が存在する場合です。

[125 が 2 番目のクライアント (クライアント B) によって変更できると仮定すると、まだ同期していないクライアント B が同じレコードの別のバージョンを提供する可能性があり、以前の競合の解決は無意味になってしまいます]。

について、" 作成または更新された についてですが、レコードがクライアントの 1 つで作成された場合、どのように適切にレコードを識別できるでしょうか (これが問題のドメインで意味をなすと仮定します)。 あなたのアプリがビジネス連絡先のリストを管理しているとします。クライアントAが新しく作成したJohn Smithを追加する必要があると言い、サーバーにはクライアントDが昨日作成したJohn Smithがある場合、別人でないことを確認できないため、2つのレコードを作成しますか? この矛盾もユーザーに調整してもらうのでしょうか?

クライアントはデータのサブセットに対して "ownership"を持っていますか?例えば、クライアント B がエリア 5 のデータに関する権限を持っている場合、クライアント A はエリア 5 のレコードを変更/作成できますか? (これは、いくつかの競合の解決を容易にしますが、あなたの状況には実行不可能であることが判明するかもしれません)。

要約すると、主な問題は次のとおりです。

  • 分離されたクライアントが新しいレコードを作成する前にサーバーにアクセスしていない可能性があることを考慮して、"identity" をどのように定義するか。
  • 前述の状況は、どんなに洗練されたソリューションであっても、データの重複が発生する可能性があるため、これらを定期的に解決する方法と、"Record #675" としていたものが実際には Record #543 にマージされた/置き換えられたことをクライアントに通知する方法を予見しなければなりません。
  • 競合が以下の方法で解決されるかどうかを決定します。 フィアット (例: "The server version always trumped the client's if the former has been updated since the last synch") または手動による介入。
  • の場合 フィアット の場合、特にクライアントが優先されると判断した場合、まだ同期していない他のクライアントが何らかの変更を行う可能性があるため、その対処方法にも注意しなければなりません。
  • 前の項目はデータの粒度を考慮していません (物事をより簡単に説明するため)。私の例のように、quot;Record" レベルで推論する代わりに、フィールド レベルで変更を記録する方がより適切であることがわかるかもしれないと言えば、十分でしょう。あるいは、レコードのセット(たとえば、Personレコード+Addressレコード+Contactsレコード)を一度に処理し、その集合体を一種のquot;Meta Record"として扱います。

書誌事項。

(最後の3つはACMデジタルライブラリからのものです。あなたがメンバーであるか、あるいは他のルートでそれらを入手できるかどうかはわかりません)。

からのものです。 Dr.Dobbs のサイトより。

  • SQL Server CE および SQL RDA を使用したアプリケーションの作成 Bill Wagner 著 2004 年 5 月 19 日 (デスクトップとモバイル PC の両方のためのアプリケーションを設計するためのベスト プラクティス - Windows/.NET)

arxiv.org より。

  • 競合のない複製されたJSONデータ型 - この論文では、JSON CRDT の実装について説明しています (Conflict-free replicated datatypes - CRDT - は、同時変更をサポートし、そのような同時更新の収束を保証するデータ構造の一群です)。