唯一索引允許為空嗎_關於資料庫索引的基本知識
技術標籤:唯一索引允許為空嗎
來源:https://www.cnblogs.com/aipiaoborensheng/archive/2004/01/13/5202654.html
一、索引
在關係資料庫中,索引是一種與表有關的資料庫結構,它可以使對應於表的SQL語句執行得更快。索引的作用相當於圖書的目錄,可以 根據目錄中的頁碼快速找到所需的內容。
當表中有大量記錄時,若要對錶進行查詢,第一種搜尋資訊方式是全表搜尋,是將所有記錄一一取出,和查詢條件進行一一 對比,然後返回滿足條件的記錄,這樣做會消耗大量資料庫系統時間,並造成大量磁碟I/O操作;第二種就是在表中建立索引,然後在索引中找到符合查詢條件的 索引值,最後通過儲存在索引中的ROWID(相當於頁碼)快速找到表中對應的記錄。
索引是一個單獨的、物理的資料庫結構,它是某個表中一列或若干列值的集 合和相應的指向表中物理標識這些值的資料頁的邏輯指標清單。索引提供指向儲存在表的指定列中的資料值的指標,然後根據您指定的排序順序對這些指標排序。資料庫使用索引的方式與您使用書籍中的索引的方式很相似:它搜尋索引以找到特定值,然後順指標找到包含該值的行。
1、索引優點
加快資料的查詢速度;
建立唯一性索引,保證資料庫表中每一行資料的唯一性;
加速表和表之間的連線;
在使用分組和排序子句進行資料檢索時,可以顯著減少查詢中分組和排序的時間。
2、索引缺點
索引需要佔物理空間
當對錶中的資料進行增加、刪除和修改的時候,索引也要動態的維護,增大的資料庫維護的難度。
二、索引種類
索引有普通索引、唯一索引、逐漸索引和複合索引,這四種。如下將做詳細介紹。
表結構如下:
DROP TABLE if EXISTS users;CREATE TABLE users( id INT(11) NOT NULL AUTO_INCREMENT, -- id INT(11) NOT NULL, username VARCHAR(255) NOT NULL, nickname VARCHAR(255) NOT NULL, age INT(11) NOT NULL DEFAULT 0, gender INT(11) NOT NULL DEFAULT 0, -- 0、男,1、女 email VARCHAR(255) NOT NULL -- , PRIMARY KEY (id))ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
1、普通索引
主要目的是為了加快查詢速度,所以那些最經常出現的查詢條件或排序條件中的列就該建立索引。只要有可能,就應該選擇一個數據最整齊、最緊湊的資料列(如一個整數型別的資料列)來建立索引。
語法:
CREATE INDEX 索引名稱 ON 表名稱(列名稱(長度)|列名稱);
字串型別設定成索引的情況比較多,數值型別也可以設定成索引,這裡只是例項。
2、唯一索引
普通索引允許被索引的資料列包含重複的值。users表中nickname可以重複,而username一般是不允許重複的。如果能確定某個數 據列將只包含彼此各不相同的值,在為這個資料列建立索引的時候就應該用關鍵字UNIQUE把它定義為一個唯一索引。
這麼做的好處是:一是簡化了MySQL 對這個索引的管理工作,這個索引也因此而變得更有效率;二是MySQL每次有新記錄插入資料表時,會自動檢查新記錄的這個欄位的值是否已經在某個記錄的這 個欄位裡出現過了;如果是,MySQL將拒絕插入那條新記錄。唯一索引可以保證某個資料欄位的唯一性,所以唯一索引往往不是為了查詢速度,而是為了保證數 據的不重複。
語法:
CREATE UNIQUE INDEX 索引名稱 ON 表名稱(列名稱(長度)|列名稱);
它與普通索引類似,但不同的是,其索引列的值必須唯一,但允許有空值。
3、主鍵索引
主鍵是一種唯一性索引,但是不能為空。主鍵的唯一性可以加快查詢速度。主鍵一般在建立表的時候指定,也可以通過修改表的方式加入主鍵。
新增主鍵索引的方式有如下兩種:
1)、在建立表的時候就指定
CREATE TABLE users( id INT(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (id))ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2)、修改表的結構設定主鍵的時候指定
ALTER TABLE users MODIFY id INT(10) NOT NULL auto_increment ,ADD PRIMARY KEY (id); -- 設定成主鍵自增,主鍵索引
或
ALTER TABLE users ADD PRIMARY KEY (id); -- 設定主鍵索引
4、組合索引
組合索會使用到表中的多個數據列,這樣查詢的速度會進一步加快。當我需要同時使用多個條件查詢的時候,可以建立組合索引。因為組合索引的查詢速 度要遠遠大於組合索引中每個字讀的單個索引的查詢速度。假如user表有3個單列索引,查詢時這三個列的組合索引會比這是哪個單列索引效率高很多。
建立語法:
CREATE INDEX 索引名稱 ON 表名稱(列名稱1,列名稱2,…,列名稱n); DROP INDEX idx_username_gender ON users;CREATE INDEX idx_username_gender on users(username(11),gender);SHOW INDEX FROM users; -- 檢視所有索引
使用索引儘量注意如下事項:
索引不會包含有NULL值的列
只要列中包含有NULL值都將不會被包含在索引中,複合索引中只要有一列含有NULL值,那麼這一列對於此複合索引就是無效的。所以我們在資料庫設計時不要讓欄位的預設值為NULL。
使用短索引
對於字元型別的欄位建立索引,儘量指定長度,這樣不僅可以提高查詢速度而且可以節省磁碟空間和I/O操作。例如,如果有一個CHAR(255)的列,如果在前10個或20個字元內,多數值是惟一的,那麼就不要對整個列進行索引。
索引列排序
MySQL查詢只使用一個索引,因此如果where子句中已經使用了索引的話,那麼order by中的列是不會使用索引的。因此資料庫預設排序可以符合要求的情況下不要使用排序操作;儘量不要包含多個列的排序,如果需要最好給這些列建立複合索引。
like語句操作
一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。like “%aaa%” 不會使用索引而like “aaa%”可以使用索引。因為索引是從前往後匹配的,不會跳過前面的內容而去匹配後面的內容。
不要在列上進行運算
select * from users where YEAR(adddate)<2007; -- 在每個行上進行運算,將導致索引失效而進行全表掃描
select * from users where adddate
不使用NOT IN和<>操作
MySQL只對,>=,BETWEEN,IN,以及某些時候的LIKE才會使用索引。
組合索引
必須要從左到右依次精確匹配索引,能匹配多少匹配多少,直到最後一個可以匹配範圍索引,只要用了某列範圍索引,後面的列的索引就無效了。
匹配值的範圍查詢(Match a range of values):僅僅使用索引中第1列。即第一列 可以用大於 小於 X>0 and X<1。
匹配部分精確而其它部分進行範圍匹配(Match one part exactly and match a range on another part):可以利用索引查詢last name為Allen,而first name以字母K開始的人。即,第一列 精確匹配,後面一列 範圍匹配。
END PHP開源社群掃描關注 進入”PHP資料“
免費獲取進階
面試、文件、視訊資源