0

少しばかげた質問があります。私のプログラムには、データベースからデータを削除する機能が必要です。ええ、実際には問題ではありません。しかし、他の人が見る危険を冒さずに、何かが削除されたというデータを削除するにはどうすればよいですか。

User Table:
U_ID  U_NAME
1     Chris
2     Peter

OTHER TABLE
ID TIMESTAMP  FK_U_D
1  2012-12-01   1
2  2012-12-02   1

IDはAUTO_INCREMENTなので、そのうちの1つを削除するとギャップが生じます。さらに、タイムスタンプも前の行よりも大きいため、昇順です。

ID 1のデータをユーザーのプロファイル(U_ID 1)から非表示にしたい。

削除するとギャップがあります。FK_U_IDを2(Peter)に変更しただけでは明らかです。データを挿入すると、同じU_IDを持つデータ行が20行または30行あるため、変更が加えられていることは明らかです。

FK_U_IDをNULLに設定した場合->別のU_IDに変更したときと同じsh**。

この作業を行うための解決策はありますか?私以外の誰もデータベースにアクセスできなくても問題はないことを私は知っています。しかし念のため、誰かが私のプログラムを制御している場合、変更があったことは明らかではありません。

だからここに行きます。

4

2 に答える 2

1

削除が実行されたという証拠を「非表示」にする理由はまったく明らかではありません。それは本当に悪い考えのように聞こえます。私は誤った情報を公布するのが好きではありません。

理想的な主キーの2つの特徴は、次のとおりです。-匿名(有用な情報がない、何に設定されているかは関係ありません)-不変(一度割り当てられると、変更されることはありません)。

しかし、その議論全体を脇に置いておくと...


私は少し異なる質問に答えることができます(あなたがあなたの特定の状況に役立つと思うかもしれない答え)

AUTO_INCREMENTを使用して列の値の「ギャップ」を解消する唯一の方法は、列の値を現在の値から連続した新しい値のシーケンスに変更することです。その列を参照する外部キーがある場合は、関係を維持するために、それらの列の値も更新する必要があります。これにより、テーブルの現在のauto_increment値がid列の最大値よりも高くなる可能性が高いため、次の挿入での「ギャップ」を回避するために、これもリセットしたいと思います。

(開発環境とテスト環境でauto_increment値の再シーケンスを実行し、ルックアップテーブルを「クリーンアップ」し、一部のテーブルのID値を他のテーブルの範囲とは異なる範囲に移動しました...SQLをテストしましょうSQL結合述語が誤って間違ったテーブルを参照し、誤って正しく見える行を返さないようにするために...これらがauto_increment値の場合に再割り当てを行った理由です)

ON UPDATE CASCADE外部キー制約がで定義され、無効にされていない限り、主キー値を変更すると、データベースは外部キー値(InnnoDBテーブルの場合)を「自動的に」更新できることに注意してくださいFOREIGN_KEY_CHECKS

処理する外部キーがなく、idの現在の値がすべて正の整数であると仮定すると、次のようなことができます:(適切なバックアップが設定されているので、問題が発生した場合に回復できます正しく動作しません)

UPDATE mytable t
  JOIN (
         SELECT s.id           AS old_id
              , @i := @i + 1   AS new_id
           FROM mytable s
          CROSS
           JOIN (SELECT @i := 0) i
          ORDER BY s.id
       ) c
    ON t.id = c.old_id
   SET t.id = c.new_id
 WHERE t.id <> c.new_id

テーブルAUTO_INCREMENTをリセットして、テーブル内の最大ID値に戻すには:

ALTER TABLE mytable AUTO_INCREMENT = 1;

通常、テーブルを作成し、そのクエリから上記のインラインビュー(別名c)にデータを入力します。次に、そのテーブルを使用して、外部キー列と主キー列の両方を更新します。最初にFOREIGN_KEY_CHECKSを無効にしてから、再度有効にします。(他のプロセスがテーブルの1つから行を挿入/更新/削除している可能性がある並行環境では、もちろん、最初に更新するすべてのテーブルの排他ロックを取得します。)


もう一度取り上げますが、前に取っておいた説明です...このタイプの「管理」機能は、テスト環境でテストケースを設定するときに役立ちます。ただし、ライブデータを使用して本番環境で実行される機能ではありません。

于 2013-01-10T15:42:34.367 に答える
1

IDギャップの問題については、 @ SLaksが提案するようにGUIDを使用できますが、ネイティブRDBMS auto_incrementを使用できません。つまり、GUIDを作成し、作成時に残りのレコードデータと一緒に挿入する必要があります。もちろん、IDがグローバルに一意である必要はありません。20文字などのランダムな文字列を格納するだけで済みますが、DB読み取りを実行して、そのIDが取得されて繰り返されるかどうかを確認する必要があります(再帰的に)未使用のIDが見つかるまでのそのプロセスは...かなり負担になる可能性があります。

于 2013-01-10T15:01:09.773 に答える