MYSQL數據類型、範式及索引總結

MySQL的數據類型

MySQL數據類型簡介

整數類型、浮點數類型和定點數類型

整數:
不一樣數據類型字節數、取值範圍的對比 如上表所示INT和INTEGER的字節數與取值範圍相同,其實,在MySQL中INT類型和INTEGE類型是同樣的。TYNYINT類型佔用的字節數最小爲1個字節,取值範圍最小;BIGIYNT類型佔用的字節數最大,須要八個字節,取值範圍最大。
容易看出,不一樣整數類型的字節數不一樣,根據不一樣類型所佔的字節數能夠推算出該類型的取值範圍。

sql

默認整數數據類型寬度以下:
Field Type
a tinyint(4)
b smallint(6)
c mediumint(9)
d int(11)
e bigint(20)

MySQL各類數據類型的字段都有寬度限制,默認數據類型寬度剛好爲顯示該數據類型全部的值的寬度。數據庫

1、在整數類型使用時,還可搭配zerofill參數。zerofill參數在數字顯示不足的空間由0來填充。須要注意的是,使用zerofill參數時,MySQL會自動加上UNSIGNED屬性。也就是說該整數類型就只能表示無符號數,期限是寬度比默認寬度小1。
2、以上數據類型的字段能夠設置顯示寬度,可是依然能夠插入大於顯示寬度的值。前提是不超過對應數據類型的默認寬度,由於該數據類型的最大值寬度是小於等於默認寬度的,超過默認寬度至關於超過該數據類型可顯示的最大值,顯然這個值是不可插入的。
3、整數類型還有一個AUTO_INCREMENT屬性。該屬性但是字段變成自增字段,對該字段,每插入一條新的紀錄,該字段都會自增1,自增的初值默認從1開始自增,若是第一條記錄設置了初值就從該記錄開始。(技巧:加上AUTO_INCREMENT的字段,其每一個值都是自動增長的。所以,這個字段不可能出現相同的值;因此,一般用於表中ID字段的約束,ID做爲表的主鍵)。

安全

浮點類型和頂點類型:
浮點和定點的取值範圍 由上表可知,DECIMALl類型和DOUBLE類型的取值範圍同樣,可是DECIMAL的有效取值範圍由 M和D決定,並且DICIMAL 字節數是M+2。也就是說,定點數的存儲空間是根據其精度肯定的。MySQL中能夠指定浮點數和定點數的精度。其基本形式以下
數據類型 (M,D)
數據類型爲float或double;M參數爲精度,是數據的總長度,小數點不佔位置;D參數是標度,指小數點後的長度爲D。


函數

1、雖然以上指定小數精度方法都適合於浮點數和定點數,但不是浮點數的通用標準,除非必要不要使用於浮點數,不然可能會影響數據庫的遷移。
2、若是沒有指定精度,浮點數和定點數都有其默認精度,float和double類型誰都會保存其實際精度。DECIMAL類型的整數位默認是10位,小數位爲0,即默認爲整數。
3、在MySQL中,定點數以字符串的方式存儲。所以,其精度比浮點數要高。並且浮點數會出現偏差,若是要求精度比較高,仍是選擇定點數(DECIMAL)比較安全。

性能

日期與時間類型

五種日期與時間類型的字節數,取值範圍和零值的對比一、YEAR
若是插入的年份信息超出範圍就回插入‘0000’;若是插入‘24’,‘86’,‘0’,‘00’,實際插入的值分別是‘2024’,‘1986’,‘2000’
學習

使用YEAR類型時,要區分0和‘0’。若是插入的是0,存入的年份是0000。若是插入的是‘0’,存入的年份則是2000。‘00’和‘0’的效果相同。編碼

二、TIME類型spa

TIME字段賦值及表示方法以下:設計

‘D HH:MM:SS’格式的字符串;向表中插入‘2 23:50:50’,‘11:11’,‘30’結果以下:code

a
71:50:50
11:11:00
00:00:30

HHMMSS格式的字符串或者HHMMSS格式的數值表示;向表中插入1212十二、‘131313’、‘0’和0。

a
12:12:12
13:13:13
00:00:00
00:00:00

a是TIME 數據類型。使用CURRENT_TIME和NOW()插入系統當前時間。

a
11:48:00
11:48:05

若是插入的TIME值是無效的,系統會提示錯誤,就算插入表中也會被轉換爲00:00:00。

三、DATE類型
‘YYYY-MM-DD’或‘YYYYMMDD’格式的字符串表示;這種方式能夠表達的範圍是‘1000-01-01’~‘9999-12-31;MySql還支持一些不嚴格的語法格式,任何標點均可以用愛作分隔符。
a是DATE數據類型,向表中插入‘1949-10-01’、‘1950#2#3’、‘1951@3@4’和‘19520101’。結果以下

a
1949-10-01
1950-02-03
1951-03-04
1952-01-01

若是向表中插入‘53-01-01’、‘78@1@10’、‘540101’和‘790101’。顯示結果以下

a
2053-01-01
1978-01-01
2054-01-01
1979-01-01

雖然MySQL支持不嚴格語法格式,可是爲了統一通常狀況用‘-’作日期分隔符,‘:’作時間分隔符。一樣可使用CURRENT_DATE()和NOW()插入當前系統的信息。例如:2020-01-02

四、DATETIME類型
DATETIME類型使用8個字節來表示日期和時間。MySQL中以‘YYYY-MM-DDHH:MM:SS’的形式顯示DATETIME類型的值。從其形式能夠看出,DATETIME類型能夠直接用DATE類型和TIME類型組合而成。給DATETME類型的字段賦值的表示方法以下:
‘YYYY-MM-DD HH:MM:SS’或‘YYYYMMDDHHMMSS’格式的字符串表示。
這種方式能夠表達的範圍是‘1000-01-01 00:00:00’~‘9999-12-3123:59:59’。


五、TIMESTAMP類型
TIMESTAMP類型使用4個字節來表示日期和時間。TIMESTAMP類型的範圍是從1970-01-01 08:00:01~2038-01-19 11:14:07。
值得注意的是,TIMESTAMP類型範圍比較小,沒有 DATETIME類型的範圍大。所以,輸入值時要保證在 TIMESTAMP類型的有效範圍內。
下面介紹 TIMESTAMP類型的幾種與DATETIME類型不一樣的形式。內容以下:
(1)使用 CURRENT_TIMESTAMP來輸入系統當前日期與時間。
(2)輸入NULL時,系統會輸入系統當前日期與時間。
(3)無任何輸入時,系統會輸入系統當前日期與時間。
TIMESTAMP類型還有一個很大的特殊點,就是時間是根據時區來顯示的。例如,在東八區插入的TIMESTAMP類型爲2009-09-30 14:21:25。在東七區顯示時,時間部分就變成了13:21:25。在東九區顯示時,時間部分就變成了15:21:25。
若要選擇的時間範圍較大仍是選擇DATETIME合適。







字符串類型

字符串類型包括:CHAR、VARCHAR、BLOB、TEXT、ENUM和SET。
一、CHAR和VARCHAR
CHAR類型的長度是固定的,在建立表時就指定了。其長度能夠是0~255的任意值。例如,CHAR(10O)就是指定CHAR類型的長度爲100。
VARCHAR類型的長度是可變的,在建立表時指定了最大長度。定義時,其最大值能夠取0~~65535之間的任意值。指定VARCHAR類型的最大值之後,其長度能夠在0到最大長度之間。例如,VARCHAR(100)的最大長度是100。可是,不是每條記錄都要佔用100個字節。而是在這個最大值範圍內,使用多少分配多少。VARCHAR類型實際佔用的空間爲字符串的實際長度加1。這樣,便可有效節約系統的空間。


須要注意的是,CHAR類型和VARCHAR類型在空格的存儲上有區別,例如存儲‘123*’,*表明空格,VARCHAR會把空格也保存下來,CHAR類型卻把空格捨棄了。

二、TEXT
TEXT 類型是一種特殊的字符串類型。TEXT只能保存字符數據,如新聞的內容等。TEXT類型包括TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。

4種 TEX類型容許的長度和存儲空間進行對比
從表4.5能夠看出,各類TEXT類型的區別在於容許的長度和存儲空間不一樣。所以在這幾種 TEXT類型中,根據需求選取既能知足須要又最節約空間的類型便可。

