2011-11-05 93 views
0

那麼,我的朋友告訴我,我應該開始使用InnoDB作爲我的數據庫,所以我第一次嘗試。我在刪除記錄/索引/字段/表格時遇到問題。每當我嘗試刪除一條記錄時,我都必須去所有的相關記錄,刪除這些記錄,然後回去刪除我的原始記錄。我無法刪除索引!有沒有更簡單的方法來做到這一點(因爲當我要在PHP中運行,它不會刪除任何東西),還是應該跳回到MyISAM?您認爲哪些更好?如何刪除MySQL InnoDB中的所有相關記錄?

回答

2

如果你喜歡刪除很多東西,InnoDB可能不適合你。 InnoDB比MyISAM嚴格得多。查詢時速度更快(SELECT,SHOW等),但更新速度較慢(UPDATEINSERT等)。

InnoDB的CASCADE是神奇的,但要非常小心。它也很慢(因爲數據庫引擎本身會檢查所有約束條件)。如果您正在處理級聯到其他刪除級聯的其他更新級聯到其他刪除級聯等的記錄,您將等待很長時間。

如果你在開發刪除,並通過InnoDB的約束惱火,你可能會發現SET FOREIGN_KEY_CHECKS = 0;非常有幫助:

SET FOREIGN_KEY_CHECKS = 0; 
/* do all kinds of dangerous deletes, eg. delete everything in the db */ 
SET FOREIGN_KEY_CHECKS = 1; 

不要在應用程序本身使用,或絕對確保你不會破壞任何依賴關係。

+0

是的,數據庫設計已基本完成,但我處於應用程序的早期開發階段,使用密鑰檢查進行測試相當困難,但我認爲我會採取不同的操作而不是刪除操作,因爲我想保留一些有外鍵的數據。 – ItsGreg

3

如果您希望從屬記錄在主表中刪除記錄時自動刪除,則需要在外鍵上指定ON DELETE CASCADE

按照說明書,你的外鍵約束的選擇是其中一個之中:

CASCADE:刪除或更新從父表中的行,並 自動刪除或更新匹配的行孩子桌子。 支持ON DELETE CASCADE和ON UPDATE CASCADE。在 兩個表之間,不要定義在父表或子表中的同一列上執行 的幾個ON UPDATE CASCADE子句。

注意級聯外鍵操作不激活觸發器。

SET NULL:從父表中刪除或更新該行,並將子表中的 外鍵列設置爲NULL。 ON DELETE SET NULL和ON UPDATE SET支持NULL子句。

如果您指定SET NULL操作,請確保您沒有將子表中的列作爲NOT NULL聲明爲 。

限制:拒絕父表的刪除或更新操作。 指定RESTRICT(或NO ACTION)與刪除ON或DELETE子句的ON 相同。

無動作:來自標準SQL的關鍵字。在MySQL中,相當於 RESTRICT。如果引用表中存在相關外鍵值,InnoDB將拒絕父表 表的刪除或更新操作。 某些數據庫系統具有延期檢查,NO ACTION是延期檢查。在MySQL中,外鍵約束立即被檢查 ,所以NO ACTION與RESTRICT相同。

默認的,如果你不指定任何東西,是NO ACTION - 這就是爲什麼你刪除沒有做任何事情現在。

+0

'沒有行動'和'RESTRICT'是完全一樣的東西,功能上,我想。我認爲MySQL同意。 「沒有行動」意味着約束失敗,所以更新是不可能的。 'RESTRICT'也會這樣做。 – Rudie

+0

@Rudie:當然是,「NO ACTION」描述的第一句話是這樣說的。 – Jon

+0

我的不好。沒有看到。至少我從回頭想起它。 – Rudie

0

這正是它應該如何工作。

它保留了所謂的數據完整性。如果你有一個用戶和一個與之關聯的地址,你應該不能刪除用戶,除非你首先刪除一個地址 - 否則你會在數據庫中留下流氓數據。

如果沒有使用ON DELETE CASCADE來強制執行,您的應用程序應負責確保刪除所有相關數據。

一般innoDB是多的保護您的數據的完整性更好地與它所以堅持不回去myISAM(還有什麼每臺發動機是最好的前一個問題,但除非你給我們更多的細節存在沒有意義住在那)。