1. 程式人生 > >資料庫中的檢視,事物,索引一些介紹及使用

資料庫中的檢視,事物,索引一些介紹及使用

檢視

檢視是一種基於查詢結果產生的虛擬表。

為什麼要有檢視?

當在執行查詢操作時,經常會出現查詢頻率高並且查詢語句非常複雜的情況。 每次都要將複雜的SQL語句重新書寫,非常不便。

比如:顯示每種商品的名字以及對應的商品型別名和品牌名

select goods.name,goods_cates.name,goods_brands.name from goods inner join goods_cates on goods.cate_id = goods_cates.id inner join goods_brands on goods.brand_id = goods_brands.id;

上面的功能實際很簡單,但是書寫起來很頭疼,如果每天還要執行很多次。頭大。。。

如果能將這個查詢的結果儲存下來,下次在使用時,直接使用結果就非常完美了。

這個需求通過檢視就可以完成。

檢視的特性

- 檢視是一個虛擬表,實際它就是一條被封裝起來的 SQL 查詢語句。
- 在使用檢視時,就相當執行了被封裝的複雜SQL查詢語句。
- 檢視不儲存具體的資料。
- 檢視的基本表發生變化,那麼檢視也隨之變化 

定義檢視

檢視在定義時,建議檢視名稱以 v_xxx 形式命名,以便和普通的表區分。 語法:create view 檢視名稱 as select語句;

create view v_goods_info as select goods.name as gname,goods_cates.name as gcname,goods_brands.name as gbname from goods inner join goods_cates on goods.cate_id = goods_cates.id inner join goods_brands on goods.brand_id = goods_brands.id;

檢視檢視

檢視以表的形式體現,通過 show tables 即可檢視檢視。

使用檢視

檢視的作用就是用來查詢,檢視的作用類似將子查詢做了封裝。

select * from v_goods_info;

 

刪除檢視

語法: drop view 檢視名稱

drop view v_goods_info;

 

檢視小結

* 檢視封裝了對多張基本表的複雜操作,簡化使用者操作
* 檢視只是一個虛表,並不儲存任何基本表的表資料,當用戶使用檢視的時候 檢視會從基本表中取出
* 通過檢視可以對使用者展示指定欄位從而遮蔽其他欄位資料,更加安全

事務

事務Transaction,是指作為一個基本工作單元執行的一系列SQL語句的操作,要麼完全地執行,要麼完全地都不執行。

為什麼要有事務?

以下內容出自《高效能MySQL》第三版,瞭解事務的ACID有助於我們更好的理解事務運作。 下面舉一個銀行應用是解釋事務必要性的一個經典例子。假如一個銀行的資料庫有兩張表:支票表(checking)和儲蓄表(savings)。現在要從使用者Jane的支票賬戶轉移200美元到她的儲蓄賬戶,那麼至少需要三個步驟:

> 1. 檢查支票賬戶的餘額高於或者等於200美元。
> 2. 從支票賬戶餘額中減去200美元。
> 3. 在儲蓄帳戶餘額中增加200美元。

上述三個步驟的操作必須打包在一個事務中,任何一個步驟失敗,則必須回滾所有的步驟。

可以用START TRANSACTION語句開始一個事務,然後要麼使用COMMIT提交將修改的資料持久儲存,要麼使用ROLLBACK撤銷所有的修改。事務SQL的樣本如下:
> 1. start transaction;
> 2. select balance from checking where customer_id = 10233276;
> 3. update checking set balance = balance - 200.00 where customer_id = 10233276;
> 4. update savings set balance = balance + 200.00 where customer_id = 10233276;
> 5. commit;

事務的四大特性 ACID

1. 原子性(Atomicity)
>一個事務必須被視為一個不可分割的最小工作單元,整個事務中的所有操作要麼全部提交成功,要麼全部失敗回滾,對於一個事務來說,不可能只執行其中的一部分操作,這就是事務的原子性

2. 一致性(Consistency)
>資料庫總是從一個一致性的狀態轉換到另一個一致性的狀態。(在前面的例子中,一致性確保了,即使在執行第三、四條語句之間時系統崩潰,支票賬戶中也不會損失200美元,因為事務最終沒有提交,所以事務中所做的修改也不會儲存到資料庫中。)

3. 隔離性(Isolation)

>通常來說,一個事務所做的修改在最終提交以前,對其他事務是不可見的。(在前面的例子中,當執行完第三條語句、第四條語句還未開始時,此時有另外的一個賬戶彙總程式開始執行,則其看到支票帳戶的餘額並沒有被減去200美元。)

4. 永續性(Durability)

>一旦事務提交,則其所做的修改會永久儲存到資料庫。(此時即使系統崩潰,修改的資料也不會丟失。)

事務操作

MySQL使用的InnoDB引擎支援事務操作。

+ 開啟事務

開啟事務後執行修改命令,變更會維護到本地快取中,而不維護到物理表中

`begin;`
或
`start transaction;`