三、ENUM
ENUM類型又稱爲枚舉類型。在建立表時,ENUM類型的取值範圍就以列表的形式指定了。其基本形式以下:
屬性名ENUM(‘值1,值2然,值n’)
其中,屬性名參數指字段的名稱;「值n」參數表示列表中的第 n個值,這些值末尾的空格將會被系統直接刪除。ENUM類型的值只能取列表中的一個元素。其取值列表中最多能有65535個值。列表中的每一個值都有一個順序排列的編號,MySQL中存入的是這個編號,而不是列表中的值。


若是ENUM類型加上了NOT NULL屬性,其默認值爲取值列表的第一個元素。若是不加 NOT NULL屬性,ENUM類型將容許插入NULL,並且NULL爲默認值。

四、SET
在建立表時,SET類型的取值範圍就以列表的形式指定了。其基本形式以下。屬性名 SET(值1,值2,值n)
其中,「屬性名」參數指字段的名稱;「值n」參數表示列表中的第n個值,這些值末尾的空格將會被系統直接刪除。其基本形式與ENUM類型同樣。SET類型的值能夠取列表中的一個元素或者多個元素的組合。取多個元素時,不一樣元素之間用逗號隔開。SET類型的值最多隻能是有64個元素構成的組合。
同ENUM類型同樣,列表中的每一個值都有一個順序排列的編號。MySQL 中存入的是這個編號,而不是列表中的值。
插入記錄時,SET字段中的元素順序可有可無。存入MySQL 數據庫後,數據庫系統會自動按照定義時的順序顯示。



SET 和ENUM類型,在插入的值不爲空,且該字段已有指定的元素時,插入的元素如不在預設範圍內就都會報錯。

二進制類型

二進制類型是在數據庫中存儲二進制數據的數據類型。二進制類型包括 BINARY、VARBINARY、BIT、TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。
各類二進制類型進行對比1.BINARY和VARBINARY類型
BINARY類型和 VARBINARY類型都是在建立表時指定了最大長度,其基本形式以下:
字符串類型 (M)
其中,「字符串類型」參數指定了數據類型爲BINARY類型仍是VARBINARY類型;M參數指定了該二進制數的最大字節長度爲M。這與CHAR類型和VARCHAR類型類似。例如,BINARY (10)就是指數據類型爲BINARY類型,其最大長度爲10。
BINARY類型的長度是固定的,在建立表時就指定了。不足最大長度的空間由「O」補全。例如,BINARY (50)就是指定BINARY類型的長度爲50。
VARBINARY 類型的長度是可變的,在建立表時指定了最大長度。指定好了VARBINARY類型的最大值之後,其長度能夠在0到最大長度之間。例如,VARBINARY(50)的最大字節長度是50。可是,不是每條記錄的字節長度都是50。在這個最大值範圍內,使用多少分配多少。VARBINARY類型實際佔用的空間爲實際長度加1。這樣,能夠有效的節約系統的空間。
在這裏插入圖片描述






2.BIT類型
BIT類型也是在建立表時指定了最大長度,其基本形式以下:
BIT( M)
其中,「M」指定了該二進制數的最大字節長度爲M,M的最大值爲64。例如,BIT(4)就是數據類型爲BIT類型,長度爲4。若字段的類型BIT(4),存儲的數據是從0~15。由於,變成二進制之後,15的值爲1111,其長度爲4。若是插入的值爲16,其二進制數爲10000,長度爲5,超過了最大長度。所以,大於等於16 的數是不能插入到BIT(4)類型的字段中的。
在查詢BIT類型類型的數據時,要用BIN(字段名+0)來將值轉換爲二進制顯示。



在這裏插入圖片描述
3. BLOB類型
BLOB類型是一種特殊的二進制類型。BLOB能夠用來保存數據量很大的二進制數據,如圖片等。BLOB類型包括TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。這幾種 BLOB 類型最大的區別就是可以保存的最大長度不一樣。LONGBLOB 的長度最大,TINYBLOB的長度最小。
BLOB類型與TEXT類型很相似。不一樣點在於BLOB類型用於存儲二進制數據,BLOB類型數據是根據其二進制編碼進行比較和排序。而 TEXT類型是文本模式進行比較和排序的。


