MySQL數據庫學習筆記(六)----MySQL多表查詢以外鍵、錶鏈接、子查詢、索引

本章主要內容:html

  • 1、外鍵
    面試

  • 2、錶鏈接
    sql

  • 3、子查詢
    數據庫

  • 4、索引ide

1、外鍵:函數

  • 一、什麼是外鍵工具

  • 二、外鍵語法 性能

  • 三、外鍵的條件學習

  • 四、添加外鍵ui

  • 五、刪除外鍵

一、什麼是外鍵:

主鍵是惟一標識一條記錄,不能有重複的,不容許爲空,用來保證數據完整性

外鍵:是另外一表的主鍵, 外鍵能夠有重複的, 能夠是空值,用來和其餘表創建聯繫用的。因此說,若是談到了外鍵,必定是至少涉及到兩張表。例以下面這兩張表:

上面有兩張表:部門表(dept)、員工表(emp)。Id=Dept_id,而Dept_id就是員工表中的外鍵:由於員工表中的員工須要知道本身屬於哪一個部門,就能夠經過外鍵Dept_id找到對應的部門,而後才能找到部門表裏的各類字段信息,從而讓兩者相關聯。因此說,外鍵必定是在從表中建立,從而找到與主表之間的聯繫;從表負責維護兩者之間的關係。

咱們先經過以下命令把部門表和職工表建立好,方便後面的舉例:

複製代碼

create table department(
            id int primary key auto_increment,
            name varchar(20) not null,
            description varchar(100)
);create table employee(
            id int primary key auto_increment,
            name varchar(10) not null,
            gender varchar(2) not null,
            salary float(10,2),
            age int(2),
            gmr int,
            dept_id int);

複製代碼

而後把兩張表的數據填好,顯示效果以下:

部門表:

員工表:

 

二、外鍵的使用須要知足下列的條件:(這裏涉及到了InnoDB的概念)

1. 兩張表必須都是InnoDB表,而且它們沒有臨時表。

注:InnoDB是數據庫的引擎。MySQL常見引擎有兩種:InnoDB和MyISAM,後者不支持外鍵。

2. 創建外鍵關係的對應列必須具備類似的InnoDB內部數據類型。

3. 創建外鍵關係的對應列必須創建了索引。

4. 假如顯式的給出了CONSTRAINT symbol,那symbol在數據庫中必須是惟一的。假如沒有顯式的給出,InnoDB會自動的建立。

面試題:你的數據庫用什麼存儲引擎?區別是?

答案:常見的有MyISAM和InnoDB。

MyISAM:不支持外鍵約束。不支持事務。對數據大批量導入時,它會邊插入數據邊建索引,因此爲了提升執行效率,應該先禁用索引,在徹底導入後再開啓索引。

InnoDB:支持外鍵約束,支持事務。對索引都是單獨處理的,無需引用索引。

 

三、添加外鍵的語法:

有兩種方式:

  • 方式一:在建立表的時候進行添加

  • 方式二:表已經建立好了,繼續修改表的結構來添加外鍵

【方式一】在建立表的時候進行添加

複製代碼

[CONSTRAINT symbol] FOREIGN KEY [id] (從表的字段1)REFERENCES tbl_name (主表的字段2)[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}][ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}

複製代碼

上面的代碼是同一行,中括號裏的內容是可選項。

解釋以下:

CONSTRAINT symbol:能夠給這個外鍵約束起一個名字,有了名字,之後找到它就很方便了。若是不加此參數的話,系統會自動分配一個名字。

FOREIGN KEY:將從表中的字段1做爲外鍵的字段。

REFERENCES:映射到主表的字段2。

ON DELETE後面的四個參數:表明的是當刪除主表的記錄時,所作的約定。

  • RESTRICT(限制)若是你想刪除的那個主表,它的下面有對應從表的記錄,此主表將沒法刪除。

  • CASCADE(級聯)若是主表的記錄刪掉,則從表中相關聯的記錄都將被刪掉。

  • SET NULL:將外鍵設置爲空。

  • NO ACTION:什麼都不作。

注:通常是RESTRICT和CASCADE用的最多。

 

【方式二】表已經建立好了,繼續修改表的結構來添加外鍵

咱們在第一段中內容中已經將表建好了,數據也填充完了,如今來給從表(員工表)添加外鍵,讓它與主表(部門表)相關聯。代碼舉例以下:

ALTER TABLE employee ADD FOREIGN KEY(dept_id) REFERENCES department(id);

代碼解釋:

ALTER TABLE employee:在從表employee中進行操做;

ADD FOREIGN KEY(dept_id):將從表的字段dept_id添加爲外鍵;

REFERENCES department(id):映射到主表department當中爲id的字段。

運行上方代碼後,咱們經過navicat來看一下外鍵有沒有添加成功:

上圖中,選中表employee,單擊紅框部分的「設計表」按鈕,界面以下:

上圖中就能夠看到咱們新建的外鍵了,並且系統默認給這個外鍵起了個名字:employee_ibfk_1。默認規則是RESTRICT。緊接着來給外鍵設置值:

上圖中,咱們打開員工表,而後給外鍵設置值,1表明宣傳部,2表明祕書部。

而後咱們回到主表(部門表),此時若是想刪除id爲1的宣傳部,會彈出以下提示:(由於外鍵的默認規則爲RESTRICT)

四、刪除外鍵:(經過sql語句的方式)

咱們在navicat中能夠經過圖形界面的方式刪除外鍵,也能夠經過sql語句來刪除。

(1)獲取外鍵名:

若是在命令行中不知道外鍵的名字,能夠經過查看錶的定義找出外鍵的名稱:

show create table emp;

運行效果以下:

其實咱們在表的信息中也能夠看到:(注意書寫命令的格式)

(2)刪除外鍵:

alter table emp drop foreign key 外鍵名;

 

2、錶鏈接(join)

咱們如下面的兩張表舉例:做爲本段內容的例子

department部門表:

employee員工表:

其中,外鍵對應關係爲:employee.dept_id=department.id。employee.leader中的數字的含義爲:生命壹號的leader是生命二號,生命二號沒有leader,生命叄號的leader是生命壹號。

一、內鏈接:只列出匹配的記錄

語法:

SELECT … FROM join_table[INNER] JOIN join_table2 
[ON join_condition]WHERE where_definition

解釋:只列出這些鏈接表中與鏈接條件相匹配的數據行。INNER能夠不寫,則默認爲內鏈接。[ON join_condition]裏面寫的是鏈接的條件。

舉例:

select e.name,d.name from employee e inner join department d on e.dept_id=d.id;

等價於:

select e.name,d.name from employee e,department d where e.dept_id=d.id;

運行效果:

二、外鏈接:

外鏈接分類:

  • 左外鏈接(LEFT [OUTER] JOIN)

  • 右外鏈接(RIGHT [OUTER] JOIN)

  • 全外鏈接(FULL [OUTER] JOIN)  注:MySQL5.1的版本暫不支持

語法:

複製代碼

SELECT … FROM join_table1

(LEFT | RIGHT | FULL) [OUTER] JOIN join_table2ON join_conditionWHERE where_definition

複製代碼

解釋:

不只列出與鏈接條件(on)相匹配的行,還列出左表table1(左外鏈接)、或右表table2(右外鏈接)、或兩個表(全外鏈接)中全部符合WHERE過濾條件的數據行。通常都是用左鏈接或者外鏈接。

其中,[OUTER]部分能夠不寫,(LEFT | RIGHT | FULL)部分要寫其中一個。

二、1左外鏈接:左表列出所有,右表只列出匹配的記錄。

舉例:

二、2右外鏈接:右表列出所有,左表只列出匹配的記錄。

舉例:

三、交叉鏈接:

語法:

SELECT … FROM join_table1 CROSS JOIN join_table2;

沒有ON子句和WHERE子句,它返回的是鏈接表中全部數據行的笛卡爾積

笛卡爾積舉例:假設集合A={a,b},集合B={0,1,2},則兩個集合的笛卡爾積爲{(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)}

其結果集合中的數據行數等於第一個表中符合查詢條件的數據行數乘以第二個表中符合查詢條件的數據行數。

等價於:(薦)

SELECT … FROM table1, table2;

舉例:

四、自鏈接參與鏈接的表都是同一張表。(經過給表取別名虛擬出兩張表)

注:很是重要,在JavaWeb中的目錄樹中用的特別多。

舉例:查詢出員工姓名和其leader的姓名(相似於求節點及其父節點)

咱們來詳細解釋一下上面的代碼。對於同一張employee表,咱們把e1做爲員工表,e2做爲領導表。首先把所有的員工列出來(基於左外鏈接),而後找到咱們所須要的條件:員工的經理id(e1.leader)等於經理表的id(e2.id)

 

舉例:查詢出全部leader的姓名。

分析的道理同上。

其實,上面的兩個查詢結果都是下面這個查詢結果的一部分:

 

3、子查詢:

做用:某些狀況下,當進行查詢的時候,須要的條件是另一個select 語句的結果,這個時候,就要用到子查詢。

定義:爲了給主查詢(外部查詢)提供數據而首先執行的查詢(內部查詢)被叫作子查詢。也就是說,先執行子查詢,根據子查詢的結果,再執行主查詢

關鍵字:用於子查詢的關鍵字主要包括 IN、NOT IN、EXIST、NOT EXIST、=、<>等(符號「<>」的意思是:不等於)。

備註:MySQL從4.1開始才支持SQL的子查詢。通常說子查詢的效率低於鏈接查詢(由於子查詢至少須要查詢兩次,即至少兩個select語句。子查詢嵌套也多,性能越低)。錶鏈接均可以用子查詢替換,但反過來講卻不必定。

