MySQL(七)
索引
索引就相當於一本書的目錄,通過目錄可以快速的找到對應的資源。
在資料庫方面,查詢一張表的時候有兩種檢索方式:
- 全表掃描
- 根據索引檢索(效率很高)
索引為何能提高檢索效率?
最根本的原理是縮小了掃描的範圍
注意:索引雖然可以提高檢索效率,但是不能隨意新增索引,因為索引也是資料庫當中的物件,也需要資料庫不斷的維護。是有維護成本的,比如:表中的資料經常被修改,這樣就不適合新增索引,因為資料一旦修改,索引需要重新排序,進行維護。
何時考慮給欄位新增索引?
- 資料量龐大(根據客戶需求、根據線上的環境)
- 該欄位很少的DML操作(因為欄位進行修改操作,索引也需要維護)
- 該欄位經常出現在where子句中(經常根據哪個欄位查詢)
主鍵和具有unique約束的欄位自動會新增索引,根據主鍵查詢效率很高,儘量根據主鍵檢索。
建立索引物件
create index 索引名稱 on 表名(欄位名);
select ename,sal from emp where sal = 5000; +-------+---------+ | ename | sal | +-------+---------+ | KING | 5000.00 | +-------+---------+ 檢視SQL語句的執行計劃 explain select ename,sal from emp where sal = 5000; +----+-------------+-------+------+---------------+------+---------+-----+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+-----+------+-------------+ | 1 | SIMPLE | emp | ALL | NULL | NULL | NULL | NULL| 14 | Using where | +----+-------------+-------+------+---------------+------+---------+-----+------+-------------+ 給薪資sal欄位新增索引 create index emp_sal_index on emp(sal); explain select ename,sal from emp where sal = 5000; +----+-------------+-------+------+---------------+---------------+---------+-----+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+---------------+---------+-----+------+-------------+ | 1 | SIMPLE | emp | ref | emp_sal_index | emp_sal_index | 9 |const| 1 | Using where | +----+-------------+-------+------+---------------+---------------+---------+-----+------+-------------+
刪除索引
drop index 索引名稱 on 表名;
drop index emp_sal_index on emp
實現原理
通過B Tree縮小掃描範圍,底層索引進行了排序,分割槽,索引會攜帶資料在表中的實體地址,最終通過索引檢索到資料之後,獲取到關聯的實體地址,通過實體地址定位表中的資料,效率是最高的。
索引的分類
單一索引:給單個欄位新增索引
複合索引:給多個欄位聯合起來新增一個索引
主鍵索引:主鍵上會自動新增索引
唯一索引:有unique約束的欄位上會自動新增索引
…
索引什麼時候失效
select ename from emo where ename like '%A%'; 迷糊查詢的時候,第一個萬用字元使用的是%,這個時候索引是失效的!!!
檢視(view)
站在不同的角度去看到資料(同一張表的資料,通過不同的角度去看待)
建立檢視
注意:只有DQL語句才能以檢視物件的方式創建出來
create view myview as select empno,ename from emp;
刪除檢視
drop view myview;
對檢視進行增刪改查,會影響到原表資料。(通過檢視影響原表資料,不是直接操作原表)
可以對檢視進行CRUD操作
select * from myview;
+------+-------+
|empno | ename |
+------+-------+
| 7369 | SMITH |
| 7499 | ALLEN |
| ... | ... |
+------+-------+
update myview set ename='hehe',sal=1 where empno = 7369;//通過檢視修改原表資料
select * from myview;
+------+-------+
|empno | ename |
+------+-------+
| 1 | hehe |
| 7499 | ALLEN |
| ... | ... |
+------+-------+
delete from myview where empno = 7369;//通過檢視刪除原表資料
select * from myview;
+------+-------+
|empno | ename |
+------+-------+
| 7499 | ALLEN |
| ... | ... |
+------+-------+
檢視的作用
檢視可以隱藏表的實現細節,保密級別較高的系統,資料庫只對外提供相關的檢視。java程式設計師只對試圖物件進行CRUD。
資料庫資料的匯入和匯出
匯出
將資料庫當中的資料匯出
在Windows的dos命令視窗中執行
匯出指定資料庫
mysqldump 資料庫名>D:\資料庫名.sql -uroot -p密碼
匯出指定資料庫當中的指定表
mysqldump 資料庫名 表名>D:\資料庫名.sql -uroot -p密碼
匯入資料
create database 資料庫名;
use 資料庫名;
source D:\資料庫名.sql
資料庫設計三正規化(重點)
設計表的資料,按照這三個正規化設計的表不會出現資料冗餘
-
第一正規化:任何一張表都應該有主鍵,並且每一個欄位原子性不可再分。
-
第二正規化:建立在第一正規化的基礎之上,所有非主鍵欄位完全依賴主鍵,不能產生部分依賴。
多對多?三張表,關係表兩個外來鍵
t_student 學生表 sno(pk) sanme ----------------- 1 張三 2 李四 3 王五 t_teacher 講師表 tno(pk) tname ----------------- 1 王老師 2 張老師 3 李老師 t_student_teacher_relation 學生講師關係表 id(pk) sno(fk) tno(fk) ---------------------------------- 1 1 3 2 1 1 3 2 2 4 2 3 5 3 1 6 3 3
-
第三正規化:建立在第二正規化的基礎之上,所有非主鍵欄位直接依賴主鍵,不能產生傳遞依賴。
一對多?兩張表,多的表加外來鍵
班級t_class cno(pk) cname --------------------- 1 班級1 2 班級2 學生 t_student sno(pk) sname classno(fk) ----------------------------------- 101 張1 1 102 張2 1 103 張3 2 104 張4 2 105 張5 2
一對一怎麼設計
兩種方案,第一種:主鍵共享
t_user_login 使用者登入表
id(pk) username password
-----------------------------
1 zs 123
2 ls 456
t_user_detail 使用者詳細資訊表
id(pk+fk) realname tel
----------------------------
1 張三 11111
2 李四 22222
第二種方案:外來鍵唯一
t_user_login 使用者登入表
id(pk) username password
-----------------------------
1 zs 123
2 ls 456
t_user_detail 使用者詳細資訊表
id(pk) realname tel userid(fk+unique)
---------------------------------------------
1 張三 11111 1
2 李四 22222 2