技巧:BLOB類型主要用來存儲圖片、PDF文檔等二進制文件。一般狀況下,能夠將圖片、PDF文檔均可以存儲在文件系統中,而後在數據庫中存儲這些文件的路徑。這種方式存儲比直接存儲在數據庫中簡單,可是訪問速度比存儲在數據庫中慢。

MySQL數據類型選擇

整數類型與浮點類型的選擇:

是否須要表達小數,要表達小數就用浮點型,反之就用整數類型

浮點數與定點數的選擇:

FLOAT,須要小數時通常使用float類型
DOUBLE,須要小數而且要求精度時使用double類型
DECIMAL,須要自定義精度時使用定點數類型,要求更高精度時也可使用定點數(由於MySQL中定點數以字符串存儲)。

日期與時間數據類型的選擇:

YEAR僅用到年份信息就是用YEAR類型

DATE不使用時分秒,僅用於日期

TIME 類型專門用來存儲時間數據(時分秒), 並且僅佔三個字節。若是須要記錄時間,TIME類型最合適。

DATETIME類型用於記錄日期和時間,其做用等價於DATE類型和TIME類型的組合。一個DATETIME類型的字段能夠用一個DATE類型的字段和一個TIME類型的字段代替。可是,若是須要同時記錄日期和時間,選擇DATETIME類型是個不錯的選擇。

雖然TIMESTAMP表示範圍較DATETIME小,可是TIMESTAMP是根據時區顯示,若是跨時區使用時間TIMESTAMP較好。

CHAR類型和VARCHAR類型的選擇:

CHAR類型的長度是固定的,而 VARCHAR類型的長度是在範圍內可變的。所以,VARCHAR類型佔用的空間比CHAR類型小。並且,VARCHAR類型比CHAR類型靈活。對於長度變化比較大的字符串類型,最好是選擇VARCHAR類型。
雖然CHAR類型佔用的空間比較大,可是CHAR類型的處理速度比VARCHAR快。所以,對於長度變化不大和查詢速度要求較高的字符串類型,最好選擇CHAR類型。

ENUM類型和SET類型的選擇:

ENUM類型最多能夠有65535個成員,而SET類型最多隻能包含64個成員。二者的取值只能在成員列表中選取。ENUM類型只能從成員中選擇一個,而SET類型能夠選擇多個。
所以,對於多個值中選取一個的,能夠選擇ENUM類型。例如,「性別」字段就能夠定義成ENUM類型,由於只能在「男」和「女」中選其中一個。對於能夠選取多個值的字段,能夠選擇SET類型。例如,「愛好」字段就能夠選擇SET 類型,由於可能有多種愛好。

TEXT類型和BLOB類型:
TEXT類型與BLOB類型很相似。TEXT類型存儲只能存儲字符數據。而BLOB類型能夠用於存儲二進制數據。若是要存儲文章等純文本的數據,應該選擇TEXT類型。若是須要存儲圖片等二進制的數據,應該選擇BLOB類型。
TEXT類型包括TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。這4者最大的不一樣是內容的長度不一樣。TINYTEXT類型容許的長度最小,LONGTEXT 類型容許的長度最大。BLOB類型也是如此。

MySQL範式

MySQL範式介紹

應用數據庫範式能夠帶來許多益處,大概總結爲三點:
1)減小數據冗餘(這是最主要的好處,其餘好處都是由此而附帶的)
2)消除異常(插入異常,更新異常,刪除異常)
3)讓數據組織的更加簡介簡潔便利


可是數據庫範式絕對不是越高越好;由於範式越高,意味着表越多,多表聯合查詢的概率就越大,SQL查詢的效率就變低了。
通常開發中只聽從第三範式就好,是具體狀況而定。

第一範式:每個數據項都是不可再分的,即表中每一列具備原子性

列都是基本數據項,不可以再進行分割,不然設計成一對多的實體關係。例如表中的地址字段,能夠再細分爲省,市,區等不可再分割(即原子特性)的字段,以下:
列是基本數據項、不能再進行擦縫,不然設計成一對多的關係
不知足第一範式不能稱之爲關係型數據庫
在這裏插入圖片描述


拆分改造後:
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/2021010213200410在這裏插入圖片描述
.png)