咱們一下面的這張員工表舉例:

一、舉例:查詢月薪最高的員工的名字

上面的例子中,咱們就是先經過聚合函數查出最高的月薪,而後根據這個值查出對應員工的名字。

二、舉例:查詢出每一個部門的平均月薪

上面的例子中,先將部門進行分類(前提是部門不能爲空),而後分別單獨求出各種中的薪水平均值。

注:這裏咱們沒有用到子查詢,由於比較麻煩。

三、舉例:查詢月薪比平均月薪高的員工的名字(咱們知道,總體的平均工資是250)

疑問:若是要查詢比部門平均工資高的員工,該怎麼寫呢?下面的這種寫法是錯誤的:

 

4、索引

主要內容以下:

  • 一、索引的概念

  • 二、普通索引

  • 三、惟一索引

  • 四、主鍵索引

  • 五、全文索引

  • 六、刪除、禁用索引

  • 七、設計索引的原則

關於索引,推薦的學習連接:

http://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html(大牛)

http://blog.csdn.net/cuidiwhere/article/details/8452997

http://www.cnblogs.com/cq-home/p/3482101.html

 

一、索引的概念:

索引是數據庫中用來提升查詢性能的最經常使用工具。

全部MySQL列類型均可以被索引,對相關列使用索引是提升SELECT操做性能的最佳途徑。索引用來快速地尋找那些具備特定值的記錄,全部MySQL索引都以B-樹的形式保存。

在使用如下操做符時,都會用到相關列上的索引:

  • >、<、>=、<=、<>、IN、 BETWEEN

  • LIKE 'pattern'(pattern不能以通配符開始,即通配符不能放前面,即便放在了前面,索引也無效)

注:索引的值由於不斷改變,因此是它須要維護的。若是數據量較少,建議不用索引。

二、normal普通索引(第一種索引)

  • 方式一:直接建立索引:

語法:

CREATE INDEX 索引名 ON 表名(列名[(length)]…);

舉例:

而後,咱們在表中能夠看到新建立的索引:(咱們能夠在這個navicat的可視化界面中修改索引類型)

 

  • 方式二:修改表時添加索引

語法:

ALTER TABLE 表名 ADD INDEX [索引名] (列名[(length)]…);

 

  • 方式三:建立表的時候指定索引:

CREATE TABLE 表名 ( 表名 ([...],INDEX [索引名] (列名[(length)]…);

注意:若是要建立索引的列的類型是CHAR、VARCHAR類型,length能夠小於字段實際長度;若是是BLOB和TEXT類型,必須指定length。

 

三、unique 惟一索引:(第二種索引)

這種索引和前面的「普通索引」基本相同,但有一個區別:索引列的全部值都必須惟一。例如能夠將×××號做爲索引。

建立方式和上方的普通索引相似。即:將普通索引的「index」改成「unique index」。

 

四、主鍵索引(一種特殊的惟一索引)

主鍵是一種特殊的惟一索引,通常在建立表的時候指定。在 MYSQL 中,當你創建主鍵時,主鍵索引同時也已經創建起來了,沒必要重複設置

記住:一個表只能有一個主鍵,也即只有一個主鍵索引。

 

五、FULLTEXT全文索引:(第三種索引)

MySQL從3.2版開始支持全文索引和全文檢索。在MySQL中,全文索引的索引類型爲FULLTEXT。

MySQL5.0版本只有MyISAM存儲引擎支持FULLTEXT,而且只限於CHAR、VARCHAR和TEXT類型的列上建立。

注:全文索引維護起來很吃力,因此瞭解便可。

建立方式和上方的普通索引相似。即:將普通索引的「index」改成「fulltext index」

 

六、刪除、禁用索引:

通常使用「刪除」,不使用「禁用」。

刪除索引:

語法:

DROP INDEX 索引名 ON 表名

對於MyISAM表在作數據大批量導入時,它會邊插入數據邊建索引。因此爲了提升執行效率,應該先禁用索引,在徹底導入後,再開啓索引。而InnoDB表對索引都是單獨處理的,無需禁用索引。

禁用索引:

ALTER TABLE 表名 DISABLE KEYS;

打開索引:

ALTER TABLE 表名 ENABLE KEYS;

 

七、設計索引的原則:

  • 最適合索引的列是出如今WHERE子句中的列,或鏈接子句(on語句)中指定的列,而不是出如今SELECT後的列。

  • 索引列的值中,不相同的數目越多,索引的效果越好。

  • 使用短索引:對於CHAR和VARCHAR列,只用它的一部分來建立索引,能夠節省索引空間,也會使查詢更快捷。

如:CREATE INDEX part_of_name ON employees(name(10));  這個句子中指定的length長度爲10,就是使用短索引,也就是說取name的前十個字符。

  • 利用最左前綴。

  • 根據搜索的關鍵字創建多列索引。

  • 不要過分索引。維護索引須要成本。

相關文章
相關標籤/搜索