概念:
主鍵可以唯壹地標識表中行的屬性或屬性組。壹個表只能有壹個主鍵,但可以有多個候選索引。主鍵通常與外鍵形成參照完整性約束,以防止數據不壹致。主鍵可以保證記錄的唯壹性和非空主鍵字段,數據庫管理系統自動為主鍵生成唯壹索引,所以主鍵也是壹個特殊索引。
外鍵是用於建立和加強兩個表數據之間的鏈接的壹列或多列。外鍵約束主要用於維護兩個表之間數據的壹致性。簡而言之,壹個表的外鍵是另壹個表的主鍵,外鍵連接兩個表。通常,要刪除表中的主鍵,必須首先確保其他表中沒有相同的外鍵(也就是說,該表中沒有與主鍵相關聯的外鍵)。
索引用於快速查找具有特定值的記錄。主要是為了方便檢索,為了加快訪問速度,按照壹定的規則創建,壹般起到排序的作用。所謂唯壹索引,和前面的“普通索引”基本相同,但有壹點不同:索引列的所有值只能出現壹次,即必須唯壹。
總結:
主鍵必須是唯壹索引,唯壹索引不壹定是主鍵。
壹個表可以有多個唯壹索引,但只能有壹個主鍵。
主鍵列不允許空值,而唯壹索引列允許空值。
主鍵可以作為外鍵被其他字段引用,而索引不能作為外鍵引用。
主鍵:
主鍵是數據表的唯壹索引。例如,學生表中有學號和姓名,姓名可能有重名,但學號是唯壹的。如果要從學生表中搜索壹條記錄,只能根據學生編號進行搜索,這樣才能找到唯壹的壹條,也就是主鍵。如:ident (10) not null主鍵auto _ increment自我成長的類型;
外鍵:
定義數據表
假設某電腦廠商在其數據庫中保存了整機和配件的產品信息。用來保存整機產品信息的表叫PC;用來存儲配件供應信息的表稱為Parts。
Pc表中有壹個字段描述這臺計算機使用的CPU型號;
零件表中有相應的字段,描述CPU的型號。我們可以把它看作是所有CPU型號的列表。
很明顯,這個廠家生產的電腦所用的CPU壹定是零件中存在的型號。這時,兩個表中有壹個約束——PC表中的CPU型號被Parts表中的型號約束。
首先,讓我們創建零件表:
創建表格部件(
...字段定義,
模型VARCHAR(20)不為空,
...字段定義...
);
接下來是Pc表:
創建臺式電腦(
...字段定義,
cpumodel VARCHAR(20)不為空,
...字段定義...
};
設置索引
要設置外鍵,referencedtable (Pc表)和referencedtable(零件表)必須為相應的兩個字段設置索引。
對於零件表:
ALTER TABLE parts添加索引idx_model(模型);
向基於模型字段的零件表中添加壹個索引,並將該索引命名為idx_model。
類似於Pc表:
ALTER TABLE PC ADD INDEX idx _ cpumodel(cpumodel);
事實上,這兩個索引可以在創建表時設置。這只是為了突出它的必要性。
定義外鍵
讓我們在兩個表之間建立前面提到的“約束”。因為pc的cpumodel必須引用parts表中對應的型號,所以我們將Pc表的CPU model字段設置為“FOREIGNKEY”,即這個KEY的引用值來自其他表。
更改表pc添加約束fk_cpu_model
外鍵(cpumodel)
參考零件(模型);
第壹行說給Pc表設置壹個外鍵,給這個外鍵起個名字叫fk _ CPU _ model第二行是將這個表的cpumodel字段設置為外鍵;第三行說明這個外鍵上的約束來自部件表的模型字段。
這樣,我們的外鍵就可以了。如果我們試圖用Parts表中不存在的CPU型號創建壹臺PC,MySQL將禁止創建這臺Pc。
級聯操作
考慮以下情況:
技術人員發現壹個月前錄入零件表的某系列cpu的型號(可能有很多型號)都錄入錯了字母,現在需要更正。我們希望當零件表中的引用列發生變化時,相應表中的引用列也能自動更正。
定義外鍵時,可以在末尾添加以下關鍵字:
關於更新級聯;也就是說,當主表被更新時,子表(子表)將有壹個鏈更新動作。似乎有人喜歡稱這種操作為“級聯”操作。:)
如果把這個語句寫完整,就是:
更改表pc添加約束fk_cpu_model
外鍵(cpumodel)
參考零件(模型)
關於更新級聯;
除了CASCADE之外,還有RESTRICT(禁止主表改變)、SET NULL(設置子表對應字段為空)等操作。
索引:
索引用於快速查找具有特定值的記錄,所有MySQL索引都以B樹的形式保存。如果沒有索引,MySQL在執行查詢時必須從第壹條記錄開始掃描整個表的所有記錄,直到找到符合要求的記錄。表中的記錄越多,這個操作的代價就越高。如果已經在列上創建了索引作為搜索條件,MySQL可以快速找到目標記錄的位置,而無需掃描任何記錄。如果表有1000條記錄,那麽通過索引查找記錄比順序掃描記錄至少快100倍。
假設我們創建了壹個名為people:
創建表people ( peopleid SMALLINT NOT NULL,name CHAR(50)NOT NULL);
然後,我們向people表中隨機插入1000個不同的名稱值。下圖顯示了people表所在的數據文件的壹小部分:
正如您所看到的,數據文件中的name列沒有任何明確的順序。如果我們為name列創建壹個索引,MySQL將對索引中的name列進行排序:
對於索引中的每壹項,MySQL都在內部保存壹個指向數據文件中實際記錄位置的“指針”。因此,如果我們要查找壹條記錄的PeopleID,其名稱等於“Mike”(SQL命令為“Select People id from People Where Name = " Mike”);),MySQL可以在name的索引中查找“Mike”的值,然後直接到數據文件中對應的行,準確返回那壹行的peopleid(999)。在這個過程中,MySQL只需要處理壹行就可以返回結果。如果沒有“姓名”列的索引,MySQL將掃描數據文件中的所有記錄,即1000條記錄!顯然,MySQL需要處理的記錄越少,完成任務的速度就越快。指數類型
MySQL提供了多種索引類型可供選擇:
總索引
這是最基本的索引類型,它沒有唯壹性等限制。可以通過以下方式創建常規索引:
創建索引,如在tablename(列列表)上創建索引;修改表,如alter table表名添加索引(列的列表);創建表時指定壹個索引,如create table table table...],index[索引的名稱](列的列表);
唯壹性指數
這個索引與前面的“普通索引”基本相同,但有壹點不同:索引列的所有值只能出現壹次,即必須唯壹。可以通過以下方式創建唯壹索引:
創建索引,如在tablename(列列表)上創建唯壹索引;修改表,如alter table表名添加unique(列的列表);創建表時指定壹個索引,如create table table table...],unique[索引名稱](列列表);
主鍵
PRIMARYKEY是唯壹索引,但必須指定為“primary key”。如果您曾經使用過AUTO_INCREMENT類型的列,您可能已經熟悉了諸如主鍵這樣的概念。主鍵通常在創建表時指定,例如,“create table tablename ([...],主鍵);"。不過我們也可以通過修改表來添加主鍵,比如“alter table table name add primary key”。。每個表只能有壹個主鍵。
全文索引
MySQL從3.23.23版本開始支持全文索引和全文檢索。在MySQL中,全文索引的索引類型是FULLTEXT。可以對VARCHAR或TEXT類型的列創建全文索引。它可以通過CREATETABLE命令或ALTER TABLE或CREATE INDEX命令創建。對於大規模數據集,通過ALTERTABLE(或CREATEINDEX)命令創建全文索引比在帶有全文索引的空表中插入記錄更快。在下壹篇文章中不再討論全文索引。更多信息,請參考MySQL文檔。
單列索引和多列索引
索引可以是單列索引,也可以是多列索引。讓我們通過具體的例子來說明這兩個指標的區別。假設有這樣壹個人表:
創建表people(peopleid SMALLINT NOT NULL AUTO _ INCREMENT,firstname CHAR(50) NOT NULL,lastname CHAR(50) NOT NULL,age SMALLINT NOT NULL,townid SMALLINT NOT NULL,PRIMARY KEY(peopleid));
以下是我們插入到這個人員表中的數據:
有四個人叫“Mikes”(其中兩個是Sullivans的,兩個是McConnells的),兩個人年齡17,還有壹個JoeSmith,名字不壹樣。
該表的主要目的是根據指定用戶的姓、名和年齡返回相應的peopleid。例如,我們可能需要查找名為MikeSullivan、年齡為17的用戶的People id(SQL命令是Select PeopleID from People,其中名字=' Mike ',姓氏=' Sullivan ',年齡= 17;)。因為我們不希望MySQL每次執行查詢時都掃描整個表,所以我們需要考慮在這裏使用索引。
首先,我們可以考慮在單個列上創建索引,比如firstname、lastname或age列。如果我們創建壹個名列的索引(alter table people add index first name);),MySQL會通過這個索引快速將搜索範圍限制在那些名字=' Mike '的記錄,然後對這個“中間結果集”進行其他條件搜索:它先排除那些姓氏不等於“Sullivan”的記錄,再排除那些年齡不等於17的記錄。當記錄滿足所有搜索條件時,MySQL返回最終的搜索結果。
由於firstname列索引的建立,MySQL的效率比全表掃描提高了很多,但是我們要求MySQL掃描的記錄數量仍然遠遠超過實際需要。雖然我們可以刪除firstname列上的索引,然後在lastname或age列上創建索引,但總的來說,無論我們在哪壹列上創建索引,搜索效率都是相似的。
為了提高搜索效率,我們需要考慮使用多列索引。如果為firstname、lastname和age三列創建多列索引,MySQL只能找到壹次正確的結果!以下是創建該多列索引的SQL命令:
ALTER TABLE people添加索引fname_lname_age(名字,姓氏,年齡);
因為索引文件是以B樹格式保存的,所以MySQL可以立即轉到相應的名字,然後轉到相應的姓氏,最後轉到相應的年齡。不用掃描數據文件中的任何記錄,MySQL就正確地找出了搜索的目標記錄!
那麽,如果在名字、姓氏、年齡三列上創建壹個單列索引,效果和創建名字、姓氏、年齡多列索引壹樣嗎?答案是否定的,兩者完全不同。當我們執行查詢時,MySQL只能使用壹個索引。如果您有三個單列索引,MySQL將嘗試選擇限制性最強的索引。但是,即使是限制性最強的單列索引,在firstname、lastname和age列上的限制性也肯定遠遠小於多列索引。
最左邊的前綴
多列索引還有壹個優點,就是通過最左前綴的概念來體現。繼續考慮前面的例子,我們現在在firstname、lastname和age列上有壹個多列索引,我們稱之為fname_lname_age。當搜索條件是以下列的組合時,MySQL使用fname_lname_age索引:
名,姓,年齡名,姓名
另壹方面,它相當於在(名字,姓氏,年齡),(名字,姓氏)和(名字)的組合上創建壹個索引。以下查詢可以使用此fname_lname_age索引:
選擇peopleid FROM people,其中名字='Mike ',姓氏='Sullivan ',年齡= ' 17 ';選擇people id FROM people WHERE first name = ' Mike ' AND last name = ' Sullivan ';選擇people id FROM people WHERE first name = ' Mike ';以下查詢根本無法使用該索引:SELECT people id FROM people WHERE last name = ' Sullivan ';選擇people id FROM persons WHERE age = ' 17 ';選擇people id FROM people WHERE last name = ' Sullivan ' AND age = ' 17 ';
選擇索引列
在性能優化過程中,選擇在哪些列上創建索引是最重要的步驟之壹。可以考慮使用索引的列主要有兩種類型:出現在WHERE子句中的列和出現在join子句中的列。請看下面的查詢:
選擇年齡##不要使用名=' Mike' # #考慮使用索引,姓=' Sullivan' # #考慮使用索引的人。
這個查詢與前面的查詢略有不同,但它仍然是壹個簡單的查詢。由於在SELECT部分引用了age,MySQL不會用它來限制列選擇操作。因此,沒有必要為此查詢創建age列的索引。這裏有壹個更復雜的例子:
SELECT people.age,##不使用索引town.name ##不使用people.townid = town.townid上的people left joint town的索引##考慮使用索引,其中名字=' mike' # #考慮使用索引,姓氏=' Sullivan' # #考慮使用索引。
與前面的示例壹樣,由於firstname和lastname出現在WHERE子句中,所以仍然有必要為這兩列創建索引。此外,由於town表的townid列在join子句中,我們需要考慮為這個列創建壹個索引。
唯壹索引:
通用索引允許索引數據列包含重復值。例如,因為人們可能有相同的姓名,所以相同的姓名可能在同壹個雇員概況數據表中出現兩次或更多次。
如果可以確定某個數據列只包含不同的值,則在為此數據列創建索引時,應該使用關鍵字UNIQUE將其定義為唯壹索引。這樣做的好處是:第壹,簡化了MySQL對這個索引的管理,索引變得更加高效;第二,在數據表中插入新記錄時,MySQL會自動檢查新記錄的這個字段的值是否已經出現在壹條記錄的這個字段中;如果是這樣,MySQL將拒絕插入新記錄。換句話說,唯壹索引可以保證數據記錄的唯壹性。事實上,在很多場合,創建唯壹索引的目的並不是為了提高訪問速度,而是為了避免數據重復。
MySQL的幾個概念:主鍵、外鍵、索引、唯壹索引。
標簽:哪些pad人完成了renamemost技術bletext?