學生表(學號、用戶名、性別、年齡,地址)
例:陝西省西安市西安工大學
例:陝西省西安市未央區學府中路西安工業大學
地址信息還包含省市區能夠拆分
拆分改造後:
學生表(學號、用戶名、性別、年齡、地址ID)
地址表(地址ID、省、市、區、街道、學校)





上圖的表就是把地址字段分紅更詳細的city,country,street三個字段,注意,不符合第一範式不能稱做關係型數據庫。

第二範式:非主屬性徹底依賴於主鍵(主要針對聯合主鍵-》消除部分依賴)
符合第一範式的基礎上,非主屬性徹底依賴於主關鍵字,若是不是徹底依賴主鍵,應該拆分紅新的實體,設計成一對多的實體關係。
示例:
假定選課關係表爲SelectCourse(學號, 姓名, 年齡, 課程名稱, 成績, 學分),關鍵字爲組合關鍵字(學號, 課程名稱),由於存在以下決定關係:
(學號, 課程名稱) → (姓名, 年齡, 成績, 學分)
這個數據庫表不知足第二範式,由於存在以下決定關係:
(課程名稱) → (學分)
(學號) → (姓名, 年齡)
即存在組合關鍵字中的字段決定非關鍵字的狀況。
因爲不符合2NF,這個選課關係表會存在以下問題:
(1) 數據冗餘:
同一門課程由n個學生選修,」學分」就重複n-1次;同一個學生選修了m門課程,姓名和年齡就重複了m-1次。
(2) 更新異常:
若調整了某門課程的學分,數據表中全部行的」學分」值都要更新,不然會出現同一門課程學分不一樣的狀況。
(3) 插入異常:
假設要開設一門新的課程,暫時尚未人選修。這樣,因爲尚未」學號」關鍵字,課程名稱和學分也沒法記錄入數據庫。
(4) 刪除異常:
假設一批學生已經完成課程的選修,這些選修記錄就應該從數據庫表中刪除。可是,與此同時,課程名稱和學分信息也被刪除了。很顯然,這也會致使插入異常。
示例2:

















學生選課表(學生ID、學生姓名、學生性別、課程ID、課程成績)
主鍵(學生ID、課程Id)
學生姓名-》學生ID -》部分依賴
學生性別-》學生ID -》部分依賴
課程成績-》(學生ID、課程id)-》徹底依賴
拆分改造後:
學生表(學生ID、學生姓名、學生性別) 主鍵:學生ID
課程成績表(課程ID、學生ID、成績) 主鍵:(課程ID、學生ID)
示例:選課關係表爲SelectCourse(學號, 姓名, 年齡, 課程名稱, 成績, 課程所佔學分),(學號,課程名稱)是聯合主鍵,可是學分字段只和課程名稱有關,和學號無關,至關於只依賴聯合主鍵的其中一個字段,不符合第二範式。







第三範式:屬性不依賴於其它非主屬性(消除依賴傳遞)
基於第二範式的基礎,非主屬性只依賴於主屬性
要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。
示例:學生表(學生ID、學生姓名、學生性別、學院id、學院電話)
主鍵:學生ID
學生姓名-》學生ID
學生性別-》學生ID
學院名稱-》學生ID
學院電話 -》 學生ID -》查詢學院id-》查詢學院電話







數據冗餘、更新異常、插入異常和刪除異常的狀況一樣存在。

拆分改造後:
學生表:(學生ID、學生姓名、學生性別、學院ID)主鍵:學生ID
學院表:(學院ID、學院名稱、學院電話) 主鍵:學院ID

示例:學生關係表爲Student(學號, 姓名, 年齡, 課程, 成績),學號是主鍵,可是學院 電話只依賴於所在學院,並不依賴於主鍵學號,所以該設計不符合第三範式,應該把學院專門設計成一張表,學生表和學院表,兩個是一對多的關係。

BCNF範式:每個決定屬性集都包含候選鍵,也就是隻有一個候選鍵才能夠達到這種狀況;

簡單的說,BC範式是在第三範式的基礎上的一種特殊狀況,即每一個表中只有一個候選鍵(在一個數據庫中每行的值都不相同,則可稱爲候選鍵);(能夠有多個決定屬性集,決定屬性集中一定含有嗎)

