nvicat-->mysql表設計-->創建索引.
(1)使用ALTER TABLE語句創建索引,其中包括普通索引、UNIQUE索引和PRIMARY KEY索引3種創建索引的格式:
PRIMARY KEY 主鍵索引:mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
NIQUE唯一索引:mysql>ALTER TABLE `table_name` ADD UNIQUE ( `column` )
INDEX普通索引 :mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
FULLTEXT全文索引 :mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column`)
INDEX多列索引:mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
索引名index_name可選,缺省時,MySQL將根據第一個索引列賦一個名稱。另外,ALTER TABLE允許在單個語句中更改多個表,因此可以同時創建多個索引。
(2)使用CREATE INDEX語句對表增加索引。
能夠增加普通索引和UNIQUE索引兩種。其格式如下:
create index index_name on table_name (column_list) ;
create unique index index_name on table_name (column_list) ; #表中有primary Key后不能用uniq index。
說明:table_name、index_name和column_list具有與ALTER TABLE語句中相同的含義,索引名不可選。另外,不能用CREATE INDEX語句創建PRIMARY KEY索引。
(3)刪除索引。
刪除索引可以使用ALTER TABLE或DROP INDEX語句來實現。2881064151DROP INDEX可以在ALTER TABLE內部作為一條語句處理,其格式如下:
drop index index_name on table_name ;
alter table table_name drop index index_name ;
alter table table_name drop primary key ;
其中,在前面的兩條語句中,都刪除了table_name中的索引index_name。而在最后一條語句中,只在刪除PRIMARY KEY索引中使用,因為一個表只可能有一個PRIMARY KEY索引,因此不需要指定索引名。如果沒有創建PRIMARY KEY索引,但表具有一個或多個UNIQUE索引,則MySQL將刪除第一個UNIQUE索引。
如果從表中刪除某列,則索引會受影響。對於多列組合的索引,如果刪除其中的某列,則該列也會從索引中刪除。如果刪除組成索引的所有列,則整個索引將被刪除。
刪除索引的操作,如下面的代碼:
mysql> drop index shili on tpsc ;
Query OK, 2 rows affected (0.08 sec)
Records: 2 Duplicates: 0 Warnings: 0
該語句刪除了前面創建的名稱為“shili”的索引。
索引不一定是唯一所以,是可以加快查詢速度的。
立索引原則:“如何查就如何建”。
索引的建立,唯一的原目的就是為了加快查詢(廣義的查詢),實際上建立索引會使得數據存儲所占空間變大,有時索引所占的空間會查過數據本身的空間。索引的建立也會使得數據插入時變慢,特殊情況下,慢的難以忍受,所以DBA的重要工作之一,就是檢查索引層級並優化。
索引的目的就是希望盡可能的被索引的字段不重復,那么查找的效率就是1,如果完全重復,效率就是N,如果部分重復,那么效率會小於N,視重復量而定。mysql的索引算法是Btree。
為什么重復值高的字段不能建索引(比如性別字段等)

結論(以innodb為例)
a、非聚簇索引存儲了對主鍵的引用,如果select字段不在非聚簇索引內,就需要跳到主鍵索引(上圖中從右邊的索引樹跳到左邊的索引樹),再獲取select字段值
b、如果非聚簇索引值重復率高,那么查詢時就會大量出現上圖中從右邊跳到左邊的情況,導致整個流程很慢
c、如果where值重復率高的字段,select用了limit,只查較少數據,也就是跳的次數很少的情況下,還是可以建索引的(后來想想也沒必要,limit限制了數量,全表掃描也很快,除非字段值是排序的,必須掃描完前面的所有值)
d、如果沒有3這個前提,則不建議在值重復率高的字段上建索引,因為查詢效率低,還需要維護索引
SQL有三個類型的索引,唯一索引 不能有重復,但聚集索引,非聚集索引可以有重復
重要:
(1) SQL如果創建時候,不指定類型那么默認是非聚集索引
(2) 聚集索引和非聚集索引都可以有重復記錄,唯一索引不能有重復記錄。
(3) 主鍵 默認是加了唯一約束的聚集索引,但是也可以在主鍵創建時,指定為唯一約束的非聚集索引,因此主鍵僅僅是默認加了唯一約束的聚集索引,不能說主鍵就是加了唯一約束的聚集索引
有點拗口,可以參考我的博客:主鍵就是聚集索引嗎?
為列創建索引實際上就是為列進行排序,以方便查詢.建立一個列的索引,就相當與建立一個列的排序。
主鍵是唯一的,所以創建了一個主鍵的同時,也就這個字段創建了一個唯一的索引,
唯一索引實際上就是要求指定的列中所有的數據必須不同。
主鍵一唯一索引的區別:
1 一個表的主鍵只能有一個,而唯一索引可以建多個。
2 主鍵可以作為其它表的外鍵。
3 主鍵不可為null,唯一索引可以為null。
聚集索引:將表內的數據按照一定的規則進行排列的目錄。正因為如此,一個表中的聚焦索引只有一個。對此我們要注意“主鍵就是聚焦索引”這是極端錯誤的,是對聚焦索引的一種浪費。(雖然SQLServer默認主鍵就是聚焦索引)使用聚焦索引的最大好處就是按照查詢要求,迅速縮小查詢范圍,避免進行全表掃描。其次讓每個數目都不相同的字段作為聚焦索引也不符合“大數目不同情況下不應建立聚集索引的原則”。
一、索引的作用
1、幫助檢索數據;
2、提高聯接效率;
3、節省ORDER BY、GROUP BY的時間;
4、保證數據唯一性(僅限於唯一索引)。
二、索引的設計
在確定要建立一個索引時,首先我們要確定它是聚集還是非聚集、單列還是多列、唯一還是非唯一、列是升序還是降序、它的存儲是如何的,比如:分區、填充因子等。下面逐條來看:
1、聚集索引
(1)首先指出一個誤區,主鍵並不一定是聚集索引,只是在SQL SERVER中,未明確指出的情況下,默認將主鍵定義為聚集,而Oracle中則默認是非聚集,因為SQL SERVER中的ROWID未開放使用。
(2)聚集索引適合用於需要進行范圍查找的列,因為聚集索引的葉子節點存放的是有序的數據行,查詢引擎可根據WHERE中給出的范圍,直接定位到兩端的葉子節點,將這部分節點頁的數據根據鏈表順序取出即可;
(3)聚集索引盡量建立在值不會發生變更的列上,否則會帶來非聚集索引的維護;
(4)盡量在建立非聚集索引之前建立聚集索引,否則會導致表上所有非聚集索引的重建;
(5)聚集索引應該避免建立在數值單調的列上,否則可能會造成IO的競爭,以及B樹的不平衡,從而導致數據庫系統頻繁的維護B樹的平衡性。聚集索引的列值最好能夠在表中均勻分布。
3、唯一索引
(1)再指出一個誤區,聚集索引並不一定是唯一索引,由於SQL SERVER將主鍵默認定義為聚集索引,事實上,索引是否唯一與是否聚集是不相關的,聚集索引可以是唯一索引,也可以是非唯一索引;
(2)將索引設置為唯一,對於等值查找是很有利的,當查到第一條符合條件的紀錄時即可停止查找,返回數據,而非唯一索引則要繼續查找,同樣,由於需要保證唯一性,每一行數據的插入都會去檢查重復性;
下面是一個簡單的比較表
| 主鍵 | 聚集索引 | |
| 用途 | 強制表的實體完整性 | 對數據行的排序,方便查詢用 |
| 一個表多少個 | 一個表最多一個主鍵 | 一個表最多一個聚集索引 |
| 是否允許多個字段來定義 | 一個主鍵可以多個字段來定義 | 一個索引可以多個字段來定義 |
| 是否允許 null 數據行出現 | 如果要創建的數據列中數據存在null,無法建立主鍵。 創建表時指定的 PRIMARY KEY 約束列隱式轉換為 NOT NULL。 |
沒有限制建立聚集索引的列一定必須 not null . 也就是可以列的數據是 null 參看最后一項比較 |
| 是否要求數據必須唯一 | 要求數據必須唯一 | 數據即可以唯一,也可以不唯一。看你定義這個索引的 UNIQUE 設置。 (這一點需要看后面的一個比較,雖然你的數據列可能不唯一,但是系統會替你產生一個你看不到的唯一列) |
| 創建的邏輯 | 數據庫在創建主鍵同時,會自動建立一個唯一索引。 如果這個表之前沒有聚集索引,同時建立主鍵時候沒有強制指定使用非聚集索引,則建立主鍵時候,同時建立一個唯一的聚集索引 |
如果未使用 UNIQUE 屬性創建聚集索引,數據庫引擎 將向表自動添加一個四字節 uniqueifier 列。 必要時,數據庫引擎 將向行自動添加一個 uniqueifier 值,使每個鍵唯一。此列和列值供內部使用,用戶不能查看或訪問。 |
下面是更加詳細的方法
MySQL中可以使用alter table這個SQL語句來為表中的字段添加索引。
使用alter table語句來為表中的字段添加索引的基本語法是:
ALTER TABLE <表名> ADD INDEX (<字段>);
我們來嘗試為test中t_name字段添加一個索引。
mysql> alter table test add index(t_name);
Query OK, 0 rows affected (0.17 sec)
Records: 0 Duplicates: 0 Warnings: 0
執行成功后,我們來看看結果。
mysql> describe test;
+------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| t_id | int(11) | YES | | NULL | |
| t_name | varchar(50) | NO | MUL | NULL | |
| t_password | char(32) | YES | | NULL | |
| t_birth | date | YES | | NULL | |
+------------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
結果可以看出,t_name字段的Key這一欄由原來的空白變成了MUL。這個MUL是什么意思呢?簡單解釋一下:如果Key是MUL,那么該列的值可以重復,該列是一個非唯一索引的前導列(第一列)或者是一個唯一性索引的組成部分但是可以含有空值NULL。
MySQL創建索引方法:ALTER TABLE和CREATE INDEX的區別
眾所周知,MySQL創建索引有兩種語法,即:
ALTER TABLE HeadOfState ADD INDEX (LastName, FirstName);
CREATE INDEX index_name HeadOfState (LastName, FirstName);
那么,這兩種語法有什么區別呢? 
在網上找了一下,在一個英文網站上,總結了下面幾個區別,我翻譯出來,如下:
1、CREATE INDEX必須提供索引名,對於ALTER TABLE,將會自動創建,如果你不提供;
2、CREATE INDEX一個語句一次只能建立一個索引,ALTER TABLE可以在一個語句建立多個,如:
ALTER TABLE HeadOfState ADD PRIMARY KEY (ID), ADD INDEX (LastName,FirstName);
3、只有ALTER TABLE 才能創建主鍵,
英文原句如下:
With CREATE INDEX, we must provide a name for the index. With ALTER TABLE, MySQL creates an index name automatically if you don’t provide one.Unlike ALTER TABLE, the CREATE INDEX statement can create only a single index per statement. In addition, only ALTER TABLE supports the use of PRIMARY KEY.
