日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL的几个概念:主键,外键,索引,唯一索引

發布時間:2025/3/21 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL的几个概念:主键,外键,索引,唯一索引 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、概念:

??? 1、主鍵(primary key)?能夠唯一標識表中某一行的屬性或屬性組。一個表只能有一個主鍵,但可以有多個候選索引。主鍵常常與外鍵構成參照完整性約束,防止出現數據不一致。主鍵可以保證記錄的唯一和主鍵域非空,數據庫管理系統對于主鍵自動生成唯一索引,所以主鍵也是一個特殊的索引

??? 2、外鍵(foreign key)?是用于建立和加強兩個表數據之間的鏈接的一列或多列。外鍵約束主要用來維護兩個表之間數據的一致性。簡言之,表的外鍵就是另一表的主鍵,外鍵將兩表聯系起來。一般情況下,要刪除一張表中的主鍵必須首先要確保其它表中的沒有相同外鍵(即該表中的主鍵沒有一個外鍵和它相關聯)。

??? 3、索引(index)?是用來快速地尋找那些具有特定值的記錄。主要是為了檢索的方便,是為了加快訪問速度, 按一定的規則創建的,一般起到排序作用。所謂唯一性索引,這種索引和前面的“普通索引”基本相同,但有一個區別:索引列的所有值都只能出現一次,即必須唯一。

??? 總結:

主鍵一定是唯一性索引,唯一性索引并不一定就是主鍵。

?一個表中可以有多個唯一性索引,但只能有一個主鍵。

主鍵列不允許空值,而唯一性索引列允許空值。

主鍵可以被其他字段作外鍵引用,而索引不能作為外鍵引用。


二、具體介紹:

??? 1、主鍵:

?????主鍵是數據表的唯一索引,比如學生表里有學號和姓名,姓名可能有重名的,但學號確是唯一的,你要從學生表中搜索一條紀錄如查找一個人,就只能根據學號去查找,這才能找出唯一的一個,這就是主鍵;如:idint(10) not null primary key auto_increment ;自增長的類型 ;


??? 2、外鍵:

?????定義數據表

  假如某個電腦生產商,它的數據庫中保存著整機和配件的產品信息。用來保存整機產品信息的表叫做Pc;用來保存配件供貨信息的表叫做Parts。

  在Pc表中有一個字段,用來描述這款電腦所使用的CPU型號;

  在Parts 表中相應有一個字段,描述的正是CPU的型號,我們可以把它想成是全部CPU的型號列表。

  很顯然,這個廠家生產的電腦,其使用的CPU一定是供貨信息表(parts)中存在的型號。這時,兩個表中就存在一種約束關系(constraint)——Pc表中的CPU型號受到Parts表中型號的約束。

  首先我們來創建 parts 表:


CREATE TABLE parts (
... 字段定義 ...,
model VARCHAR(20) NOT NULL,
... 字段定義 ...
);

?


  接下來是pc表:

CREATE TABLE pc (
... 字段定義 ...,
cpumodel VARCHAR(20) NOT NULL,
... 字段定義 ...
};


設置索引

  若要設置外鍵,在參照表(referencing table,即Pc表) 和被參照表 (referencedtable,即parts表) 中,相對應的兩個字段必須都設置索引(index)。

  對Parts表:

  ALTER TABLE parts ADD INDEX idx_model (model);

  這句話的意思是,為 parts 表增加一個索引,索引建立在 model字段上,給這個索引起個名字叫idx_model。

  對Pc表也類似:

  ALTER TABLE pc ADD INDEX idx_cpumodel (cpumodel);

  事實上這兩個索引可以在創建表的時候就設置。這里只是為了突出其必要性。

  

定義外鍵

  下面為兩張表之間建立前面所述的那種“約束”。因為pc的CPU型號必須參照parts表中的相應型號,所以我們將Pc表的cpumodel字段設置為“外鍵”(FOREIGNKEY),即這個鍵的參照值來自于其他表。


