mySQL外鍵和主鍵
考慮具有列 id(主鍵)、名稱的表 A 和具有列 id、a_id(與表 A id 列連結的外鍵)、地址的表 B。如果查詢是,列的順序是什麼:
SELECT * FROM B INNER JOIN A ON B.a_id = A.id;
“列序列”是什麼意思?一種解釋與
SELECT *
-*
將按定義順序列出列,首先是 fromB
,然後是 fromA
。
SELECT *
至少對於生產查詢來說,使用它通常是一個壞主意。
最好的方法就是測試!
為了回答您的問題,我執行了以下操作(請參見此處的小提琴):
CREATE TABLE a ( b INTEGER AUTO_INCREMENT NOT NULL PRIMARY KEY, c VARCHAR (50) );
填充它:
INSERT INTO a (c) VALUES ('a1_sdfs'), ('a2_eerre3'), ('a3_sfssdww'), ('a4_sfs'), ('a5_3433443'); SELECT * FROM a;
然後我們創建並填充子表:
CREATE TABLE x ( y INTEGER AUTO_INCREMENT NOT NULL PRIMARY KEY, a_id INTEGER NOT NULL, z VARCHAR (50), CONSTRAINT x_a_fk FOREIGN KEY (a_id) REFERENCES a (b) );
記錄:
INSERT INTO x (a_id, z) VALUES (1, '1_1adad'), (1, '2_1adad'), (1, '3_1adad'), (1, '4_1adad'), (1, '5_1adad'), (1, '6_1adad'), (2, '1_2adad'), (2, '2_2adad'), (2, '3_2adad'), (2, '4_2adad'), (2, '5_2adad'), (2, '6_2adad'), (3, '1_3adad'), (3, '2_3adad'), (3, '3_3adad'), (3, '4_3adad'), (3, '5_3adad'), (3, '6_3adad'), (4, '1_4adad'), (4, '2_4adad'), (4, '3_4adad'), (4, '4_4adad'), (4, '5_4adad'), (4, '6_4adad'), (5, '1_5adad'), (5, '2_5adad'), (5, '3_5adad'), (5, '4_5adad'), (5, '5_5adad'), (5, '6_5adad');
所以,現在我們測試!
首先,我們執行您的查詢:
SELECT * FROM x -- x is the child table - as per the question! INNER JOIN a ON x.a_id = a.b;
結果:
y a_id z b c 1 1 1_1adad 1 a1_sdfs 2 1 2_1adad 1 a1_sdfs 3 1 3_1adad 1 a1_sdfs 4 1 4_1adad 1 a1_sdfs 5 1 5_1adad 1 a1_sdfs ... ... snipped for brevity, see the fiddle for full results! ... 28 5 4_5adad 5 a5_3433443 29 5 5_5adad 5 a5_3433443 30 5 6_5adad 5 a5_3433443
哪個是兩個表,看起來(對於 MySQL 來說可能不常見)是合乎邏輯的,即 table 的欄位在 table 的欄位
x
之前a
。您可以按照查詢表中指定的順序返回結果。如果我們顛倒我們的順序SELECT
:SELECT * FROM a INNER JOIN x ON a.b = x.a_id;
結果:
b c y a_id z 1 a1_sdfs 1 1 1_1adad 1 a1_sdfs 2 1 2_1adad 1 a1_sdfs 3 1 3_1adad .. .. results agains snipped for brevity - see fiddle .. 5 a5_3433443 28 5 4_5adad 5 a5_3433443 29 5 5_5adad 5 a5_3433443 30 5 6_5adad
這次結果是表格的列順序,
a
然後是表格的列順序x
- 再次合乎邏輯(至少在我看來)!這與這篇文章和我對 MySQL 行為的解釋有關!MySQL 查詢結果的排序(顯然)是在 (clustered)
PRIMARY KEY
s 的基礎上完成的 - 這也是合乎邏輯的(並且也發生在小提琴中!)。但是,在上面的連結中,我引用了 Bill Karwin 的話:如果沒有明確的 ORDER BY,目前版本的 InnoDB 會按照它讀取的索引的順序返回行。哪個索引有所不同,但它總是從某個索引中讀取。即使從“表”中讀取實際上也是一個索引——它是主鍵索引。
正如上面的評論,不能保證這在下一個版本的 InnoDB 中會保持不變。您應該將其視為巧合行為,它沒有記錄在案,並且 MySQL 的製造商不承諾不會更改它。
現在,根據您的問題,我搜尋了諸如“SELECT * JOIN 列順序”之類的謂詞 - 我沒有得到任何重要的東西。
在我看來,您不應該依賴MySQL 按給定順序返回列 - 您應該在 SQL 查詢本身中指定所需的列順序!顯然,這沒有記錄在案,因此您今天依賴的行為可能會在未來沒有警告或通知的情況下發生變化 - 而且由於它沒有記錄,您不能為依賴給定的列順序辯護任何先驗理由!
最佳做法是在查詢本身中指定列順序。那麼,就沒有可能的歧義了。如果有人在您的(未指定的)列之間插入一個新列,您的(如果您使用的是一個)框架可能會誤解您的新欄位**?**
讓您自己和所有可能/將要追隨您的同事的生活更輕鬆,請按您需要的順序指定列。這只是一次性的額外輸入,並且將避免將來潛在的、難以發現的錯誤!