我有三個表,其中之一是一個關係表,例如:SQL和外鍵約束刪除
表人民有主鍵:的peopleid;
表寵物有主鍵:petid;
表自己有兩個外鍵:的peopleid和petid,他們一起作爲現在
我試圖刪除表的人一人給
表自己的主鍵的peopleid,同時,寵物這個人自己應該刪除,以及關係存儲在表自己
請擺脫一些光線,提前致謝!
編輯:我的問題是如何編寫sql來實現這一點。
我有三個表,其中之一是一個關係表,例如:SQL和外鍵約束刪除
表人民有主鍵:的peopleid;
表寵物有主鍵:petid;
表自己有兩個外鍵:的peopleid和petid,他們一起作爲現在
我試圖刪除表的人一人給
表自己的主鍵的peopleid,同時,寵物這個人自己應該刪除,以及關係存儲在表自己
請擺脫一些光線,提前致謝!
編輯:我的問題是如何編寫sql來實現這一點。
我認爲你需要的是ON DELETE CASCADE
。
使用此功能,您可以自動刪除所有表格引用,如果您刪除主鍵行。
就你而言,如果你使用peopleid
刪除一個人,它會自動從Own
表中刪除引用。
樣品SQL語句
CREATE TABLE Own (
peopleid int(11) NOT NULL,
KEY peopleid (peopleid),
FOREIGN KEY (peopleid)
REFERENCES People (peopleid)
ON DELETE CASCADE
) ENGINE=InnoDB;
由於寵物表沒有外鍵百姓餐桌,你需要定義一個觸發自動刪除寵物的條目,當人們條目被刪除。
CREATE TRIGGER pet_delete AFTER DELETE on own
FOR EACH ROW
BEGIN
DELETE FROM Pet
WHERE Pet.petid = old.petid;
END
定義級聯規則和觸發,如果執行後:
DELETE FROM People WHERE peopleid = 3
它將從own
表peopleid = 3
和Pet
表中相應petid
自動刪除條目。
點擊此鏈接瞭解更多詳情。
http://www.mysqltutorial.org/mysql-on-delete-cascade/
MySQL Trigger: Delete From Table AFTER DELETE
ON DELETE CASCADE規則將用於從'own'表中刪除相關行,當刪除'people'表中的行時,但不適用於'寵物'桌。 (因爲外鍵來自引用「pet」表的「自己」表)。 – spencer7593 2014-09-13 05:02:20
是的你是對的。對於寵物桌,在他的回答中提到的一些觸發器需要被定義爲@ spencer7593 – cppcoder 2014-09-13 05:34:11
,寵物可能由多個人擁有。在這種情況下,我不想刪除表Pet中的寵物....我應該如何修改觸發器來實現此目的? – Arch1tect 2014-09-13 07:03:37
一種選擇是使用多表DELETE語句,從所有三個表中刪除行,例如:
DELETE o.*
, t.*
, p.*
FROM pet t
JOIN own o
ON o.petid = t.petid
JOIN people p
ON p.peopleid = o.peopleid
WHERE p.peopleid = :b_peopleid
但是...有一個與外鍵的問題。這些行可能會以違反外鍵約束的順序被刪除。這不是MyISAM的問題,因爲它不強制執行外鍵。但是對於InnoDB,如果定義了外鍵約束,這可能是一個問題。不幸的是,InnoDB沒有(尚未?)支持延遲約束,所以最接近的解決方法,這是暫時禁用國外鍵檢查...
SET foreign_key_checks = 0 ;
那麼DELETE語句,然後重新啓用的外鍵檢查..
SET foreign_key_checks = 1;
但是,這會禁用會話中的所有外鍵檢查,而不僅僅是在DELETE中引用的表上定義的外鍵。所以,這種方法並不理想,因爲可能會引入不一致的數據。 (例如,如果還有另外一個帶有引用pet.petid的外鍵的表,並且我們從pet中刪除了「parent」行,這可能會在引用不存在的「child」表中留下一行鍵)。
從pet
刪除行(s)?
數據模型建議pet
可能與多個people
有關。例如:
pet: petid petname ------ ------- 1 Spot people: peopleid name -------- ------ 2 Jack 3 Jill own: petid peopleid ------- -------- 1 2 1 3
如果我們要刪除「傑克」,我們可以在「自己」(以下簡稱「傑克」和「點」之間的關係刪除相關的行,但在這種情況下,「點」是。也與「Jill」有關,own
中還有一行引用了「Spot」,所以我們不能刪除「Spot」,也沒有將「Spot」與「Jill」的關係刪除。 ,問題是,我們真的想在這種情況下刪除「Spot」嗎?
如果我們確實想刪除「Spot」,我們還需要從中刪除另一行3210也是關於「Spot」和「Jill」的那個。我們可以使用兩個引用own
表;一個得到「Jack」和他自己擁有的pet
之間的關係,另一個得到參照「Spot」的own
行的全部。
DELETE r.*
, t.*
, p.*
FROM pet t
JOIN own r
ON r.petid = t.petid
JOIN own o
ON o.petid = t.petid
JOIN people p
ON p.peopleid = o.peopleid
WHERE p.peopleid = :b_peopleid
在另一方面,如果我們不希望刪除「點」,因爲「吉爾」 /「點」在own
行還引用了「點」,我們也許能夠非常做些什麼類似。 (我不是一個SQL例子這一點。)
一些其他的選擇來處理,可能是可行的爲您的使用情況是BEFORE DELETE觸發器外鍵關係,和/或外ON DELETE
規則主要制約因素。)
如果我們對DELETE從own
引用people
和pet
的外鍵定義CASCADE規則,我們可以允許從own
刪除行。
然後我們可以在我的答案中使用第一個示例DELETE語句,並且我們可以在DELETE列表中省略對o.*
的引用,並且只指定t.*
和p.*
。(我們仍然需要參考own
表在FROM子句中,拿到之間people
(「傑克」)和pet
(「點」)的關係,所以我們知道要刪除的從pet
行。
否則,您可以運行三個單獨的DELETE語句,但執行DELETE語句的順序可能實際上刪除了您需要的信息,以確定需要刪除其他表中的哪些行,這意味着您可能需要查詢表找到要刪除的行,保存該信息,然後按適當的順序執行所需的刪除操作。
這種「刪除」問題的另一種可行方法是模擬刪除,並在行上更新「deleted_flag」類型列。
也就是說,應用程序不是發出DELETE語句,而是發出UPDATE以在每一行上設置特殊用途「deleted_flag」。但是,必須爲此設計應用程序用例,幾乎所有查找「未刪除」數據的查詢都需要合併排除「已刪除」行的謂詞。如果邏輯上刪除的行實際上確實需要從表中刪除,那麼DELETE語句可以由單獨的批處理進程運行。
對此有所瞭解?問題是什麼? – 2014-09-13 04:10:56
@LarryLustig我試圖編寫sql來實現此目的.. – Arch1tect 2014-09-13 04:14:26