mysql中主鍵不是索引。主鍵全稱“主鍵約束”,是對表中數(shù)據(jù)的一種約束,它是表的一個特殊字段,該字段能唯一標識該表中的每條信息;而索引是一種特殊的數(shù)據(jù)庫結(jié)構(gòu),由數(shù)據(jù)表中的一列或多列組合而成,可以用來快速查詢數(shù)據(jù)表中有某一特定值的記錄。
本教程操作環(huán)境:windows7系統(tǒng)、mysql8版本、Dell G3電腦。
MySQL 主鍵
在 MySQL 中,主鍵(PRIMARY KEY)的完整稱呼是“主鍵約束”,是?MySQL?中使用最為頻繁的約束。一般情況下,為了便于 DBMS 更快的查找到表中的記錄,都會在表中設(shè)置一個主鍵。
約束是指對表中數(shù)據(jù)的一種約束,能夠幫助數(shù)據(jù)庫管理員更好地管理數(shù)據(jù)庫,并且能夠確保數(shù)據(jù)庫中數(shù)據(jù)的正確性和有效性。
主鍵是表的一個特殊字段,該字段能唯一標識該表中的每條信息。例如,學生信息表中的學號是唯一的。
主鍵分為單字段主鍵和多字段聯(lián)合主鍵,本節(jié)將分別講解這兩種主鍵約束的創(chuàng)建、修改和刪除。
使用主鍵應(yīng)注意以下幾點:
-
每個表只能定義一個主鍵。
-
主鍵值必須唯一標識表中的每一行,且不能為 NULL,即表中不可能存在有相同主鍵值的兩行數(shù)據(jù)。這是唯一性原則。
-
一個字段名只能在聯(lián)合主鍵字段表中出現(xiàn)一次。
-
聯(lián)合主鍵不能包含不必要的多余字段。當把聯(lián)合主鍵的某一字段刪除后,如果剩下的字段構(gòu)成的主鍵仍然滿足唯一性原則,那么這個聯(lián)合主鍵是不正確的。這是最小化原則。
在創(chuàng)建表時設(shè)置主鍵約束
在創(chuàng)建數(shù)據(jù)表時設(shè)置主鍵約束,既可以為表中的一個字段設(shè)置主鍵,也可以為表中多個字段設(shè)置聯(lián)合主鍵。但是不論使用哪種方法,在一個表中主鍵只能有一個。下面分別講解設(shè)置單字段主鍵和多字段聯(lián)合主鍵的方法。
1)設(shè)置單字段主鍵
在 CREATE table 語句中,通過 PRIMARY KEY 關(guān)鍵字來指定主鍵。
在定義字段的同時指定主鍵,語法格式如下:
??PRIMARY?KEY?[默認值]
例 1
在 test_db 數(shù)據(jù)庫中創(chuàng)建 tb_emp3 數(shù)據(jù)表,其主鍵為 id,SQL 語句和運行結(jié)果如下。
mysql>?CREATE?TABLE?tb_emp3 ????->?( ????->?id?INT(11)?PRIMARY?KEY, ????->?name?VARCHAR(25), ????->?deptId?INT(11), ????->?salary?FLOAT ????->?); Query?OK,?0?rows?affected?(0.37?sec) mysql>?DESC?tb_emp3; +--------+-------------+------+-----+---------+-------+ |?Field??|?Type????????|?Null?|?Key?|?Default?|?Extra?| +--------+-------------+------+-----+---------+-------+ |?id?????|?int(11)?????|?NO???|?PRI?|?NULL????|???????| |?name???|?varchar(25)?|?YES??|?????|?NULL????|???????| |?deptId?|?int(11)?????|?YES??|?????|?NULL????|???????| |?salary?|?float???????|?YES??|?????|?NULL????|???????| +--------+-------------+------+-----+---------+-------+ 4?rows?in?set?(0.14?sec)
或者是在定義完所有字段之后指定主鍵,語法格式如下:
[CONSTRAINT?]?PRIMARY?KEY?[字段名]
例 2
在 test_db 數(shù)據(jù)庫中創(chuàng)建 tb_emp4? 數(shù)據(jù)表,其主鍵為 id,SQL 語句和運行結(jié)果如下。
mysql>?CREATE?TABLE?tb_emp4 ????->?( ????->?id?INT(11), ????->?name?VARCHAR(25), ????->?deptId?INT(11), ????->?salary?FLOAT, ????->?PRIMARY?KEY(id) ????->?); Query?OK,?0?rows?affected?(0.37?sec) mysql>?DESC?tb_emp4; +--------+-------------+------+-----+---------+-------+ |?Field??|?Type????????|?Null?|?Key?|?Default?|?Extra?| +--------+-------------+------+-----+---------+-------+ |?id?????|?int(11)?????|?NO???|?PRI?|?NULL????|???????| |?name???|?varchar(25)?|?YES??|?????|?NULL????|???????| |?deptId?|?int(11)?????|?YES??|?????|?NULL????|???????| |?salary?|?float???????|?YES??|?????|?NULL????|???????| +--------+-------------+------+-----+---------+-------+ 4?rows?in?set?(0.14?sec)
2)在創(chuàng)建表時設(shè)置聯(lián)合主鍵
所謂的聯(lián)合主鍵,就是這個主鍵是由一張表中多個字段組成的。
比如,設(shè)置學生選課數(shù)據(jù)表時,使用學生編號做主鍵還是用課程編號做主鍵呢?如果用學生編號做主鍵,那么一個學生就只能選擇一門課程。如果用課程編號做主鍵,那么一門課程只能有一個學生來選。顯然,這兩種情況都是不符合實際情況的。
實際上設(shè)計學生選課表,要限定的是一個學生只能選擇同一課程一次。因此,學生編號和課程編號可以放在一起共同作為主鍵,這也就是聯(lián)合主鍵了。
主鍵由多個字段聯(lián)合組成,語法格式如下:
PRIMARY?KEY?[字段1,字段2,…,字段n]
注意:當主鍵是由多個字段組成時,不能直接在字段名后面聲明主鍵約束。
例 3
創(chuàng)建數(shù)據(jù)表 tb_emp5,假設(shè)表中沒有主鍵 id,為了唯一確定一個員工,可以把 name、deptId 聯(lián)合起來作為主鍵,SQL 語句和運行結(jié)果如下。
mysql>?CREATE?TABLE?tb_emp5 ????->?( ????->?name?VARCHAR(25), ????->?deptId?INT(11), ????->?salary?FLOAT, ????->?PRIMARY?KEY(name,deptId) ????->?); Query?OK,?0?rows?affected?(0.37?sec) mysql>?DESC?tb_emp5; +--------+-------------+------+-----+---------+-------+ |?Field??|?Type????????|?Null?|?Key?|?Default?|?Extra?| +--------+-------------+------+-----+---------+-------+ |?name???|?varchar(25)?|?NO???|?PRI?|?NULL????|???????| |?deptId?|?int(11)?????|?NO???|?PRI?|?NULL????|???????| |?salary?|?float???????|?YES??|?????|?NULL????|???????| +--------+-------------+------+-----+---------+-------+ 3?rows?in?set?(0.14?sec)
在修改表時添加主鍵約束
主鍵約束不僅可以在創(chuàng)建表的同時創(chuàng)建,也可以在修改表時添加。但是需要注意的是,設(shè)置成主鍵約束的字段中不允許有空值。
在修改數(shù)據(jù)表時添加主鍵約束的語法格式如下:
ALTER?TABLE??ADD?PRIMARY?KEY();
查看 tb_emp2 數(shù)據(jù)表的表結(jié)構(gòu),SQL 語句和運行結(jié)果如下所示。
mysql>?DESC?tb_emp2; +--------+-------------+------+-----+---------+-------+ |?Field??|?Type????????|?Null?|?Key?|?Default?|?Extra?| +--------+-------------+------+-----+---------+-------+ |?id?????|?int(11)?????|?NO???|?????|?NULL????|???????| |?name???|?varchar(30)?|?YES??|?????|?NULL????|???????| |?deptId?|?int(11)?????|?YES??|?????|?NULL????|???????| |?salary?|?float???????|?YES??|?????|?NULL????|???????| +--------+-------------+------+-----+---------+-------+ 4?rows?in?set?(0.14?sec)
例 4
修改數(shù)據(jù)表 tb_emp2,將字段 id 設(shè)置為主鍵,SQL 語句和運行結(jié)果如下。
mysql>?ALTER?TABLE?tb_emp2 ????->?ADD?PRIMARY?KEY(id); Query?OK,?0?rows?affected?(0.94?sec) Records:?0??Duplicates:?0??Warnings:?0 mysql>?DESC?tb_emp2; +--------+-------------+------+-----+---------+-------+ |?Field??|?Type????????|?Null?|?Key?|?Default?|?Extra?| +--------+-------------+------+-----+---------+-------+ |?id?????|?int(11)?????|?NO???|?PRI?|?NULL????|???????| |?name???|?varchar(30)?|?YES??|?????|?NULL????|???????| |?deptId?|?int(11)?????|?YES??|?????|?NULL????|???????| |?salary?|?float???????|?YES??|?????|?NULL????|???????| +--------+-------------+------+-----+---------+-------+ 4?rows?in?set?(0.12?sec)
通常情況下,當在修改表時要設(shè)置表中某個字段的主鍵約束時,要確保設(shè)置成主鍵約束的字段中值不能夠有重復(fù)的,并且要保證是非空的。否則,無法設(shè)置主鍵約束。
MySQL??索引(Index)
索引是一種特殊的數(shù)據(jù)庫結(jié)構(gòu),由數(shù)據(jù)表中的一列或多列組合而成,可以用來快速查詢數(shù)據(jù)表中有某一特定值的記錄。
通過索引,查詢數(shù)據(jù)時不用讀完記錄的所有信息,而只是查詢索引列。否則,數(shù)據(jù)庫系統(tǒng)將讀取每條記錄的所有信息進行匹配。
可以把索引比作新華字典的音序表。例如,要查“庫”字,如果不使用音序,就需要從字典的 400 頁中逐頁來找。但是,如果提取拼音出來,構(gòu)成音序表,就只需要從 10 多頁的音序表中直接查找。這樣就可以大大節(jié)省時間。
索引的優(yōu)缺點
索引有其明顯的優(yōu)勢,也有其不可避免的缺點。
優(yōu)點
索引的優(yōu)點如下:
-
通過創(chuàng)建唯一索引可以保證數(shù)據(jù)庫表中每一行數(shù)據(jù)的唯一性。
-
可以給所有的 MySQL 列類型設(shè)置索引。
-
可以大大加快數(shù)據(jù)的查詢速度,這是使用索引最主要的原因。
-
在實現(xiàn)數(shù)據(jù)的參考完整性方面可以加速表與表之間的連接。
-
在使用分組和排序子句進行數(shù)據(jù)查詢時也可以顯著減少查詢中分組和排序的時間
缺點
增加索引也有許多不利的方面,主要如下:
-
創(chuàng)建和維護索引組要耗費時間,并且隨著數(shù)據(jù)量的增加所耗費的時間也會增加。
-
索引需要占磁盤空間,除了數(shù)據(jù)表占數(shù)據(jù)空間以外,每一個索引還要占一定的物理空間。如果有大量的索引,索引文件可能比數(shù)據(jù)文件更快達到最大文件尺寸。
-
當對表中的數(shù)據(jù)進行增加、刪除和修改的時候,索引也要動態(tài)維護,這樣就降低了數(shù)據(jù)的維護速度。
使用索引時,需要綜合考慮索引的優(yōu)點和缺點。
索引可以提高查詢速度,但是會影響插入記錄的速度。因為,向有索引的表中插入記錄時,數(shù)據(jù)庫系統(tǒng)會按照索引進行排序,這樣就降低了插入記錄的速度,插入大量記錄時的速度影響會更加明顯。這種情況下,最好的辦法是先刪除表中的索引,然后插入數(shù)據(jù),插入完成后,再創(chuàng)建索引。
【相關(guān)推薦:mysql視頻教程】