假設倉庫管理關係表爲StorehouseManage(倉庫ID, 存儲物品ID, 管理員ID, 數量),且有一個管理員只在一個倉庫工做;一個倉庫能夠存儲多種物品。這個數據庫表中存在以下決定關係:
主鍵(倉庫ID,管理員ID, 存儲物品ID)
(倉庫ID,管理員ID, 存儲物品ID) → (數量)
可是咱們發現:
(倉庫ID, 存儲物品ID) →(管理員ID, 數量)
(管理員ID, 存儲物品ID) → (倉庫ID, 數量)
因此,(倉庫ID, 存儲物品ID)和(管理員ID, 存儲物品ID)都是StorehouseManage的候選關鍵字,表中的惟一非關鍵字段爲數量,它是符合第三範式的。可是,因爲存在以下決定關係:
(倉庫ID) → (管理員ID)
(管理員ID) → (倉庫ID)
即存在關鍵字段決定關鍵字段的狀況,因此其不符合BCNF範式。它會出現以下異常狀況:
(1)數據冗餘
(2)刪除異常:
當倉庫被清空後,全部」存儲物品ID」和」數量」信息被刪除的同時,」倉庫ID」和」管理員ID」信息也被刪除了。
(3)插入異常:
當倉庫沒有存儲任何物品時,沒法給倉庫分配管理員。
(4)更新異常:
若是倉庫換了管理員,則表中全部行的管理員ID都要修改。
把倉庫管理關係表分解爲二個關係表:
倉庫管理:StorehouseManage(倉庫ID, 管理員ID);
倉庫:Storehouse(倉庫ID, 存儲物品ID, )。
這樣的數據庫表是符合BCNF範式的,基本消除了刪除異常、插入異常和更新異常。



















第四範式:消除表中的多值依賴

簡單來講,第四範式就是要消除表中的多值依賴,也就是說能夠減小維護數據一致性的工做。

對於數據庫範式進行分解的過程當中不難看出,應用的範式越高,表越多。表多會帶來不少問題:
1 查詢時須要鏈接多個表,增長了SQL查詢的複雜度
2 查詢時須要鏈接多個表,下降了數據庫查詢性能
所以,並非應用的範式越高越好,要看實際狀況而定。第三範式已經很大程度上減小了數據冗餘,而且基本預防了數據插入異常,更新異常,和刪除異常了。




MySQL範式聯繫與轉化

在這裏插入圖片描述由上圖可知,範式越高所包含的範圍與小;所以能夠理解第幾範式能向高級範式分解,以解決數據操做的各類異常。
分解其實就是把可能造成另外一個關係的屬性列拿出來建立一個新的表,或者對一些能夠繼續分解的屬性列分解爲另外一個關係。

MySQL索引

索引的含義及特色

索引的含義:建立在表上的,對數據庫中一列或者多列的值進行排序的一種結構。索引能夠提升查詢速度。

不一樣的存儲引擎定義了每一個表的最大索引數和最大索引長度。全部存儲引擎對每一個表至少支持16個索引,總索引長度至少爲256字節。有些存儲引擎支持更多的索引數和更大的索引長度。索引有兩種存儲類型,包括B型樹(BTREE)索引和哈希(HASH)索引。InnoDB和 MyISAM存儲引擎支持 BTREE索引,MEMORY存儲引擎支持HASH索引和BTREE索引,默認爲前者。

索引有其明顯的優點,也有其不可避免的缺點。

索引的優勢是能夠提升檢索數據的速度,這是建立索引的最主要的緣由;對於有依賴關係的子表和父表之間的聯合查詢時,能夠提升查詢速度;使用分組和排序子句進行數據查詢時,一樣能夠顯著節省查詢中分組和排序的時間。

索引的缺點是建立和維護索引須要耗費時間,耗費時間的數量隨着數據量的增長而增長;索引須要佔用物理空間,每個索引要佔必定的物理空間;增長、刪除和修改數據時,要動態的維護索引,形成數據的維護速度下降了。

索引的分類

1.普通索引
在建立普通索引時,不附加任何限制條件。這類索引能夠建立在任何數據類型中,其值是否惟一和非空由字段自己的完整性約束條件決定。創建索引之後,查詢時能夠經過索引進行查詢。例如,在 student表的stu_id字段上創建一個普通索引。查詢記錄時,就能夠根據該索引進行查詢。

