USERS、CHATBOX、IMAGEBOARDの3つのテーブルを取得しました。ユーザーは (0,N) チャットボックスを持つことができ、チャットボックスは (0,1) イメージボードを持つことができます。ユーザーを削除する必要があります。そのため、チャットボックスの前にイメージボードを削除し、ユーザーの前にチャットボックスを削除する必要があります。リクエストは何ですか?
これは私のスキーマのイメージです:
USERS、CHATBOX、IMAGEBOARDの3つのテーブルを取得しました。ユーザーは (0,N) チャットボックスを持つことができ、チャットボックスは (0,1) イメージボードを持つことができます。ユーザーを削除する必要があります。そのため、チャットボックスの前にイメージボードを削除し、ユーザーの前にチャットボックスを削除する必要があります。リクエストは何ですか?
これは私のスキーマのイメージです:
チャットボックスにはイメージボードへの参照があるため、チャットボックスを削除することはできません。これは、イメージボードへのリンクが失われるためです (残りのすべてのイメージボードのうち、削除されたチャットボックスに属するものがわからないためです。
ただし、chatbox テーブルから参照されているため、imageboard テーブルからは削除できません。imagebox テーブルに chatbox テーブルへの参照が含まれていれば、作業はより簡単になります。
使用されなくなったイメージボードも削除できる場合は、次のように動作するはずです。
delete from chatbox
where fk_username = 'foobar';
delete from imageboard
where not exists (select 1 from chatbox where imageboard.id = chatbox.fk_imagebox);
delete from users
where username = 'foobar';
commit;
別のオプションは、外部キーを延期することです。その後、chatbox テーブルから削除する前に imageboard テーブルから削除できます。これは、延期された制約が実際の delete ステートメントの実行時ではなくコミット時に評価されるためです。延期された制約は、PostgreSQL と Oracle で使用できます。
次のようなパターンを使用します。
BEGIN TRANSACTION
BEGIN TRY
-- delete statements here.
END TRY
COMMIT TRANSACTION;
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
削除ステートメントは次のようになります: (私は mysql をあまり使用しないので、小さな間違いは許してください)
CREATE TEMPORARY TABLE IMAGELIST (
-> ID INT NOT NULL
)
SELECT C.FK_IMAGEBOARD AS ID
FROM CHATBOX C
INTO IMAGELIST
WHERE C.FK_USERNAME = @USERNAME
DELETE FROM CHATBOX WHERE FK_USERNAME = @USERNAME;
DELETE FROM IMAGEBOARD WHERE ID IN
(SELECT ID FROM IMAGELIST)
DELETE FROM USERS WHERE USERNAME = @USERNAME;
テーブルとテーブルon delete cascade
に条件を追加します。そうすれば何もする必要はありません。ユーザーを削除すると、DB がエントリを削除します。users
chatbox
ここでMySQLの例を見つけることができます