+ 提交事務

將快取中的資料變更維護到物理表中

`commit;`

+ 回滾事務

放棄快取中變更的資料 表示事務執行失敗 應該回到開始事務前的狀態

`rollback;`

驗證事務提交

為了檢視效果,需要開啟兩個終端視窗,使用同一個資料庫,操作同一張表。

step 1:

兩個終端同時連線同一個資料庫並查詢同一張表
`select * from goods_cates;`

step 2:

終端1開啟事務,插入資料,檢視
```sql
begin;
insert into goods_cates(name) values('手機')
select * from goods_cates;  -- 插入的資料顯示插入成功了
```

setp 3:

終端2查詢資料
```sql
select * from goods_cates; -- 並沒有看到新資料,因為終端1的操作快取在本地,還沒有提交。隔離性
```

step 4:

終端1提交資料,並查詢 
```sql
commit; -- 提交後,事務完成,原子性操作結束
select * from goods_cates;
```

step 5:

終端2查詢 
```sql
select * from goods_cates; -- 可以查到新資料,一致性,永續性。
```

驗證事務回滾

為了檢視效果,需要開啟兩個終端視窗,使用同一個資料庫,操作同一張表。

step 1:

兩個終端同時連線同一個資料庫並查詢同一張表
`select * from goods_cates;`

step 2:

終端1開啟事務,刪除所有資料,檢視
```sql
begin;
insert into goods_cates(name) values('HIFI播放器');
select * from goods_cates;  -- 插入的資料顯示插入成功了
```

setp 3:

終端2查詢資料
```sql
select * from goods_cates; -- 並沒有看到新資料,因為終端1的操作快取在本地,還沒有提交。隔離性
```

step 4:

終端1因為各種原因不想或不能提交資料,取消之前的操作 
```sql
rollback;
```

step 5:

終端2查詢 
```sql
select * from goods_cates; -- 沒有查到新資料,一致性,永續性。
```

事務小結

事務的存在是解決資料在操作過程中的 ACID 問題。

索引

什麼是索引?

能夠快速查詢資料的線索就稱之為索引。

為什麼需要索引?

思考: 如何在一個圖書館中找到一本書的?

在圖書館中如果沒有其他輔助手段只能一條道走到黑,一本書->一本書的掃。 終於經過1個小時的連續掃描發現你需要看的那本書在一分鐘之前被人借走了。這種就是順序查詢。 圖書館管理員發現這個問題,於是決定減少這樣的(>﹏<)悲劇故事。 為同學們購置了一套圖書館管理系統。 大家要找書籍先在系統上查詢到書籍所在的房屋編號和貨架編號,然後就可以直接大搖大擺的去取書了。 這個房屋編號和貨架編號就是索引。

索引目的

索引的目的在於提高查詢效率。

索引原理

除了詞典,生活中隨處可見索引的例子,如火車站的車次表、圖書的目錄等,它們的原理都是一樣的。 通過不斷的縮小想要獲得資料的範圍來篩選出最終想要的結果。

索引的使用

+ 查看錶中已有索引 
`show index from 表名`
+ 建立索引
`create index 索引名稱 on 表名(欄位名稱(長度))`
    - 如果指定欄位是字串,需要指定長度,建議長度與定義欄位時的長度一致
    - 欄位型別如果不是字串,可以不填寫長度部分

+ 刪除索引:
`drop index 索引名稱 on 表名;`

驗證索引的效率

+ 建立一個新表(不帶索引)
```sql
create table test_index(title varchar(10));
```

+ 準備10萬條資料
```python
from pymysql import connect

def main():
    # 建立Connection連線
    conn = connect(host='localhost',port=3306,database='jddb',user='root',password='123123',charset='utf8')
    # 獲得Cursor物件
    cursor = conn.cursor()
    # 插入10萬次資料
    for i in range(100000):
        cursor.execute("insert into test_index values('ha-%d')" % i)
    # 提交資料
    conn.commit()

if __name__ == "__main__":
    main()
```

+ 查詢驗證
    - 開啟執行時間監測
    `set profiling=1;`

    - 查詢 ha-99999 的資料
    `select * from test_index where title='ha-99999;`

    - 為表 test_index 建立索引 
    `create index title_index on test_index(title(10));`

    -  再次查詢 ha-99999 的資料
    `select * from test_index where title='ha-99999;`

    - 檢視執行時間
    `show profiles;`
    <img src='images/118.png'>

    - 使用 desc 命令也可以檢視索引的效率
    ` desc select * from test_index where title='ha-99999';`
    <img src='images/119.png'>

索引小結:

1. 索引可以明顯提高某些欄位的查詢效率。
1. 但不是所有的表都需要建立索引 
1. 如果表中資料很少,沒有必要建立索引
1. 如果一個表中的資料增刪很頻繁,不能建立索引 ,因為只要資料發生增減,索引就要重新建立。增加了系統開銷,反而慢了。
1. 索引只適合查詢操作頻繁的表。