sql >> データベース >  >> RDS >> Mysql

SQLiteクライアントデータベースとMySQLサーバーデータベースの同期

    これは些細な問題ではないことに気づきましたか。昨年、商用アプリ用にこれを実現するためのライブラリを作成しましたが、満足のいく場所に到達するまでに約6か月かかりました。

    ファイアウォールとサポートの問題を回避するためにポート80とHTTP(TCP / IP)を使用するという議論はさておき、プロトコルを設計する必要があります。私のプロジェクトは非常にデータ集約的だったので、あらゆるデータを処理できるバイナリプロトコル(肥大化したxmlではなく)を使用しました。また、データを挿入したり、リクエストを実行したりできるように、双方向にする必要がありました。サーバーでCGI/FastCGIを使用しました。

    私が設計したバイナリプロトコルは非常に単純で(常に優れています)、大規模な転送をユーザー定義のサイズのチャンクに分割します(約600kが適切と思われます)。各チャンクには、ヘッダーとそれに続くデータがあります。

    このプロトコルはあらゆる種類のデータの送信に使用できますが、質問が示唆するように、通常はデータベーススタイルのデータに使用されます。これに対応するために、行/列のアプローチを使用して設計することにしました。データは一度に1行ずつ格納されます。つまり、各列は行1に格納され、次にすべての列が行2...行nに格納されます。

    単一列データの形式は次のとおりです。

    ' Col1Type          1Bytes - BYTE     ' Data Type (REMSQL_TEXT etc)                
    ' Col1Len           4Bytes - DWORD    ' Length in bytes the Column Data                            - up to 4.2GB
    ' Col1Data          nBytes - BYTE     ' String data  
    

    (Cでは、BYTEはCHARです)

    これは、各列にデータ型記述子があることを意味します。すべてのデータ型は次のように表すことができます:

    REMSQL_NONE = 0    ' DataType undefined
    REMSQL_QUAD = 1    ' 64-bit signed integer                
    REMSQL_DBLE = 2    ' 64-bit IEEE floating point number
    REMSQL_TEXT = 3    ' STRING - (CHAR) string of Ascii Bytes                                     
    REMSQL_BLOB = 4    ' BLOB - (CHAR) string of Binary Bytes                                       
    REMSQL_NULL = 5    ' NULL - Empty Column
    

    これらのデータ型はSQLiteの基本的なデータ型と一致し、数値的にはSQL3の基本的なデータ型の列挙型と同等です。

    この設計では、フィールドが空(NULL)の場合、フィールドを格納するのに5バイトしかかかりません。たとえば、フィールドに200バイトのテキストがある場合、フィールドを格納するのに必要なのは205バイトだけです。より大きな利点は、データを解析することです。これは、200バイトすべてを読み取って終了文字を見つけることなく、列をスキップできるためです。

    チャンクヘッダーには、行数、列数、合計バイト数などが含まれている必要があります。DWORD(符号なし64ビット整数)を使用する場合、チャンクの理論上の制限は4.2ギガで、ローカルネットワークの送信にも十分です。

    実装では、この機能のためにSQLite/MYSQLラッパーを作成する必要があります。私はBINARYプロトコルを排他的に使用していますが、これには少し時間がかかりますが、基本的に次の関数が必要です。クライアント側:SendRequest()-要求を送信し、応答を待機します

    サーバー側:ProcessRequest()-リクエストを受信して​​処理し、レスポンスを返します

    私の場合、応答は!00MB以上のデータになる可能性があります。 MySQLからデータセット全体を取得し、サーバー上のディスクに保存します。次に、データセットのメトリックを含む空のチャンクを返します。次に、クライアントは600kのチャンクでデータセットを1つずつ要求します。接続が失われた場合は、中断したところから再開します。

    最後に、データセットはほとんどがテキスト(名前、アドレスなど)であったため、圧縮に適しています。この場合、セキュリティは非常に大きな問題であったため、暗号化が不可欠でした。これは実装が少し複雑になりますが、基本的にはチャンク全体を圧縮し、ブロック暗号BLOCKSIZEの倍数の長さにパディングして暗号化します。

    このすべての過程で、私は非常に高速な文字列ビルダークラス、ASMでのAES暗号化の実装、およびFastCGIライブラリ全体(www.coastrd.com)を作成します

    だから私が言ったように、些細なことではありません。このライブラリはまもなく利用できるようになります。チェックアウトしたい場合は、私にメールしてください。

    通信を書き込んだら、同期の設計を開始できます。各レコードにハッシュを使用するか、単純なブールフラグを使用します。サーバーで何か変更があった場合は、レコード全体を送信してクライアント側で上書きします(クライアントの同期を維持しようとしていると仮定します...)

    自分で書いた場合は、ここにあなたの経験について投稿してください!

    PS。検索しやすいようにタイトルを変更することを検討してください。おそらく次のようになります。

    「SQLiteクライアントデータベースとMySQLサーバーデータベースの同期」



    1. Ubuntu 8.04でMySQLリレーショナルデータベースを使用する(Hardy)

    2. PHPで自動データベース接続を閉じますか?

    3. SQLServerで先行ゼロを埋めて数値をフォーマットする

    4. 一意性の制約を条件付きで適用できますか?