Oracle のシーケンスが気に入らない人もいます。なんで?とても使いやすく、とてもいいと思います。選択、挿入、更新などで使用できます...
8 に答える
私はしません。私は時々人々が彼らが理解していないことを嫌うことを指摘する必要があります。
シーケンスは、一意のIDを生成するために非常に重要です。概念的には、テーブルの内容に依存しないIDを生成する方法があると便利です。一意の番号を生成するためにテーブルをロックする必要はありません。
シーケンスは、一意である必要がある複数のテーブルにまたがるキーを生成する場合にも役立ちます。たとえば、システムに新しいアイテムを入力し、一度に複数のテーブルに行を配置したい場合、シーケンスからIDを取得して、任意の数のテーブルに挿入するときに再利用できます。適切に行われると、IDがすでにテーブルにある値と競合せず、各行が同じIDを持つことがわかります。
これらのことは、自動インクリメント列でも可能だと思います。
要約すると、私はシーケンスが好きですが、列の autoincrement キーワードがもっと欲しいです。
DBAがデータベースを移行し、すべてのオブジェクトとデータを移動し、シーケンスを誤って再作成し、0から再起動することに何度か噛まれたためです。陽気さが続きます...
また、シーケンスは RAC で for ループをスローすることができます。厳密に増加するように指定しない限り、それらから一意の番号が取得されますが、必ずしも厳密に増加する順序であるとは限りません (これは、inter を避けるために発生します)。 -すべての sequence.nextval 呼び出しのノード通信、各ノードは今後の番号の個別の小さなスライスを取得します)。さまざまな「select max(sequence_id)」クエリに大混乱をもたらします。
ああ、autoincrement キーワードはいいのですが、それは構文糖衣にすぎません。他の 2 つの問題は、かなり深刻な「落とし穴」です。
JPAに夢中になるまで、自動インクリメント列(MySQL、SQL Serverなど)を好んでいました。その時点で、自動インクリメント フィールドの弱点が明らかになりました。ID を取得する前に挿入する必要があります。これは、オブジェクト間の関係を維持する際の問題です。
Oracleを使用する場合のJPAではentityManger.persist(object)
、次のシーケンス値を選択してIDとして割り当てますが、自動インクリメント列はコミット後まで発生しません。大きな違い。
ただし、それらは少し難しい作業です。それが、人々がそれらを好まない理由だと思います(または、自動インクリメントフィールドと比較して利点がわかりません)。
シーケンスに関するもう 1 つの問題は、順序が緩く、多くの人が絶対的な順序付けを望んでいることです。それが最大の欠点だと思います(とにかく見ることができます)。
IBM Informix Dynamic Server の SERIAL 列よりも使用が難しいためです。
平凡な自動インクリメント フィールドを設定するボイラープレートを覚えるのが難しいため、一部の同僚はそれらを好まなかった。
幸い、定型文は SQL Developer が埋めてくれるので、問題はそれほど深刻ではありません。
シーケンスの問題は、複数のワーカーが同じテーブルに書き込んでいて、すべてが同じシーケンスからキーを取得している場合、その結果、ワーカーが同じテーブルに書き込んでいる可能性が高く、インデックス ブロックの周りで競合が発生することです。ブロックします(つまり、待つ必要があります)。
これに対する 1 つの解決策は、逆キー インデックスを使用することです。
もう 1 つの方法は、:worker_number||nanoTime()||random_number() のようなキーを作成することです。
つまり、一意の番号を提供する可能性が非常に高いものです。(たとえば、地球が小惑星に衝突する可能性は、重複した番号を取得するよりも可能性が高い)
シークエンスは嫌いじゃない。シーケンスは素晴らしいです。彼らを愛する!
分散環境では安全です。必要に応じて (トリガーを使用して) 自動インクリメント フィールドを模倣するために使用できますが、事前に ID を取得することもできます。これは、データセットを複数のテーブルに読み込む準備をしていて、挿入する前に ID が必要な場合に最適です。
私はジョナサン・レフラーの彼自身の答えへのコメントを受け入れますが、私にとっては、コントロールのバランスは、独立したシーケンスが ID 生成を提供し、AUTOINCREMENT フィールドを模倣することの比較的容易さをもたらします。