web-dev-qa-db-ja.com

ID列の再シード:必要な場合

大学(私は学生です)での最後のレッスンの1つで、講師から、データベース(必要に応じてMySQLサーバー)と、データベースをデータソースとして使用する小さなクライアントアプリを開発するように求められました。

要件の1つは、ID列(すべてのテーブルのPK)が連続している必要があることです。つまり、テーブル行が削除された場合、そのPKは後続の挿入で再利用する必要があります。 RDBMS、PK、およびID列に関する平均的な知識があります。私が理解していることから、そのID列は、行を挿入するときにDBがPKを自動生成できるようにするための手段にすぎません。また、ID列の値は(自然キーでない限り)行属性とは一切関係しません。

この要件(厳密に連続したID列)は私には疑わしいものでした。 IDがシーケンシャルではない(削除によるギャップがある)場合、何が悪いのかを講師に尋ねてみましたが、「ユーザーにとって便利で、データベースを管理するDB管理者にとっても便利」という非常に抽象的な回答を得ました。具体的な例はありません。 「ユーザーにとって便利」という議論は、ビジネスドメインでは何の意味もないため、ばかげているように思われます。

したがって、これらの理由が本当かどうか知りたいのですが。 ID列を再シードする必要がある場合、つまりIDスペースが使い果たされた場合の1つだけを考えることができます。しかし、これは、ID列のタイプが誤って選択された場合の設計上の問題です。テーブルに10億行が含まれている場合、intまたはbigintではなく単純なuniqueidentifierと言います。 ID列がクラスター化インデックスであると仮定します。ID列のギャップがインデックスのパフォーマンスに影響を与える可能性がありますか?多分、私が知らない削除ごとに自動ID列が再シードされる実際の理由は他にもありますか?

前もって感謝します!

11
Crypt32

つまり、テーブル行が削除された場合、そのPKは後続の挿入で再利用する必要があります。

あなたの講師はどの宇宙から来ましたか?

それは非常に非効率的です。これを行おうとすると、パフォーマンスの見通しが10分の1になります。

監査のためにギャップのない数値が必要な場合は、データベースツールから直接ではなく、明示的に作成してください。また、行を削除しないでください。ただし、「削除済み」のフラグを付けてください。このような行は無視する必要があるため、クエリの煩雑さが増します。

MySQLでは、InnoDBは各テーブルに一意のPRIMARY KEYの存在を必要とします。しかし、それは要件の範囲です。キーは文字列にすることもできます。

ギャップは、ユーザーとDBAにとってconveniencenotは不便です。

ギャップレスが便利な1つのケースを考えることができます。一度に100行のグループにチャンク化します。ただし、LIMIT 100,1を使用する簡単な回避策があります。

ギャップはパフォーマンスに影響を与えません。これには、非数値インデックスが含まれます。そして非ユニークなインデックス。そして複合インデックス。

もちろん、IDが不足する可能性があります。 MySQLを使用してから20年近くの間に2回発生するのを見てきました。小惑星にぶつかる心配もあるでしょう。私の物、つまり私に起きている夜の目覚めのリストには載っていません。

ギャップは(少なくとも)から発生します:INSERT IGNOREIODKUREPLACEDELETEROLLBACK(明示的、またはクラッシュが原因)、マルチマスターレプリケーション(Galeraおよびグループレプリケーションを含む)。あなたは本当にそれらの回避策を考え出しますか?!

講師が疑わしいと言っているものは何でも正気チェックしてください。

17
Rick James

ID値の再利用は、一般的にお勧めできません。値は完全に内部で使用されます。その場合、実際の値は重要ではありません。または、外部で使用される場合、値を再利用すると誤認につながる可能性が高くなります。

請求書または注文番号の明らかなケースを取り上げます。これらはID列から簡単に取得され、外部に公開される可能性がありますが、その理由でそれらを再利用することは決してありません。どちらも、混乱させたくない特定のトランザクションを指します。

このような問題を解決することは、企業が合併または買収されたときに大きな手間がかかる可能性があります。意図的にそのような問題を作成しますか?賢くない。

8
jmoreno

PK id値の再利用には問題があり、通常は回避する必要があります。

まず、auto_incrementカラムの実装では、ギャップがないという保証はありません。実際、自動インクリメント列で挿入をロールバックすると、ギャップが発生します。

次に、ギャップIDは、削除されていない既存のデータを参照する可能性があります(FK制約がないため)。それらがシステム外で通信されるメンバー番号に変換される場合、それは潜在的なビジネスIDリスクをもたらします。

第三に、bigint unsigned挿入率が非常に高い場合でも、IDが長時間不足することはありません。

ギャップの最大の問題は、監査の欠陥を主張する監査人に出くわすことです。 DBAにとって、彼らはギャップが存在することとその理由を知っています。

5
danblack

PKを再利用することは悪い考えであるという他の人のコメントをエコーすることはしませんが、ID列を再シードする必要がある場合があります。

PKインデックス自体の破損。

確かに、これはMS-SQLを使用しており、何年も前に使用されていましたが、それでも適切です。何年も前に私が働いている会社では、クライアントが使用するには古すぎてそれらをクローゼットに貼り付けた後、PCを150以上のリモートロケーションのサーバーとして再利用することをお勧めします。換気なし。 120以上の温度のミッションクリティカルなデータベースを実行している非常に小さな部屋に10年前のがらくたのコンピューターが山積みになっていると、良いことになるだけだと私たちは皆知っています。 40%の失敗率のように、私は私のキャリアの選択を再考します。データを会社の本社に複製しますが、多くの場合、これらの障害によりデータベースに問題が発生します。それらの1つは、データベースとレプリケーションプロセスを占有する破損したインデックスを持つデータベースでした。この素晴らしい環境で2回、レプリケーションを修正する唯一のソリューションは、インデックスを再シードしてからレプリケーションを再確立することでした。サーバーを完全に廃棄する前に、後でサーバーを交換しました。

0
user1207758