數據庫的索引和建表


一、索引

1、聚集索引

平時建表的時候都會為表加上主鍵, 在某些關系數據庫中, 如果建表時不指定主鍵,數據庫會拒絕建表的語句執行。 事實上, 一個加了主鍵的表,並不能被稱之為「表」。一個沒加主鍵的表,它的數據無序的放置在磁盤存儲器上,一行一行的排列的很整齊, 跟我認知中的「表」很接近。如果給表上了主鍵,那么表在磁盤上的存儲結構就由整齊排列的結構轉變成了樹狀結構,類似整個表就變成了一個索引,也就是所謂的「聚集索引」。 這就是為什么一個表只能有一個主鍵, 一個表只能有一個「聚集索引」,因為主鍵的作用就是把「表」的數據格式轉換成「索引(平衡樹)」的格式放置。

上圖就是帶有主鍵的表(聚集索引)的結構圖。其中樹的所有結點(底部除外)的數據都是由主鍵字段中的數據構成,也就是通常我們指定主鍵的id字段。最下面部分是真正表中的數據。

假如我們執行一個SQL語句:

select * from table where id = 98;

首先根據索引定位到98這個值所在的葉結點,然后再通過葉結點取到id等於98的數據行。 這里不講解平衡樹的運行細節, 但是從上圖能看出,樹一共有三層, 從根節點至葉節點只需要經過三次查找就能得到結果。

缺點:平衡樹這個結構必須一直維持在一個正確的狀態, 增刪改數據都會改變平衡樹各節點中的索引數據內容,破壞樹結構, 因此,在每次數據改變時,必須去重新梳理樹(索引)的結構以確保它的正確,這會帶來不小的性能開銷,也就是為什么索引會給查詢以外的操作帶來副作用的原因。

2、非聚集索引

非聚集索引和聚集索引一樣, 同樣是采用平衡樹作為索引的數據結構。索引樹結構中各節點的值來自於表中的索引字段, 假如給user表的name字段加上索引 , 那么索引就是由name字段中的值構成,在數據改變時, DBMS需要一直維護索引結構的正確性。如果給表中多個字段加上索引 , 那么就會出現多個獨立的索引結構,每個索引(非聚集索引)互相之間不存在關聯。 如下圖

 

 

//創建非聚集索引

create index index_birthday on user_info(birthday);

//查詢生日在1995年11月1日出生用戶的用戶名

select user_name from user_info where birthday = '1995-11-01'

這句SQL語句的執行過程如下

首先,通過非聚集索引index_birthday查找birthday等於1995-11-01的所有記錄的主鍵id值。然后,通過得到的主鍵id值執行聚集索引查找,找到主鍵id值對應的真實數據(數據行)存儲的位置。最后,從得到的真實數據中取得user_name字段的值返回,取得最終的結果

非聚集索引和聚集索引的區別在於,通過聚集索引可以查到需要查找的數據, 而通過非聚集索引可以查到記錄對應的主鍵值 ,再使用主鍵的值通過聚集索引查找到需要的數據。

3、復合索引

有一種例外可以不使用聚集索引就能查詢出所需要的數據, 這種索引稱之為「覆蓋索引」查詢, 也就是復合索引或者多字段索引查詢。當為字段建立索引以后,字段中的內容會被同步到索引之中,如果為一個索引指定兩個字段,那么這個兩個字段的內容都會被同步至索引之中。

先看下面這個SQL語句

//創建復合索引

create index index_birthday_and_user_name on user_info(birthday, user_name);

select user_name from user_info where birthday = '1995-11-01'

這句SQL語句的執行過程:

通過非聚集索引index_birthday_and_user_name查找birthday等於1995-11-01的葉節點的內容,葉節點中除了有user_name表主鍵id的值以外user_name字段的值也在里面,因此不需要通過主鍵id值去查找數據行的真實所在,直接取得葉節點中user_name的值返回即可,大大的提高了查詢性能。

4、注意點

最左前綴匹配原則,非常重要的原則

create index index_name_email on user(name,email)

- 最左前綴匹配:必須按照從左到右的順序匹配

select * from user where name='zhangsan'; #可以

select * from user where name='zhangsan'and email='163.com'; #可以

select * from user where email='zhangsan@163.com'; #不可以

 

二、建表

1.新建用戶

1.1 登錄MYSQL:

C:\mysql\mysql-5.6.41-winx64\bin>mysql -u root -p

Enter password: **********

 

1.2 創建用戶:

mysql> insert into mysql.user(Host,User,Password) values("localhost","demo",password("1234"));

這樣就創建了一個名為:demo 密碼為:1234 的用戶。

注意:此處的"localhost",是指該用戶只能在本地登錄,不能在另外一台機器上遠程登錄。如果想遠程登錄的話,將"localhost"改為"%",表示在任何一台電腦上都可以登錄。也可以指定某台機器可以遠程登錄。

 

1.3 然后登錄一下:

mysql>exit;

C:\mysql\mysql-5.6.41-winx64\bin>mysql -u demo -p

Enter password: **********

2.為用戶授權

授權格式:grant 權限 on 數據庫.* to 用戶名@登錄主機 identified by "密碼"; 

2.1 登錄MYSQL(有ROOT權限),這里以ROOT身份登錄:

C:\mysql\mysql-5.6.41-winx64\bin>mysql -u demo -p

Enter password: **********

 

2.2 首先為用戶創建一個數據庫(testDB):

mysql>create database demoDB;

 

2.3 授權test用戶擁有testDB數據庫的所有權限(某個數據庫的所有權限):

mysql>grant all privileges on demoDB.* to demo@localhost identified by '1234';

mysql>flush privileges;//刷新系統權限表

格式:grant 權限 on 數據庫.* to 用戶名@登錄主機 identified by "密碼"; 

 

2.4 如果想指定部分權限給一用戶,可以這樣來寫:

mysql>grant select,update on demoDB.* to demo@localhost identified by '1234';

mysql>flush privileges; //刷新系統權限表

 

2.5 授權test用戶擁有所有數據庫的某些權限:  

mysql>grant select,delete,update,create,drop on *.* to demo@"%" identified by "1234";

//test用戶對所有數據庫都有select,delete,update,create,drop 權限。

//@"%" 表示對所有非本地主機授權,不包括localhost。(localhost地址設為127.0.0.1,如果設為真實的本地地址,不知道是否可以,沒有驗證。)

//對localhost授權:加上一句grant all privileges on demoDB.* to demo@localhost identified by '1234';即可。

3. 刪除用戶

C:\mysql\mysql-5.6.41-winx64\bin>mysql -u demo -p

Enter password: **********

mysql>Delete FROM user Where User='demo' and Host='localhost';

mysql>flush privileges;

mysql>drop database demoDB; //刪除用戶的數據庫

刪除賬戶及權限:>drop user 用戶名@'%';

        >drop user 用戶名@ localhost;

4. 修改指定用戶密碼

C:\mysql\mysql-5.6.41-winx64\bin>mysql -u demo -p

Enter password: **********

mysql>update mysql.user set password=password('新密碼') where User="demo" and Host="localhost";

mysql>flush privileges;

5. 列出所有數據庫

mysql>show database;

6. 切換數據庫

mysql>use '數據庫名';

7. 列出所有表

mysql>show tables;

8. 顯示數據表結構

mysql>describe 表名;

9. 刪除數據庫和數據表

mysql>drop database 數據庫名;

mysql>drop table 數據表名;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM