2

JPA またはデータベース レベルで、データベース テーブルの主キーに MAX 値を設定できますか? もしそれが不可能なら、私は考えていました

  1. 0 ~ 9999999999 の間でランダムに作成しますkey(9999999999 が私の MAX です)
  2. 新しく作成されたデータベースで SELECT を実行しますkey。戻りオブジェクトがnullの場合は INSERT、そうでない場合は手順 1 に戻ります。

上記の場合、2つの質問があります。この環境は同時性が高いことに注意してください。

Q1: SELECT を使用したチェックのオーバーヘッドは重要ですか? 私が本当に言いたいのは、通常は DB に一意の PK を作成させるので、このプロセスは正常なのですか?

Q2: Q1 でパフォーマンスが大幅に低下しない場合、同時発生の問題が発生する可能性はありますか? たとえば、Id1 を持つ P1 がテーブルをチェックした場合、Id1 はそこになく、挿入する準備ができており、P2 は P1 ができる前に Id1 を挿入します。そのため、P1 が Id1 を挿入すると失敗します。ここでプロセスを失敗させたくありません。ループに戻り、新しい ID を見つけて、プロセスを繰り返します。それ、どうやったら出来るの?

私の環境はSQLとMYSQL dbです。Eclipselink実装でJPAを使用しています

:このように実装するという私の決定に疑問を呈する人もいますが、答えはTravisJ以下の提案とまったく同じです。私は非常に高い同時実行環境を持っています。プロセスが開始したら、別のプロセスへのリクエストを作成し、そのプロセスに 10 文字の一意の ID を渡す必要があります。現在の環境が高いため、PK のゼロではない独自の機能を活用したいと考えています。リクエストには多くの情報が含まれているためRequest、リクエスト ID を PK としてテーブルを作成します。すべての DB が PK にインデックスを付けているため、PK のクエリが高速であることはわかっています。より良い方法があれば、私に知らせてください。

4

3 に答える 3

2

1 から始めて、自動インクリメントを使用してみませんか? これは、循環しなければならない衝突が発生しないため、はるかに効率的です。数が足りなくなった場合は、どちらの方法でも同じボートに乗ることになりますが、少なくとも順番に進むと、衝突に対処する必要がなくなります。

利用可能な番号の 90% を使い果たしたときに、未使用のキーを見つけようとすることを想像してみてください。これには時間がかかります。また、ランダムに生成している場合、未使用のキーが (一生のうちに) 見つからない可能性が常にあります。

また、自動インクリメントを使用すると、制限に近づいているかどうかを簡単に判断できます ( SELECT MAX(col))。いつリセットする必要があるかを知らせるアラートをスクリプト化できます。ランダムな方法の場合、そのクエリはどのようになりますか?

InnoDB を使用している場合でも、主キーを使用したくない場合があります。クラスター化インデックスにランダム レコードを挿入すると、実際のテーブル データを並べ替える必要があるため、パフォーマンスが低下します。代わりに、一意のキーを使用します (自動インクリメントの主キーを使用)。

問題の列に一意のインデックスを使用して、範囲内の乱数を生成し、挿入を試みます。挿入に失敗した場合は、新しい番号を生成して再試行してください。挿入が成功した場合は、次に進みます。これにより、同時実行の問題が説明されます。

それでも、順次自動インクリメント キーを使用すると、パフォーマンスが向上します。

于 2012-04-04T23:28:50.803 に答える
2

テーブル定義にチェック制約を実装できます。

CREATE TABLE P
(
P_Id int PRIMARY KEY NOT NULL,
...
CONSTRAINT chk_P_Id CHECK (P_Id>0 and P_Id<9999999999)
)

編集:コメントで述べたように、MySql は CHECK 制約を尊重しません。これはバグ ログの 6 年前の欠陥であり、MySql チームはまだ修正していません。MySql は現在 Oracle Corp によって監督されているため、修正されることはありません (単に「文書化された制限」と見なされ、それが気に入らない人は有料の DBMS にアップグレードできます)。ただし、この構文とチェック制約機能自体は、Oracle、MS SQL Server (SQLExpress/MSDE を含む)、MS Access、Postgre、および SQLite で動作します。

于 2012-04-04T21:00:04.123 に答える
1

見る、

http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing

と、

http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Advanced_Sequencing

JPA はすでに適切な ID 生成をサポートしていますが、独自に実装する意味はありません。

同時実行性とパフォーマンスに関心があり、MySQL を使用している場合は、大きな事前割り当てサイズの TABLE ジェネレーターを使用することをお勧めします (他のデータベースでは、SEQUENCE ジェネレーターをお勧めします)。大量のデータがある場合は、ID に long を使用してください。

これ以上のものが本当に必要だと思う場合は、UUID id の生成を検討してください。EclipseLink 2.4 は @UUIDGenerator を提供します。

于 2012-04-05T13:35:47.650 に答える