ALTER TABLE pc ADD CONSTRAINT fk_cpu_model
FOREIGN KEY (cpumodel)
REFERENCES parts(model);


  第一行是說要為Pc表設置外鍵,給這個外鍵起一個名字叫做fk_cpu_model;第二行是說將本表的cpumodel字段設置為外鍵;第三行是說這個外鍵受到的約束來自于Parts表的model字段。

  這樣,我們的外鍵就可以了。如果我們試著CREATE一臺Pc,它所使用的CPU的型號是Parts表中不存在的,那么MySQL會禁止這臺PC被CREATE出來。

  級聯操作

  考慮以下這種情況:

  技術人員發現,一個月之前輸入到 parts 表中的某個系列的 cpu(可能有很多款)的型號全都輸錯了一個字母,現在需要改正。我們希望的是,當 parts 表中那些 Referenced Column有所變化時,相應表中的 Referencing Column 也能自動更正。

  可以在定義外鍵的時候,在最后加入這樣的關鍵字:

  ON UPDATE CASCADE;即在主表更新時,子表(們)產生連鎖更新動作,似乎有些人喜歡把這個叫“級聯”操作。:)

  如果把這語句完整的寫出來,就是:

ALTER TABLE pc ADD CONSTRAINT fk_cpu_model
FOREIGN KEY (cpumodel)
REFERENCES parts(model)
ON UPDATE CASCADE;

?

  除了 CASCADE 外,還有 RESTRICT(禁止主表變更)、SET NULL(子表相應字段設置為空)等操作

索引:

?????索引用來快速地尋找那些具有特定值的記錄,所有MySQL索引都以B-樹的形式保存。如果沒有索引,執行查詢時MySQL必須從第一個記錄開始掃描整個表的所有記錄,直至找到符合要求的記錄。表里面的記錄數量越多,這個操作的代價就越高。如果作為搜索條件的列上已經創建了索引,MySQL無需掃描任何記錄即可迅速得到目標記錄所在的位置。如果表有1000個記錄,通過索引查找記錄至少要比順序掃描記錄快100倍。

??????假設我們創建了一個名為people的表:


CREATE TABLE people ( peopleid SMALLINT NOT NULL, name CHAR(50) NOT NULL );


然后,我們完全隨機把1000個不同name值插入到people表。
在數據文件中name列沒有任何明確的次序。如果我們創建了name列的索引,MySQL將在索引中排序name列
對于索引中的每一項,MySQL在內部為它保存一個數據文件中實際記錄所在位置的“指針”。因此,如果我們要查找name等于“Mike”記錄的 peopleid(SQL命令為“SELECTpeopleid FROM people WHEREname='Mike';”),MySQL能夠在name的索引中查找“Mike”值,然后直接轉到數據文件中相應的行,準確地返回該行的 peopleid(999)。在這個過程中,MySQL只需處理一個行就可以返回結果。如果沒有“name”列的索引,MySQL要掃描數據文件中的所有 記錄,即1000個記錄!顯然,需要MySQL處理的記錄數量越少,則它完成任務的速度就越快。


索引的類型

MySQL提供多種索引類型供選擇:

普通索引

這是最基本的索引類型,而且它沒有唯一性之類的限制。普通索引可以通過以下幾種方式創建:

創建索引,例如:CREATE?INDEX?<索引的名字>?ON?tablename?(列的列表); 修改表,例如:ALTER?TABLE?tablename?ADD?INDEX?[索引的名字]?(列的列表);? 創建表的時候指定索引,例如:CREATE?TABLE?tablename?(?[...],?INDEX?[索引的名字]?(列的列表)?);


唯一性索引

這種索引和前面的“普通索引”基本相同,但有一個區別:索引列的所有值都只能出現一次,即必須唯一。唯一性索引可以用以下幾種方式創建:

創建索引,例如:CREATE?UNIQUE?INDEX?<索引的名字>?ON?tablename?(列的列表);? 修改表,例如:ALTER?TABLE?tablename?ADD?UNIQUE?[索引的名字]?(列的列表);? 創建表的時候指定索引,例如:CREATE?TABLE?tablename?(?[...],?UNIQUE?[索引的名字]?(列的列表)?);


主鍵

主鍵是一種唯一性索引,但它必須指定為“PRIMARYKEY”。如果你曾經用過AUTO_INCREMENT類型的列,你可能已經熟悉主鍵之類的概念了。主鍵一般在創建表的時候指定,例如:

????? “CREATETABLE tablename ( [...], PRIMARY?KEY?(列的列表) );”

但是,我們也可以通過修改表的方式加入主鍵,例如:

????? “ALTER TABLE tablename ADD PRIMARY KEY(列的列表); ”

