春節放假沒事,找了本電子書mysql必知必會敲了下。用的工具是有道筆記的markdown文檔類型。mysql
下面是根據大綱已經敲完的章節,可複製到有道筆記的查看,更美觀。git
# 第一章 瞭解SQL
## 什麼是SQL
#### SQL(Structured Query Language)機構化查詢語言,是一種專門與數據庫通訊的語言。
***
### 什麼是數據庫?
#### 數據庫是一個以某種有組織的方式存儲的數據集合。
數據庫(database):保存有組織數據的容器(一般是一個文件或一組文件)
***
### 什麼是表:
#### 某種特定類型數據的結構化清單
***
### 什麼是模式:
模式(schema):關於數據庫和表的佈局及特性的信息
```
graph TD
A[DBMS數據庫管理系統] --> B{DB數據庫}
B --> C((table1))
B --> D((table2))
C --> E[data]
D --> F[data]
```
# 第二章 MySQL簡介
# 第三章 使用MySQL
### MySQL普遍使用的緣由:
- reason
- 成本 - 免費開源,還能夠修改
- 性能 - 執行快
- 可依賴 - 衆多聲望高的公司使用其處理重要數
- 簡單 - 安裝和使用都很簡單
> 數據的全部存儲,檢索管理和處理實際是有DBMS完成的,MySQL是一種DBMS,即一種數據庫軟件。目前最新的穩定版本是5.1
***
> DB是DBMS建立或操做的容器,使用DBMS訪問DB,DB中有一張或多張有關係的表
***
> table中的數據是一種類型的數據或者一個清單
```
graph TD
B[基於文件共享] -->A{DBMS分類}
C[基於客戶機-服務器] -->A
D(Microsoft Access和File Maker桌面應用) -->B
E(MySQL Oracle Microsoft SQL Server) -->C
```
# 第四章 檢索數據
### sql語句
> SQL關鍵字大寫,字段小寫,使代碼更容易閱讀和調試,不必定非要大寫,都小寫也行。
- 查看mysql版本:進入後 show variables like 'version';
- 退出:quit exit ctrl+D
- 顯示錶列
- show columns from customers;
- desc customers;
- describe customers;
- 顯示普遍的服務器狀態:
- show status;
- 顯示建立指定數據庫的MySQL語句:
- show create database youknowyoucan;
- 顯示建立指定表的MySQL語句:
- show create table customers;
- 顯示受權用戶的安全權限:
- show grants;
- 顯示服務器報錯信息:
- show errors;
- 顯示服務器警告信息:
- show warnings;
- 在mysql命令行顯示容許的show語句:
- help show;
- 檢索單列:
- select prod_name from products;
- 檢索多列:
- select prod_id, prod_name, prod_price from products;
- 檢索全部列:
- select * from products;
- 檢索不一樣的行(去重):
- select vend_id from products;[14]
- select distinct vend_id from products;[4]
- 限制結果:
- select prod_name from products limit 5,5;[5,5表從行5開始的5行]【索引從0開始】
- select prod_id, prod_name from products limit 3,4;[從4行開始4行]
- select prod_id, prod_name from products limit 4 offset 3;[同上mysql5纔有]
- 使用徹底限定的表名或列名:
- select products.prod_name from products;
- select products.prod_nsme from youknowyoucan.products;github
# 第五章 排序檢索數據
### sql語句
> sql語句是有子句(clause)組成,排序使用order by子句
- 5.1 排序索引
- select prod_name from products;
- select prod_name from products order by prod_name;
- 5.2 按多個列排序
- select prod_id, prod_price, prod_name from products order by prod_price, prod_name;[價格同樣,按照名排]
- 5.3 指定排序方向(asc/desc)
- select prod_id, prod_price, prod_name from products order by prod_price desc;
- select prod_id, prod_price, prod_name from products order by prod_price desc, prod_name;[以價格降序,名升序]
- select prod_price from products order by prod_price desc limit 1;[找出最貴的]
> order by 必須位於from後,limit必須位於order by以後,不然檢索信息會失真正則表達式
# 第六章 過濾數據
> 本章使用select的where子句指定搜索條件
### sql語句
- 6.1 使用where子句
- select prod_name, prod_price from products where prod_price = 2.50;[相等測試]
> where子句的位置,同時使用order by和where時,order by位於where以後
- 6.2 where子句操做符
- 6.2.1 檢查單個值
- select prod_name, prod_price from products where prod_name = 'fuses';
- select prod_name, prod_price from products where prod_price < 10;
- select prod_name, prod_price from products where prod_price <= 10;
- 6.2.2 不匹配查詢
- select vend_id, prod_name from products where vend_id <> 1003;
- 6.2.3 範圍值查詢 -- between操做符
- select prod_name, prod_price from products where prod_price between 5 and 10;
- 6.2.4 空值檢查 -- null
- select prod_name from products where prod_price is null;
- select cust_id from customers where cust_email is null;
> <>與!=結果同樣;當與字符串列對比時須要將條件字符串加上單引號,若是是數值列進行比較值的話,不須要加單引號。
***
> between x and y -- 是包括x和y的值。
***
> null(no value) 與字段包含0,空字符串或者僅僅包含空格不一樣。算法
# 第七章 數據過濾
> 組合where子句創建跟高級的搜索條件;not和in操做符的學習
### sql語句
- 7.1 組合where子句 -- and與or(操做符)進行鏈接
- 7.1.1 and操做符
- select prod_id, prod_price, prod_name from products where vend_id = 1003 and prod_price <= 10;
- 7.1.2 or操做符
- select prod_id, prod_price, prod_name from products where vend_id = 1003 or prod_price <= 10;
- 7.1.3 計算次序
- select prod_name, prod_price from products where vend_id = 1002 or vend_id = 1003 or prod_price >= 10;
- select prod_name, prod_price from products where (vend_id = 1002 or vend_id = 1003) and prod_price >= 10;
- 7.2 in操做符 -- eg: id in(1,2,3)
- select prod_name, prod_price from products where vend_id in (1002,1003) order by prod_name; --- 等同於下面
- select prod_name, prod_price from products where not in (1002,1003) order by prod_name;
- 7.3 not操做符
- select prod_name, prod_price from products where vend_id = 1002 or vend_id = 1003 order by prod_name;
> and where子句中使用關鍵字,匹配的是符合全部條件的行;or where 子句匹配的是任意一個符合條件行。
***
> and 默認計算順序是優於 or,但and or連用都應加上括號以明確地操做符。
***
> or 也能實現in where子句實現的條件查詢效果,in的優勢:
- 1.使用長的合法清單,in操做符的語法更清楚直觀;
- 2.in使用的次序更好管理,因其使用的操做符更是少
- 3.in執行速度比or快
- 4.in能夠包含其餘select子句,可以動態地創建where子句。sql
# 第八章 用通配符進行過濾
> 知道什麼是通配符;怎樣使用like操做符
- 8.1 like操做符
- 通配符(wildcard):
- 用來匹配值的一部分的特殊字符
- 搜索模式(search pattern):
- 由字面值、通配符或者二者組合構成的搜索條件
- like:
- 指示mysql後跟的搜索模式利用通配符匹配而不是直接相等匹配進行比較
- 8.1.1 百分號(%)通配符
- % --- 表示任意字符出現任意次數 (jet開頭的)
- select prod_id, prod_name from products where prod_name like 'jet%';
- % --- 在任意位置使用 (無論兩端是什麼字符,只要包含anvil)
- select prod_id, prod_name from products where prod_name like '%anvil%';
- % --- 位置中間(以s開頭e結尾)
- select prod_id, prod_name from products where prod_name like 's%e';
- 8.1.2 下劃線(_)通配符
- (_)與%用途同樣可是,下劃線只是匹配單個字符
- select prod_id, prod_name from products where prod_name like '_ ton anvil';
- select prod_id, prod_name from products where prod_name like '%ton anvil';
- 8.2 使用通配符的技巧
- 不要過分使用通配符
- 除非絕對有必要,不要將通配符置於搜索模式的開始處,搜索起來是最慢的。
- 注意通配符的位置數據庫
> 從技術上,like是謂詞(predicate)而不是操做符。
***
> 注意:%不能能夠匹配一個或0個或任意多個
字符,可是不能匹配null值。api
# 第九章 用正則表達式進行搜素
- 9.1 正則表達式介紹
- 正則表達式用來匹配文本的特殊的串(字符集合)
- 全部種類的程序設計語言、文本編輯器、操做系統等都支持正則表達式。
- 9.2 使用MySQL正則表達式
- 9.2.1 基本字符匹配
- select prod_name from products where prod_name regexp '1000' order by prod_name;
- select prod_name from products where prod_name regexp '.000' order by prod_name;
- 9.2.2 進行or匹配 -- |匹配多個串
- select prod_name from products where prod_name regexp '1000|2000' order by prod_name;
- 9.2.3 匹配幾個字符之一 --[]
- select prod_name from products where prod_name regexp '[123 ton]' order by prod_name;【等價於下面】
- select prod_name from products where prod_name regexp '[1|2|3 ton]' order by prod_name;【不一樣於下面】
- select prod_name from products where prod_name regexp '1|2|3 ton' order by prod_name;
- 9.2.4 匹配範圍 -- [0-9]
- select prod_name from products where prod_name regexp '[1-5] ton' order by prod_name;
- 9.2.5 匹配特殊字符 -- 雙反斜槓+.
- select vend_name from vendors where vend_name regexp '.' order by vend_name;【匹配全部的】
```
- select vend_name from vendors where vend_name regexp '\\.' order by vend_name;【匹配.】
```
- 9.2.6 匹配字符類
- 爲了方便工做,可以使用預約義的字符集,稱爲字符類(character class)。
- 9.2.7 匹配多個實例
- 匹配的條件中的字符出現屢次的狀況,由重複元字符來完成。
- select prod_name from products where prod_name regexp '\\([0-9] sticks?\\) order by prod_name';
- select prod_name from products where prod_name regexp '[[:digit:]]{4}' order by prod_name;
- select prod_name from products where prod_name regexp '[0-9][0-9][0-9][0-9]' order by prod_name;
- 9.2.8 特殊定位符
- 匹配特定位置的字符,由定位元字符完成
```
- select prod_name from products where prod_name regexp '^[0-9\\.]' order by prod_name;
```
> ^雙重做用:在集合中表取反,不然,指字符串的開始。
> 簡單正則表達式測試:在不使用數據庫狀況下,select檢測regexp返回0或者1,如 select 'hello' regexp '[0-9]';
***
| 定位元字符| 說明 |
|:------------|:--------|
| ^ |文本的開始|
| $ |文本的結束|
| [[:<:]] |詞的開始 |
| [[:>:]] |詞的結尾 |
***
| 重複元字符 | 說明 |
|:-----------|---------:|
| * |0個或多個匹配|
| + |1個或多個匹配,{1,}|
| ? |0個或1個匹配,{0,1}|
| {n} |指定數目的匹配|
| {n,} |很多於指定數目的匹配|
| {n,m} |匹配數目的範圍m<=255|
***
| 字符類 | 說明 |
|:-----------|---------:|
| [:alnum:] |任意字母和數字[a-z0-9A-Z]|
| [:alpha:] |任意字符[a-zA-Z]|
| [:blank: ]|空格和製表[\\\t]|
| [:cntrl:] |ASCII製表字符(ASCII0-31和127)|
| [:digit:] |任意數字[0-9]|
| [:graph:] |同[:print:可打印任意字符,不包括空格]|
| [:lower: ]|任意小寫字母[a-z]|
| [:print:] |任意可打印字符|
| [:punct:] |不在[:alnum:]和[:cntrl:]中 的任意字符|
| [:space:] |包括空格在內的任意空白符[空白元字符]|
| [:upper:] |任意大寫字母[A-Z]|
| [:xdigit:] |任意十六進制數字[a-fA-F0-9]|
***安全
> like 與 regexp一個重要區別:like 匹配字段,regexp可匹配字段的值,regexp也能夠^$來替代like。
***
> mysql中regexp匹配不區分大小寫,用binary進行區分,格式 -- regexp binary + '條件'
***
> 雙反斜槓加上特殊字符的處理,稱爲轉義(escaping),雙反斜槓也用來引用元字符(特殊意義的字符)
##### 空白元字符服務器
| 元字符 | 說明 |
|:---------|---------|
| \\\f | 換頁 |
| \\\n | 換行 |
| \\\r | 回車 |
| \\\t | 製表 |
| \\\v | 縱向製表|
|都是雙反斜槓|若是匹配\自己須要三個\|
# 第十章 建立計算字段
> 怎麼建立計算字段,以及給字段起別名並引用
- 10.1 計算字段
- 字段(field):基本上與列(column)的意思相同。
- 客戶機與服務器的格式:在sql語句內完成的許多轉換和格式化工做均可以直接在客戶機應用程序內完成。通常在數據庫服務器上完成這些操做比客戶機完成要快得多。
- 10.2 拼接字段
- 拼接(concatenate):將值聯結到一塊兒構成單個值
- mysql的不一樣之處:多數DBMS使用+或||來實現拼接,使用Concat()函數來拼接兩個列。
- select Concat(vend_name,'(',vend_country,')') from vendors order by vend_name;
- 刪除數據右側的多餘空格,用mysql的RTrim()函數來完成。
- select Concat(RTrim(vend_name),'(,RTrim(vend_country),)') from vendors order by vend_name;
- 使用別名
- select Concat(RTrim(vend_name),'(',RTrim(vend_country),')') as vend_title from vendors order by vend_name;
- 10.3 執行算數計算
- select prod_id, quantity, item_price from orderitems where order_num = 20005;
- select prod_id, quantity, item_price, quantity*item_price as expanded_price where item_num = 20005;
- select 測試計算
- select 3*2;--- 6
- select Trim('abc'); --- abc
- select now(); --- 當前時間
> Trim函數,RTrim()去掉串右邊的空格,LTrim()去掉串左邊的空格,Trim()去掉串兩端的空格。
> 導出列:別名有時也稱導出列(derived column)
# 第十一章 使用數據處理函數
- 11.1 函數
- 函數沒有sql的可移植性強:能運行在、在多個系統上的代碼爲可移植性的(portable).
- 11.2 使用函數
- 處理文本串的文本函數
- 在數值數據上進行算數操做的數值函數
- 處理日期和時間值並從這些值中提取特定成分的日期和時間函數
- 返回DBMS正使用的特殊信息的系統函數
- 11.2.1 文本處理函數
- select vend_name, Upper(vend_name) as vend_name_upcase from vendors oeder by vend_name;
- select cust_name, cust_contact from customers where cust_contact = 'Y. Lie';
- select cust_name, cust_contact from customers where Soundex(cust_contact) = Soundex('Y Lie');
- 11.2.2 日期和時間處理函數
- mysql使用的日期格式:yyyy-mm-dd
- select cust_id, order_id from orders where order_date = '2005-09-01';【結果同下】
- select cust_id, order_num from orders where Date(order_date) = '2005-09-01';【更優】
- select cust_id, order_num from orders where Date(order_date) between '2005-09-01' and '2005-09-30';
- select cust_id, order_num from orders where Year(order_date) = 2005 and Month(order_date) = 9;
- 11.2.3 數值處理函數
- 數值處理函數僅處理數值數據。
#### 經常使用數值處理函數
| 函數 | 說明 |
|:---------|---------:|
| Abs() |返回一個數的絕對值|
| Cos() |返回一個數的餘弦|
| Exp() |返回一個數的指數值|
| Mod() |返回除操做的餘數|
| Pi() |返回圓周率|
| Rand() |返回一個隨機數|
| Sin() |返回一個角度的正弦|
| Sqrt() |返回一個數的平方根|
| Tan() |返回一個角度的正切|
***
#### 經常使用日期和時間處理函數
| 函數 | 說明 |
|:---------|---------:|
| AddDate()|增長一個日期|
| AddTime()|增長一個時間|
| CurDate()|返回當前日期|
| CurTime()|返回當前時間|
| Date() |返回日期時間的日期部分|
|DateDiff()|計算兩個日期之間的差值|
|Date_Add()|高度靈活的日期運算函數|
|Date_Format()|返回一個格式化的日期或時間串|
| Day() |返回一個日期的天數部分|
| Hour() |返回一個日期的小時部分|
|DayOfWeek()|返回一個日期對應的星期幾|
| Minute()|返回一個時間的分鐘部分|
| Month() |返回一個日期的月份部分|
| Now() |返回當前日期和時間|
| Second()|返回一個時間的秒部分|
| Time() |返回一個日期時間的時間部分|
| Year() |返回一個日期時間的年份部分|
***
#### 經常使用文本函數說明
| 函數 | 說明 |
|:---------|---------:|
| Left() |返回串左邊的字符|
| Length()|返回串的長度|
| Locate()|找出串的一個子串|
| Lower() |將串轉爲小寫|
| LTrim() |去掉串左邊的空格|
| Right() |返回串右邊的字符|
| RTrim() |去掉串右邊的空格|
| Soundex()|返回穿的SOUNDEX值|
|SubString()|返回字串的字符|
| Upper() |將串轉爲大寫|
> soundex()
是一個將任何文本串轉爲描述其語音表示的字母數字模式的算法。比較相似發音字符和音節,而不是比較字母。
# 第十二章 彙總數據
> 什麼是sql的彙集函數?如何利用它們彙總表的數據?
- 12.1 彙集函數
- 彙集函數(aggregate function)運行在行祖上,計算和返回單個值的函數。mysql給出了5個彙集函數。
- 12.1.1 AVG() 函數
- select AVG(prod_price) as avg_price from products;
- select AVG(prod_price) as avg_price from products where vend_id = 1003;
- 12.1.2 COUNT() 函數
- 兩種使用方式:count(*)--行的數目;count(column)--符合條件的行的數目
- select COUNT(*) as cust_num from customers;
- select COUNT(cust_email) as cust_num from customers;
- 12.1.3 MAX() 函數
- select MAX(prod_price) as max_price from products;
- 12.1.4 MIN() 函數
- select MIN(prod_price) as max_price from products;
- 12.1.5 SUM() 函數
- select SUM(quantity) as items_ordered from orderitems where order_num = 20005;
- select SUM(item_price*quantity) as total_price from orderitems where order_num = 20005;
- 12.2 彙集不一樣值
- distinct(去重) 與 all ,不指定distinct,默認參數爲all
- select AVG(DISTINCT prod_price) as avg_price from products where vend_id = 1003;
- 12.3 組合彙集函數
- select COUNT(*) as num_items, MIN(prod_price) as price_min, MAX(prod_price) as price_max, AVG(prod_price) as price_avg from products;
> distinct 能夠應用count(),不能應用count(*),distinct必須使用列名。
***
> SUM() 忽略null值列。 全部彙集函數都利用標準的算數操做符在多個列上進行計算。
***
> MAX() 通常是計算數值日期的最大值,也可計算文本最大值,若是數據按照相應的列排序,返回的是最後一行。MAX()忽略null值。
***
> COUNT() 在使用COUNT(*)時,列中null值不忽略;使用特定條件計算時,忽略列中null值。
***
> AVG() --- 只用於單個列,得到多個列的平均值,用多個AVG()
> AVG() 忽略null值
#### sql彙集函數
| 函數 | 說明 |
|:---------|---------:|
| AVG() |返回某列的平均值|
| COUNT() |返回某列的行數|
| MAX() |返回某列的最大值|
| MIN() |返回某列的最小值|
| SUM() |返回某列之和|
# 第十三章 分組數據
> 如何分組數據,學習兩個新的select子句:GROUP BY 和HAVING。
- 13.1 數據分組
- 分組把數據分爲多個邏輯組,以便對每一個組進行彙集計算。
- 13.2 建立分組
- select vend_id, COUNT(*) as num_prods from products GROUP BY vend_id;
- select vend_id, COUNT(*) as num_prods from products GROUP BY vend_idWITH ROLLUP;
- 13.3 過濾分組
- HACING很是相似WHERE,全部的where子句均可以用having代替。惟一區別:where過濾行,having過濾分組。
- select cust_id, COUNT(*) as orders from orders GROUP BY cust_id HAVING COUNT(*) >= 2;
- select vend_id, COUNT(*) as num_prods from products where prod_price >= 10 GROUP BY vend_id HAVING COUNT(*) >= 2;
- select vend_id, COUNT(*) as num_prods from products GROUP BY vend_id HAVING COUNT(*) >= 2;
- 13.4 分組和排序
- select order_num, SUM(quantity*item_price) as ordertotal from orderitems GROUP BY
order_num HAVING SUM(quantity*item_price) >= 50;
- select order_num, SUM(quantity*item_price) as ordertotal from orderitems GROUP BY
order_num HAVING SUM(quantity*item_price) >= 50 ORDER BY ordertotal;
- 13.5 select子句順序
***
#### select子句及其順序
| 子句 | 說明 | 是否必須使用 |
|:---------|----------|-----------------:|
| select |要返回的列或者表達式| 是 |
| from |從中檢索數據的表| 僅在從表檢查數據時使用|
| where |行級過濾 | 否 |
| group by|分組說明 |僅在按組計算彙集時使用|
| having |組級過濾 | 否 |
| order by|輸出排序順序| 否 |
| limit |要檢索的行數| 否 |
> group by 必須在where子句以後,order by子句以前。
***
> 使用with rollup關鍵字,獲得每一個分組及每一個分組級別的值,null值組也有返回。
# 第十四章 使用子查詢
> 什麼是子查詢,以及子查詢的使用
- 14.1 子查詢
- mysql4.1或更高版本支持
- 查詢(query)任何sql語句都是查詢,此術語通常只select。
- 子查詢(subquery)即嵌套在其餘查詢中的查詢。
- 14.2 利用子查詢進行過濾
- select order_num from orderitems where prod_id = 'TNT2';
- select cust_id from orders where order_num IN (20005,20007);
- select cust_id from orders where order_num IN (select order_num from orderitems where prod_id = 'TNT2');
- select cust_name, cust_contact from customers where cust_id IN (10001,10004);
- select cust_name, cust_contact from customers where cust_id IN (select cust_id from orders where order_num IN (select order_num from orderitems where prod_id = 'TNT2'));
- 14.3 做爲計算字段使用子查詢
- select cust_name, cust_state, (select COUNT(*) from orders where orders.cust_id = customers.cust_id) as orders from customers order by cust_name;
- 相關子查詢(correlated subquery)涉及外部查詢的子查詢
- select cust_name, cust_state, (select COUNT(*) from orders where cust_id = cust_id) as orders from customers order by cust_name;
> 格式化sql 包含子查詢的select子句難以閱讀和調試,應把子查詢分解爲多行並適當進行縮進,簡化子查詢的使用。
# 第十五章 聯結表
> 什麼是聯結,爲何使用聯結,如何編寫使用聯結的select語句。
- 15.1 聯結
- sql最強大的功能之一是能在數據檢索查詢的執行中聯結(join)表。
- 15.1.1 關係表
- 主鍵(primary key) 惟一標識
- 外鍵(foreign key) 爲某個表中的一列,它包含一個表的主鍵值,定義兩個表之間的關係。
- 可伸縮性(scale)可以適應不斷增長的工做量而不失敗。設計良好的數據庫或應用程序稱之爲可伸縮性好(scale well)。
- 15.1.2 爲何要使用聯結
- 聯結是一種機制,用來在一條select語句中關聯表,所以稱之爲聯結。
- 15.2 建立聯結
- select vend_name, prod_name, prod_price from vendors, products where vendors.vend_id = products.vend_id order by vend_name, prod_name;
- 徹底限定列名:當引用的列可能出現二義性時,必須使用徹底限定列名(用一個點分隔表名和列名),不然,mysql將返回錯誤。
- 15.2.1 where子句的重要性
- 笛卡兒積(cartesian product) 由沒有聯結條件的表關係返回的結果爲笛卡兒積。檢索出的行數將是第一個表中的行數乘以第二個表中的行數。
- select vend_name, prod_name, prod_price from vendors, products order by vend_name, prod_name;
- 15.2.2 內部聯結
- 目前爲止用的聯結稱爲等值聯結(equijoin),它基於兩個表之間的相等測試,這種聯結也成爲內部聯結。
- select vend_name, prod_name, prod_price from vendors
INNER JOIN products ON vendors.vend_id = products.vend_id;
- 15.2.3 聯結多個表
- select prod_name, vend_name, prod_price, quantity from orderitems, products, vendors where products.vend_id = vendors.vend_id and orderitems.prod_id = products.prod_id and order_num = 20005;
- select cust_name, cust_contact from customers where cust_id IN (select cust_id from orders where order_num IN (select order_num from orderitems where prod_id = 'TNT2'));【嵌套的子查詢】
- select cust_name, cust_contact from customers, orders, orderitems where customers.cust_id = orders.cust_id and orderitems.order_num = orders.order_num and prod_id = 'TNT2';【兩個聯結】
> 多作實驗 --- 如上所見,執行一個給定sql操做,通常存在不止一種方法。性能可能會受操做類型、表中的數據量、是否存在索引或鍵以及其餘條件的影響。
***
> 性能考慮 --- mysql在運行時關聯指定每一個表以處理聯結。這種處理可能很是消耗資源,應慎重,不要聯結沒必要要的表。聯結的表越多,性能降低地越厲害。
***
> 使用哪一種語法 -- ANSI SQL規範首選inner join語法。儘管,where子句定義聯結的確比較簡單,但使用明確的聯結語法可以確保不會忘記聯結條件,有時這樣作也能影響性能。
***
> 不要忘了where子句,應保證全部聯結都有where子句,不然,mysql將返回比想要的多得多的數據。
***
> 叉聯結(cross join)有時咱們會聽到返回稱爲叉聯結的笛卡兒積的聯結類型。
# 第十六章 建立高級聯結
> 講解另一些聯結類型/含義/使用方法,如何對被聯結的表使用表別名和彙集函數。
- 16.1 使用表別名
- select Concat(RTrim(vend_name),'(',RTrim(vend_country),')') as vend_title from vendors order by vend_name;
- select cust_name, cust_contact from customers as c, orders as o, orderitems as oi where c.cust_id = o.cust_id and oi.order_num = o.order_num and prod_id = 'TNT2';
- 16.2 使用不一樣類型的聯結
- 迄今爲止,咱們使用的只是稱爲內部聯結或等值聯結(equijoin)的簡單聯結。下面介紹其餘3種聯結:自聯結、天然聯結和外部聯結。
- 16.2.1 自聯結
- 使用表別名能在單條 select語句中不止一次引用相同的表。
- select prod_id, prod_name from products where vend_id = (select vend_id from products where prod_id = 'DTNTR');
- select p1.prod_id, p1.prod_name from products as p1, products as p2 where p1.vend_id = p2.vend_id and p2.prod_id = 'DTNTR';
- 16.2.2 天然聯結
- 天然聯結是這樣一種聯結,其中你只能選擇哪些惟一的列。通常是經過對錶使用select(*)通配符。
- select c.*, o.order_num, o.order_date, oi.prod_id, oi.quantity, oi.item_price from customers as c, orders as o, orderitems as oi where c.cust_id = o.cust_id and oi.order_num = o.order_num and prod_id = 'FB';
- 迄今爲止,咱們創建的每一個內部聯結都是天然聯結。
- 16.2.3 外部聯結
- 聯結包含了那些在相關表中沒有關聯行的行,這個類型的聯結稱爲外部聯結。
- select customers.cust_id, orders.order_num from customers INNER JOIN orders ON customers.cust_id = order.cust_id;
- select customers.cust_id, orders.order_num from customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id;
- select customers.cust_id, orders.order_num from customers RIGHT OUTER JOIN orders ON customers.cust_id = orders.cust_id;
- 16.3 使用帶彙集函數的聯結
- select customers.cust_name, customers.cust_id, COUNT(orders.order_num) as num_ord from customers INNER JOIN orders ON customers.cust_id = orders.cust_id GROUP BY customers.cust_id;
- select customers.cust_name, customers.cust_id, COUNT(orders.order_num) as num_ord from customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id GROUP BY customers.cust_id;
- 16.4 使用聯結和聯結條件
- [ ] 注意使用的聯結類型,通常使用內聯結。
- [ ] 保證使用正確的聯結條件,不然返回不正確的數據。
- [ ] 應該老是提供聯結條件,不然會得出笛卡兒積。
- [ ] 在一個聯結中能夠包含多個表,甚至對於每一個聯結能夠採用不一樣類型的聯結,雖然合法,但應分別測試每一個聯結。
> 沒有*=操做符 --- mysql不支持簡化字符*=和=*的使用,這兩個操做符在其餘DBMS中是很流行。
***
> 外部聯結的類型 --- 作外部聯結和右外部聯結。它們之間的惟一差異是所關聯的表的順序不一樣。即左外部聯結可經過顛倒from和where子句中的表的順序爲由外部聯結。
# 第十七章 組合查詢
> 利用union操做符將多條select語句組合成一個結果集。
- 17.1 組合查詢
- mysql容許執行多個查詢(多條select語句),並將結果做爲單個查詢結果集返回。這些組合查詢一般稱爲並(union)或複合查詢(compound query)。
- 使用組合查詢的狀況:
- 在單個查詢中從不一樣的表返回相似結構的數據
- 對單個表執行多個查詢,按單個查詢返回數據
- 17.2 建立組合查詢
- 17.2.1 使用union
- 在給出的每條select語句之間放上關鍵字union
- select vend_id, prod_id, prod_price from products where prod_price <= 5;
- select vend_id, prod_id, prod_price from products where vend_id IN (1001,1002);
- select vend_id, prod_id, prod_price from products where prod_price <= 5
UNION
select vend_id, prod_id, prod_price from products where vend_id IN (1001,1002);
- 17.2.2 union規則
- [ ] union必須由兩條及兩條以上的select語句組成,語句之間用union關鍵字分開。
- [ ] union中的每一個查詢必須包含相同的列、表達式或彙集函數(不過各個列不須要以相同的次序列出)
- [ ] 列數據類型必須兼容:類型沒必要徹底相同,但必須是DBMS能夠隱含的轉換類型。
- 17.2.3 包含或取消重複行
- union的默認行爲,重複的行自動取消,若是想返回全部匹配的行,可以使用union all。
- select vend_id, prod_id, prod_price from products where vend_id IN (1001,1002);
- select vend_id, prod_id, prod_price from products where prod_price <= 5
UNION ALL
select vend_id, prod_id, prod_price from products where vend_id IN (1001,1002);
- 17.2.4 對組合查詢結構排序
- select語句的輸出用order by子句排序。在使用union組合查詢時,只能用一個order by,出如今最後一個select語句後。mysql實際是用它來排序全部的select語句。
- select vend_id, prod_id, prod_price from products where vend_id IN (1001,1002);
- select vend_id, prod_id, prod_price from products where prod_price <= 5
UNION
select vend_id, prod_id, prod_price from products where vend_id IN (1001,1002) order by vend_id, prod_price;
> 組合不一樣的表 可以使用union組合查詢應用不一樣的表。
# 第十八章 全文本搜索
> 學習如何使用mysql的全文本搜索功能進行高級的數據查詢和選擇。
- 18.1 理解全文本搜索
- 並不是全部的引擎都支持全文本搜索。兩個最經常使用的引擎爲MyISAM和InnoDB,前者支持全文搜索,後者不支持。
- 搜索機制(以前的like、正則)存在幾個重要的限制:
- [ ] 性能 —— 通配符和正則匹配一般匹配表中全部行(這些搜索極少使用表索引)。所以,搜索行增長,搜索可能很是耗時。
- [ ] 明確控制 —— 使用通配符和正則很難明確控制匹配什麼和不匹配什麼。
- [ ] 智能化的結果 —— 雖然基於通配符和正則表達式的搜索提供了很是靈活的搜索,但它們不能提供一種智能化的選擇結果。
- 18.2 使用全文本搜索
- 18.2.1 啓用全文本搜索支持
- 通常在建立表時啓用全文本搜素。create table語句接收FULLTEXT子句,它給出被索引列的一個逗號分隔的列表。
- 不要在導入數據時使用FULLTEXT —— 更新索引要花時間。建立一個新表,應先導入全部數據,再修改表定義FULLTEXT。
- 18.2.2 進行全文搜索
- Match()和Against()執行全文本搜索。
- Match()指定被搜索的列
- Against()指定要使用的搜索表達式
- select note_text from productnotes where Match(note_text) Against('rabbit');
- select note_text from productnotes where note_text like '%rabbit%';【like實現】
- select note_text, Match(note_text) Against('rabbit') as rank from productnotes;
- 18.2.3 使用查詢擴展
- 查詢擴展功能只用於mysql版本4.1.1或更高級的版本
- select note_text from productnotes where Match(note_text) Against('anvils');【未使用只查詢出1條】
- select note_text from productnotes where Match(note_text) Against('anvils' WITH QUERY EXPANSION);
- 18.2.4 布爾文本搜索
- mysql支持全文本搜索的另一種形式,布爾方式(boolean mode)。是個很是緩慢的操做。
- 提供如下細節:
- [ ] 要匹配的詞
- [ ] 要排斥的詞
- [ ] 排列提示
- [ ] 表達式分組
- [ ] 等
- select note_text from productnotes Match(note_text) Against('heavy' IN BOOLEAN MODE);
- select note_text from productnotes Match(note_text) Against('heavy -rope*' IN BOOLEAN MODE);
- select note_text from productnotes Match(note_text) Against('+rabbit +bait' IN BOOLEAN MODE);【包含】
- select note_text from productnotes Match(note_text) Against('rabbit bait' IN BOOLEAN MODE);【或】
- select note_text from productnotes Match(note_text) Against('"rabbit bait"' IN BOOLEAN MODE);【短語】
- select note_text from productnotes Match(note_text) Against('>rabbit <carrot' IN BOOLEAN MODE);【增減等級】
- select note_text from productnotes where Match(note_text) Against('+safe +(<combination)' IN BOOLEAN MODE);
- 18.2.5 全文本搜索的使用說明
- [ ] 短詞(<=3的字符)被忽略且從索引中排除
- [ ] mysql自帶一個內建非用詞(stopword
)列表,全文本搜索時被忽略。
- [ ] 忽略單引號。
- [ ] 不具備詞分隔符的語言不能恰當地返回全文本檢索結果。
- [ ] 僅在MyISAM數據庫引擎中支持全文本搜索。
#### 全文本布爾操做符
| 布爾操做符 | 說明 |
|:---------------|---------:|
| + |包含,詞必須存在|
| - |排除,詞必須存在|
| > |包含,並且增長等級值|
| < |包含,並且減小等級值|
| () |把詞組成子表達式|
| ~ |取消一個詞的排序值|
| * |詞尾的通配符|
| "" |定義一個短語|
***
> 全文本搜索的一個重要部分就是對結果排序,符合條件的文本出現的次序越靠前,優先級越高,越先返回。
***
> 使用完整match()說明 -- 傳遞給match的值必須與FULLTEXT()定義同樣,,若是指定多個列,必須列出它們(次序正確)
***
> 搜索不區分大小寫,除非使用binary方式。
mysql必知必會電子書,所需腳本,能夠在個人github上clone一下:https://github.com/nola222/ySQL.git