2.惟一性索引
使用UNIQUE參數能夠設置索引爲惟一性索引。在建立惟一性索引時,限制該索引的值必須是惟一的。例如,在 student表的 stu_name字段中建立惟一性索引,那麼stu_name字段的值就必需是惟一的。經過惟一性索引,能夠更快速地肯定某條記錄。主鍵就是一種特殊惟一性索引。

3.全文索引
使用FULLTEXT參數能夠設置索引爲全文索引。全文索引只能建立在CHAR、VARCHAR或TEXT類型的字段上。查詢數據量較大的字符串類型的字段時,使用全文索引能夠提升查詢速度。例如,student 表的 information字段是TEXT類型,該字段包含了不少的文字信息。在 information字段上創建全文索引後,能夠提升查詢information字段的速度。MySQL數據庫從3.23.23版開始支持全文索引,但只有MyISAM存儲引擎支持全文檢索。在默認狀況下,全文索引的搜索執行方式不區分大小寫。但索引的列使用二進制排序後,能夠執行區分大小寫的全文索引。

4.單列索引
在表中的單個字段上建立索引。單列索引只根據該字段進行索引。
單列索引能夠是普通索引,也能夠是惟一性索引,還能夠是全文索引。只要保證該索引只對應一個字段便可。

5.多列索引
多列索引是在表的多個字段上建立一個索引。該索引指向建立時對應的多個字段,能夠經過這幾個字段進行查詢。可是,只有查詢條件中使用了這些字段中第一個字段時,索引纔會被使用。例如,在表中的id、name和 sex字段上創建一個多列索引,那麼,只有查詢條件使用了id字段時該索引纔會被使用。

6.空間索引
使用SPATIAL參數能夠設置索引爲空間索引。空間索引只能創建在空間數據類型上,這樣能夠提升系統獲取空間數據的效率。MySQL 中的空間數據類型包括GEOMETRY和POINT、LINESTRING和 POLYGON等。目前只有MyISAM存儲引擎支持空間檢索,並且索引的字段不能爲空值。對於初學者來講,這類索引不多會用到。

MySQL創建索引原則

1.選擇惟一性索引
惟一性索引的值是惟一的,能夠更快速的經過該索引來肯定某條記錄。

2.爲常常須要排序、分組和聯合操做的字段創建索引
常常須要ORDER BY、GROUP BY、DISTINCT 和 UNION等操做的字段,排序操做會浪費不少時間。若是爲其創建索引,能夠有效地避免排序操做。

3.爲常做爲查詢條件的字段創建索引
若是某個字段常常用來作查詢條件,那麼該字段的查詢速度會影響整個表的查詢速度。所以,爲這樣的字段創建索引,能夠提升整個表的查詢速度。

4.限制索引的數目
索引的數目不是越多越好。每一個索引都須要佔用磁盤空間,索引越多,須要的磁盤空間就越大。修改表時,對索引的重構和更新很麻煩。越多的索引,會使更新表變得很浪費時間。

5.儘可能使用數據量少的索引
若是索引的值很長,那麼查詢的速度會受到影響。例如,對一個CHAR(100)類型的字段進行全文檢索須要的時間確定要比對CHAR(10)類型的字段須要的時間要多。

6.儘可能使用前綴來索引
若是索引字段的值很長,最好使用值的前綴來索引。例如,TEXT和BLOG類型的字段,進行全文檢索會很浪費時間。若是隻檢索字段的前面的若干個字符,這樣能夠提升檢索速度。
7.刪除再也不使用或者不多使用的索引
表中的數據被大量更新,或者數據的使用方式被改變後,原有的一些索引可能再也不須要。數據庫管理員應當按期找出這些索引,將它們刪除,從而減小索引對更新操做的影響。


注意:選擇索引的最終目的是爲了使查詢的速度變快。上面給出的原則是最基本的準則,但不能拘泥於上面的準則。讀者要在之後的學習和工做中進行不斷的實踐。根據應用的實際狀況進行分析和判斷,選擇最合適的索引方式。.

MySQL建立索引

1.建立表時建立索引
2.在已經存在的表上建立索引
3.用alter table建立索引
在這裏插入圖片描述


