17

新しいデータの挿入を伴う多くのローカルデバイス上でオフラインのiPad/Androidアプリバージョンを持つ新しいWebアプリを構築しています。そのため、マスターデータベースとの必要な双方向同期を可能にするためにUUIDを使用する必要があります。このために、UUIDをBINARY(16)主キーとして保存します。

調査後に私が学んだ問題は、非シーケンシャルな主キーの挿入に必要な時間が時間の経過とともに増加し、これらの挿入が断片化につながることです(ここで回答)。の利点AUTO_INCREMENTは、通常、新しい行がテーブルの最後に追加されるだけなので、UUIDの速度の問題が発生しないことです。

私の質問は、AUTO_INCREMENT列を主キーとして使用し、UUID列をnull以外の一意のインデックスとして使用する方がよいかどうかです。おそらく、これには、分散データベースの同期に必要なUUIDを保持しながら、順次挿入の速度の利点があります。

これで私が見ることができる1つの問題は、UUIDを他のテーブル(つまり、サイトに添付されている検査に添付されている問題のリスト)への参照として(外部キー制約を使用して)使用する必要があることです。挿入に関与しているため、すべてUUIDが必要です)。意味的には、主キーが参照である方が理にかなっていますが、分散システムであるAUTO_INCREMENTSため、これらに使用することはできません。JOINこれらの参照(およびもちろん、それらに付属するs)に、主キーではなく(null以外の)一意のインデックスを使用することには欠点がありますか?

マスター(オンライン)データベースはMySQL(InnoDB)を使用し、分散(オフライン)データベースはSQLiteを使用することにも注意してください。

編集:

UUIDを主キーとして使用する方がおそらく良いことを考えると(意味的にはそれが何であるか)、UUIDを主キーとして設定し、AUTO_INCREMENT列をnull以外の一意のインデックスとして設定すると、順次挿入のメリットが得られますか? ?それとも、新しい行を挿入する場所を決定するときに関連するのは主キーだけですか?

4

4 に答える 4

15

プライマリとuuid列として自動インクリメントを使用することは有効なモデルですが、自動インクリメントがもたらすいくつかの問題に苦労する必要があります。それはすべて、シンクロの実行方法によって異なります。

とにかく、私はuuidを主キーとして使用してきました(私の現在のデータベースには50万レコードがあります)、それでもかなり高速ですが、挿入の速度が少し遅くなるだけですが、毎日非常に大量の挿入がある場合を除いて、そうすべきではありません。あなたを怖がらせます。

Sql-Serverを使用する場合、確認できる別のソリューションはシーケンシャルUUIDです。これは、通常のUUIDよりも衝突の可能性がわずかに高くなりますが、絶対的な衝突の可能性はまだかなり低く、部分的にシーケンシャルであるため、問題をカバーします。断片化を伴います。

于 2013-03-12T11:53:14.323 に答える
6

大規模な分散データウェアハウスを作成した後、一意のキーとしてUUIDまたはGUIDを使用し、それを後で結合に使用する場合、それは適切ではありません。

UUIDまたはGUIDを使用する代わりに、マスターデータベースまたはデータパイプラインにシーケンシャルサロゲートキーを作成してください。

私たちのプロジェクトの経験を参考として共有してください。並列データウェアハウスには3,000億のレコードが保存されており、システムでは自動インクリメンタルキーもサポートされていません。主キーとして8バイトのbigintを使用します(システムで実際に一意のキーもサポートされていませんが、論理的な一意性には影響しません)。ファイルを処理してファイルをロードするときは、3バイトを使用してファイルIDを生成します。これは2^24です。ファイルの場合、1日あたり約2,000個のファイルをロードする必要があるため、2 ^ 24は、間違いがなければ約25年をサポートできます。

残りの4バイトを行IDとして使用します。これは40億行であり、どのファイルにも40億行はありません。1バイトを予約します。ETL処理中は、自動インクリメンタルIDをサポートするマスターデータベース内のファイルIDを追跡するだけで済みます。ファイル処理時にレコードIDを生成する必要がある場合は、FileID +reserved1バイト+4バイトrowIDを組み合わせます。

于 2013-03-21T22:07:13.130 に答える
2

https://uuid.fyi/uuidorintから

UUID

長所

  • グローバルにユニーク。
  • ステートレス、オンザフライで生成できます。
  • 悪意のあるユーザーはIDを推測できないため、安全です。
  • バージョン1のUUIDはタイムスタンプ情報を格納し、場合によっては役立つことがあります。

短所

  • 読めない。
  • クラスター化された主キーを使用するMySQL、Oracleなどのデータベースの場合、バージョン4のランダムに生成されたUUIDは、主キーとして使用されると挿入パフォーマンスを低下させます。これは、新しく挿入された行をクラスター化インデックス内の正しい位置に配置するために、行を並べ替える必要があるためです。一方、PostgreSQLはクラスター化された主キーの代わりにヒープを使用するため、PKとしてUUIDを使用してもPostgreSQLの挿入パフォーマンスに影響はありません。

整数/シーケンスの自動インクリメント

長所

  • 読み取り可能。これは、外部に公開する場合に特に役立ちます。問題IDを考えると、明らかに、issue-123はissue-b1e92c3b-a44a-4856-9fe3-925444ac4c23よりもはるかに読みやすくなっています。

短所

  • 異なるホストがまったく同じ数を生成する可能性が非常に高いため、分散システムでは使用できません。
  • その場で生成することはできません。代わりに、データベースを調べて、次に利用可能なPKを把握する必要があります。
  • 最新のIDは在庫の総数を表す可能性があるため、一部のビジネスデータが公開される可能性があります。攻撃者は整数範囲をスキャンしてリークを調査することもできます(ただし、ACLが正しく実装されている場合は発生しないはずです)。
于 2020-09-12T13:54:28.330 に答える
0

オフラインクライアントによって割り当てられた自動インクリメントのbigintID値とクライアントに割り当てられたbigintIDで構成される複合主キーを使用できます。したがって、クライアント1235でエントリ15を作成することになります。

クライアントは、最初の編集が行われる前に、たとえばサーバーのマスターデータを最初に取得するときに、サーバーにIDを要求することが望ましいでしょう。

于 2013-03-21T22:06:51.910 に答える