使用外鍵快速插入/刪除的表結構
目前情況
我們有一個名為
c
ca300,000 行。在此表中,我們儲存了特定產品的競爭對手。例子:
編號 | 競爭對手 | 關於競爭對手的一些資訊 | 產品 --------------------------------------------------------------- 1 | C_1 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | P_1 2 | C_2 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | P_1 3 | C_3 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | P_1 4 | C_1 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | P_2 5 | C_4 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | P_2
我們每 30 分鐘閱讀一次新的競爭對手。為此,我們首先刪除具有特定產品 (P_1) 的每個人,然後插入新產品。因此,我們的數據庫中永遠不會有競爭對手,目前該產品還沒有列出。
當我們得到新資訊時,我們會對產品進行某種研究。
(我們還有一個名為
p
ca. 100,000 行的表。在該表中,我們儲存有關產品的資訊。)所以回到研究過程。我們遍歷每一種產品,必須讓競爭對手獲得他們的資訊。為此,我們確實做了一個 mysql 請求,例如
SELECT * FROM c WHERE product LIKE "P_1";
. 並不是說這不是很好的表現。我想要實現的目標
p
是,只需一個查詢,我就可以從相同的競爭對手c
那裡product id
。這樣這些資訊就會儲存在這樣的數組中:[0]['id'] => '2' [0]['product_identifier'] => 'P_1' [0]['c'][0]['competitors'] => 'C_1' [0]['c'][1]['competitors'] => 'C_2' [0]['c'][3]['competitors'] => 'C_3'
可能的解決方案
為了通過一個查詢獲得所需的資訊,我想出了這個解決方案。
在表
c
中,產品行包含一個連結到p
表的外鍵。這很容易實現。但我問自己是否可以輕鬆刪除c
或p
行。我從來沒有這麼密集地使用外鍵——在我看來總是會產生一些錯誤。而且我還想知道我是否可以那麼容易地加入,因為我想從
p
相關競爭對手那裡獲得,而不是相反。你知道我的意思?不確定我是否可以這樣做。如果可以的話,如何處理這個外鍵。為了不弄亂不干淨的數據庫,我要尋找什麼。範例
我們將使用
c
上面的表,其中c.product
儲存了表的外鍵p.product_identifier
。像這樣:編號 | 產品標識符 | 關於產品的一些資訊 --------------------------------------------------------------- 1 | P_1 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 2 | P_2 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 3 | P_3 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
我不確定這是如何工作的,或者它是否是一個好主意,但我的查詢看起來如何?如果我想從
SELECT
每個產品p
以及他們的競爭對手那裡獲得c
?
首先,如果您的表是 InnoDB,並且 column
c.P_ID
是 column 的引用p.P_ID
(注意實際的列名可能不同),那麼您絕對應該使用外鍵來避免孤兒,但要知道您必須明確聲明ON DELETE CASCADE
,因為預設值為ON DELETE SET NULL
,保留孤兒。但這與選擇競爭對手的產品和資訊的“單一查詢”沒有任何關係。
達到:
我想實現,只需一個查詢,我就從 p 獲得了產品資訊,還從 c 獲得了競爭對手的產品資訊,其中產品 ID 相同。
您的查詢將使用連接:
SELECT products.P_ID, products.product_name, competitors.info FROM products LEFT JOIN competitors ON competitors.P_ID=products.P_ID
這將使您獲得產品的重複資訊(競爭對手資訊會有所不同)。然後您將使用您的應用程序將該資訊解析為您需要的數組。
如果您想要產品的單行,您可以使用
GROUP_CONCAT
競爭對手的功能:SELECT products.P_ID, products.product_name, GROUP_CONCAT(competitors.info SEPARATOR ',') as competitor_info FROM products LEFT JOIN competitors ON competitors.P_ID=products.P_ID GROUP BY products.P_ID;
您應該注意的一個主要警告:
ON UPDATE|DELETE CASCADE
不會在級聯刪除/更新的行上觸發觸發器:筆記
目前,級聯外鍵操作不啟動觸發器。
CASCADE
如果您想刪除孤立行,這不應該阻止您使用。但你應該意識到這一點。