MySQL刪除索引

刪除索引是指將表中已經存在的索引刪除掉。一些再也不使用的索引會下降表的更新速度,影響數據庫的性能。對於這樣的索引,應該將其刪除。本節將詳細講解刪除索引的方法。
對應已經存在的索引,能夠經過DROP語句來刪除索引。基本形式以下:

drop INDEX 索引名 on 表名;

MySQL索引的有效性

索引失效:
1.隱式轉換致使索引失效。
例:
因爲表的字段name定義爲varchar(20),但在查詢時把該字段做爲數字類型,以where條件傳給Mysql,這樣會致使索引失效.
強轉會引發索引失效:
name varchar(20)
index(name);
錯誤的例子:select * from test where name = 999;






N行數據 把N行數據的name屬性分別取出來先強轉在比較。
因爲須要將每一行數據都拿出來進行強換以後再比較。
強轉以後改變了原有字段的比較規則
正確的例子:select * from test where name=‘999’; 能用到索引


2.對索引列進行運算致使索引失效,對索引列進行運算包括(+,-,*,/,! 等)
例:
index(id)
錯誤的:select * from test where id - 1 < 9;
須要將每個元組中的id值先取出,再減一而後和9再去比較
正確的例子:select * from test where id < 10;能用到索引




3.使用MySQL內部函數致使索引失效.對於這樣狀況應當建立基於函數的索引。
錯誤的例子:select * from test where F(id)=10; 說明,此時id的索引已經不起做用了(須要將每個元組中的id值先取出,再經過函數計算,計算以後的值在和10比較)
要使用索引的話須要將:F(x) = y; ----> x = R(y);
正確的例子:select * from test where id= R(10);


4. 如下使用會使索引失效,應避免使用;
a.使用 <> 、not in 、!=
index(id)
select * from … where id not in (12,13,15); 用不到 沒有明確查詢條件
id
1


999







select * from … where id in (12,13,15); 能用到

b. like 「%_」 百分號在前(可採用在創建索引時用reverse(columnName)這種方法處理)
%:任意個任意字符
index(name)
select * from name like ‘%a’; //因爲字符串的最左比較法 用不到
字符串的索引是如何創建:從左到右一個字符一個字符進行大小比較而後得出的B+樹的結構。



abcdsdsa
abdr
select * from name like ‘a%’; //因爲字符串的最左比較法 能用到

五、使用OR關鍵字查詢語句
查詢語句的查詢條件中只有OR關鍵字,且OR先後的兩個條件中列都是索引時,查詢中才會使用索引。不然,查詢將不使用索引。

name = 「tom」 or(或) age < 90; ---->index(name) index(age);

name = 「tom」 and age < 90; ----> index(name,age)

索引的使用規則

最左前最原則:對帶有聯合索引的表進行多字段查詢時,應將聯合索引中的第一個索引字段放在第一位,這樣索引才能使用到。
**索引使用時的時間複雜度:**小表決定查詢次數,大表決定查詢時間。

例:

聯合查詢中如何使用索引,在表rb1,rb2中均在stu_id 字段上添加索引 index(stu_id)。判斷哪張表的索引能用到。

假設rb2是大表,rb1是小表
1.explain select * from rb1 a , rb2 b where a.stu_id = b.stu_id\G
where a.stu_id = b.stu_id
底層處理:把b中的全部的stu_id取出來,分別和a中的stu_id做比較;大表rb2可以使用到索引 而小表rb1用不到索引
在這裏插入圖片描述



explain select * from rb1 a  join rb2 b 
	on a.stu_id = b.stu_id where a.stu_id < 25\G

rb1使用到索引:where條件
rb2使用到索引:rb2是大表固然用到索引
在這裏插入圖片描述

3.explain select * from rb1 a join rb2 b
on a.stu_id = b.stu_id where b.stu_id < 25\G
rb2用到了索引由於where條件,同時變成小表,rb1變成大表用到了索引
在這裏插入圖片描述


4.沒給id加索引時:
a表的id上沒有索引因此仍是小表不用索引,rb2用索引
在這裏插入圖片描述

給id加上索引後:
在這裏插入圖片描述

相關文章
相關標籤/搜索