每個表只能有一個主鍵。

單列索引與多列索引

索引可以是單列索引,也可以是多列索引。下面我們通過具體的例子來說明這兩種索引的區別。假設有這樣一個people表:

CREATE?TABLE?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)?);


??? 假如:這個表中有四個名字為“Mike”的人(其中兩個姓Sullivans,兩個姓McConnells),有兩個年齡為17歲的人,還有一個名字與眾不同的JoeSmith。
??? 這個表的主要用途是根據指定的用戶姓、名以及年齡返回相應的peopleid。例如,我們可能需要查找姓名為MikeSullivan、年齡17歲用戶的 peopleid

(SQL命令為SELECT peopleid FROM people WHEREfirstname='Mike' AND lastname='Sullivan' AND age=17;)。

由于我們不想讓MySQL每次執行查詢就去掃描整個表,這里需要考慮運用索引。

首先,我們可以考慮在單個列上創建索引,比如firstname、lastname或者age列。如果我們創建firstname列的索引 (ALTERTABLE people ADD INDEX firstname(firstname);),MySQL將通過這個索引迅速把搜索范圍限制到那些firstname='Mike'的記錄,然后再在這 個“中間結果集”上進行其他條件的搜索:它首先排除那些lastname不等于“Sullivan”的記錄,然后排除那些age不等于17的記錄。當記錄滿足所有搜索條件之后,MySQL就返回最終的搜索結果。

??? 由于建立了firstname列的索引,與執行表的完全掃描相比,MySQL的效率提高了很多,但我們要求MySQL掃描的記錄數量仍舊遠遠超過了實際所需要的。雖然我們可以刪除firstname列上的索引,再創建lastname或者age列的索引,但總地看來,不論在哪個列上創建索引搜索效率仍舊相似。

??? 為了提高搜索效率,我們需要考慮運用多列索引。如果為firstname、lastname和age這三個列創建一個多列索引,MySQL只需一次檢索就能夠找出正確的結果!下面是創建這個多列索引的SQL命令:

ALTER?TABLE?people?ADD?INDEX?fname_lname_age?(firstname,lastname,age);



??? 由于索引文件以B-樹格式保存,MySQL能夠立即轉到合適的firstname,然后再轉到合適的lastname,最后轉到合適的age。在沒有掃描數據文件任何一個記錄的情況下,MySQL就正確地找出了搜索的目標記錄!

??? 那么,如果在firstname、lastname、age這三個列上分別創建單列索引,效果是否和創建一個firstname、lastname、 age的多列索引一樣呢?答案是否定的,兩者完全不同。當我們執行查詢的時候,MySQL只能使用一個索引。如果你有三個單列的索引,MySQL會試圖選擇一個限制最嚴格的索引。但是,即使是限制最嚴格的單列索引,它的限制能力也肯定遠遠低于firstname、lastname、age這三個列上的多列 索引。

最左前綴

??? 多列索引還有另外一個優點,它通過稱為最左前綴(LeftmostPrefixing)的概念體現出來。繼續考慮前面的例子,現在我們有一個firstname、lastname、age列上的多列索引,我們稱這個索引為fname_lname_age。當搜索條件是以下各種列的組合時,MySQL將使用fname_lname_age索引:

firstname,lastname?age,?firstname?lastname,?firstname



??? 從另一方面理解,它相當于我們創建了(firstname,lastname,age)、(firstname,lastname)以及(firstname)這些列組合上的索引。下面這些查詢都能夠使用這個fname_lname_age索引:

SELECT?peopleid?FROM?people?WHERE?firstname='Mike'?AND?lastname='Sullivan'?AND?age='17'; SELECT?peopleid?FROM?people?WHERE?firstname='Mike'?AND?lastname='Sullivan';? SELECT?peopleid?FROM?people?WHERE?firstname='Mike';The?following?queries?cannot?use?the?index?at?all:?SELECT?peopleid?FROM?people?WHERE?lastname='Sullivan';? SELECT?peopleid?FROM?people?WHERE?age='17';? SELECT?peopleid?FROM?people?WHERE?lastname='Sullivan'?AND?age='17';

from:?http://wushank.blog.51cto.com/3489095/1641308

總結

以上是生活随笔為你收集整理的MySQL的几个概念:主键,外键,索引,唯一索引的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。