7

現在、HTML5 SQL-Lite データベースにデータを格納するプロジェクトに取り組んでいます。現在、次のようなスキーマがあります(4つのテーブル):

TransData:
-----------------------------------------------------------
|   TID   | UserName | TransColor | ... |  Date  |  Note  |
-----------------------------------------------------------
|    6    | Brendan  |      Red   | ... |        |        |
-----------------------------------------------------------
|    7    | Brendan  |      Red   | ... |        |     1  |
-----------------------------------------------------------

FullData:
-----------------------------------------------------------
|   TID   | UserName | TransColor | ... |  Date  |  Note  |
-----------------------------------------------------------
|    1    | Brendan  |      Red   | ... |        |  Start |
-----------------------------------------------------------
|    ...  | Brendan  |      Red   | ... |        |        |
-----------------------------------------------------------
|   40    | Brendan  |      Red   | ... |        |  End   |
-----------------------------------------------------------

SalamanderData:
----------------------------------------------------
|   SID   | SalamanderName | Length | ... |  TID   |
----------------------------------------------------
|    1    | Northern-Slimy |   16   | ... |    6   |
----------------------------------------------------
|    2    |   Two-Lined    |   26   | ... |    6   |
----------------------------------------------------  
|    3    |   Two-Lined    |   12   | ... |    7   |
----------------------------------------------------  

SalamanderData:
----------------------------------------------------
|   SID   | SalamanderName | Length | ... |  TID   |
----------------------------------------------------
|    1    | Northern-Slimy |   16   | ... |    6   |       
----------------------------------------------------
|    2    |   Two-Lined    |   26   | ... |    6   |   
---------------------------------------------------- 
|    3    |   Two-Lined    |   12   | ... |    7   |
----------------------------------------------------

注: TransData の「メモ」列は、FullData フィールドのコレクションの開始データ ポイントを指すために使用されます。

私のアプリとサーバーの間のデータベースは同期されるべきではありません。これらのすべてのテーブルをサーバー上のデータベースにダンプしようとしているだけです (つまり、ダンプとは、他のテーブルへの参照を更新してから、サーバー データベースに挿入することです)。

を使用MAX(TID-Server) + TID-App = new TID-Serverして、更新をテーブルにカスケードします。

これをどのように行うつもりですか?

4

3 に答える 3

6

Dan Pichelmanのコメントによると、問題は、クライアントがレコードをローカル DB に挿入し、そのためにレコードの主キーを決定する必要があることです。ただし、すべての異なるクライアントが同じことを行っている場合、新しい PK はサーバーにヒットしたときに衝突します。

これは、物理的に切断されているシステム (少なくとも時々) や、共有シーケンス ジェネレーターなどの単一障害点が存在しないシステムでよくある問題です。

一般的な解決策は次のとおりです。

GUID

ここで、PK は 128 ビット (またはそれ以上) の乱数です。2 つの PK が同じである可能性は非常に小さいです。しかし、衝突の変化をさらに減らすために、GUID アルゴリズムには、一意のマシン識別子 (ネットワーク MAC) と時間のシードが含まれています。同じマシンで生成された 2 つの GUID が衝突することはなく、MAC が異なるマシンで生成された GUID も衝突しません。ほとんどのマシンと言語には、GUID を生成するためのネイティブ関数がありますが、JavaScript にはありません。見る:

パーティションの命名スキーム

このスキームでも、PK は大きな数 (実際にはビットフィールド) であり、それを階層的に分割します。良い例は、国際電話システム (少なくとも携帯電話番号以前) です。ここで、電話番号は次のように分類されます。

  • 国コード: 例 USA - 1
  • 市外局番: 例 Sunnyvale - 615
  • 取引所が管理する加入者番号。

あなたの場合、次のように番号を分割できます。

  • ユーザーログイン(各ユーザー固有の番号など)
  • セッション ID (たとえば、同じユーザーの異なるブラウザー/コンピューター上の異なるセッションを区別するための、ユーザーごとの各ログオンに固有の番号)
  • シリアルナンバー

3 つすべてを組み合わせると、一意の PK が保証されます。

PK「ライセンス」サーバー

最初の 2 つの提案には、完全に切り離された状態で機能するというメリットがあります。接続されたクライアントがある場合、クライアントが要求したときに PK を提供する Web サービスを持つことができます。

効率のために、たとえば 100 個の数値のバッチを返す場合があります。これは、ユーザーがログオンしたときに返されることもあります。

クライアントはそれらすべてを使用して、さらに要求することができます。クライアントが状態を忘れて、グローバル PK シーケンスに「穴」を残す場合があります。これは、ほぼ確実に問題になることはありません。

いくつかの考慮事項

テーブルの順序付けのために、連続した PK が必要な場合があります。どちらの場合、クライアントまたは作成時間で注文する必要がありますか? どちらかが重要な場合は、パーティションの命名スキームを高く評価することができます。必要に応じて、クライアントまたは時間を最初のパーティションとして配置します。または、テーブルに列を追加します。

パーティションの名前付けスキームの固定構造が必要ない場合は、GUID が適切に機能します。

一元的な調整が必要な場合は、PK ライセンス サーバーを使用します。

于 2012-09-10T11:08:56.487 に答える
0

これを行うための審美的に楽しい方法はわかりませんが、ストアドプロシージャを作成することで「解決」しました。

最初のテーブルは簡単です。必要に応じて更新または挿入します。挿入を行う場合は、新しく挿入されたレコードの主キーを取得し、それに応じて従属テーブルを処理します (通常、新しい主キーでデータを挿入することを意味します)。必要に応じて、関係をたどっていきます。4 テーブルの場合は問題ありませんが、40 テーブルの場合はやりたくないです。

私の場合、それは面倒で、oldPK と newPK を含む一時的なルックアップ テーブルが関係していました。

それはまた、かなり長くて退屈なコードであり、唯一の償還機能はそれが機能することです.

于 2012-09-06T18:35:39.243 に答える
0

これはあなたの要求に少し反するので、これが完全に的外れである場合はコメントしてください。削除します. しかし、主キーに関してサーバー/クライアントが同期できない特定の理由を指定しませんでした (私の意見では、これが実際にここでの問題です)。

また、(あなたのデータとあなたの質問から) サーバーに時折アップロードされるユーザー作成コンテンツ (ログなど) を含む webapp について話していると仮定しています。

スポーツだけに、いくつかのフィールドで構築された主キーを使用することを検討しましたか? そうすれば、ローカルデータベースで自動インクリメントを行い、データをサーバーにダンプでき、他のユーザーのデータと衝突しません。SalamanderData テーブルの例は、次のようなものです。

CREATE TABLE SalamanderData
(
    SID int NOT NULL,
    SalamanderName varchar(255),
    Length int,
    ... ...,
    TID int NOT NULL,
    CONSTRAINT pk_SDataEntry PRIMARY KEY (SID,TID)
)

次に、SID と TID から PK を作成します。

私の投稿を読んで他の回答を確認すると、これがアンドリューが提案したものであることがわかりました。これが役に立ったとしても、彼の回答を本当に受け入れる必要があります

おそらく解決策を明確にし、コード例を示す目的で答えを保持します

于 2012-09-12T18:23:41.030 に答える