主鍵是一個索引,mysql的索引是B+樹,Mysql會按照鍵值的大小進行順序存放,如果我們設(shè)置自增id為主鍵,這個時候主鍵是按照一種緊湊的接近順序?qū)懭氲姆绞竭M行存儲數(shù)據(jù)。如果我們用其他字段作為主鍵的話,此時Mysql不得不為了將新記錄插到合適位置而移動數(shù)據(jù),甚至目標頁面可能已經(jīng)被回寫到磁盤上而從緩存中清掉,此時又要從磁盤上讀回來,這增加了很多額外的開銷,同時頻繁的移動、分頁操作造成了大量的碎片。
創(chuàng)新互聯(lián)建站總部坐落于成都市區(qū),致力網(wǎng)站建設(shè)服務(wù)有做網(wǎng)站、網(wǎng)站設(shè)計、網(wǎng)絡(luò)營銷策劃、網(wǎng)頁設(shè)計、網(wǎng)站維護、公眾號搭建、微信小程序定制開發(fā)、軟件開發(fā)等為企業(yè)提供一整套的信息化建設(shè)解決方案。創(chuàng)造真正意義上的網(wǎng)站建設(shè),為互聯(lián)網(wǎng)品牌在互動行銷領(lǐng)域創(chuàng)造價值而不懈努力!
- 考慮性能消耗
- 考慮資源消耗
- 考慮分庫分表
mysql設(shè)置主鍵的代碼是PRIMARY KEY (主鍵字段)。
如:CREATE TABLE Customer (SID integer,Last_Name varchar(30),F(xiàn)irst_Name varchar(30),PRIMARY KEY (SID))。
主關(guān)鍵字(主鍵,primary key)是被挑選出來,作表的行的唯一標識的候選關(guān)鍵字。一個表只有一個主關(guān)鍵字。主關(guān)鍵字又可以稱為主鍵。
擴展資料:
永遠也不要更新主鍵。實際上,因為主鍵除了唯一地標識一行之外,再沒有其他的用途了,所以也就沒有理由去對它更新。如果主鍵需要更新,則說明主鍵應(yīng)對用戶無意義的原則被違反了。
主鍵應(yīng)當由計算機自動生成。如果由人來對主鍵的創(chuàng)建進行干預(yù),就會使它帶有除了唯一標識一行以外的意義。一旦越過這個界限,就可能產(chǎn)生人為修改主鍵的動機,這樣,這種系統(tǒng)用來鏈接記錄行、管理記錄行的關(guān)鍵手段就會落入不了解數(shù)據(jù)庫設(shè)計的人的手中。
主鍵是數(shù)據(jù)表的唯一索引,比如學(xué)生表里有學(xué)號和姓名,姓名可能有重名的,但學(xué)號確是唯一的,你要從學(xué)生表中搜索一條紀錄如查找一個人,就只能根據(jù)學(xué)號去查找,這才能找出唯一的一個,這就是主鍵
1、主鍵定義
表中經(jīng)常有一個列或多列的組合,其值能唯一地標識表中的每一行。這樣的一列或多列稱為表的主鍵,通過它可強制表的實體完整性。當創(chuàng)建或更改表時可通過定義 PRIMARY KEY 約束來創(chuàng)建主鍵。一個表只能有一個 PRIMARY KEY 約束,而且 PRIMARY KEY 約束中的列不能接受空值。由于 PRIMARY KEY 約束確保唯一數(shù)據(jù),所以經(jīng)常用來定義標識列。
2、主鍵作用
1)保證實體的完整性;
2)加快數(shù)據(jù)庫的操作速度
3) 在表中添加新記錄時,數(shù)據(jù)庫會自動檢查新記錄的主鍵值,不允許該值與其他記錄的主鍵值重復(fù)。
4) 數(shù)據(jù)庫自動按主鍵值的順序顯示表中的記錄。如果沒有定義主鍵,則按輸入記錄的順序顯示表中的記錄。
3、主鍵的必要性
在有些數(shù)據(jù)庫中,雖然主鍵不是必需的,但最好為每個表都設(shè)置一個主鍵,不管是單主鍵還是復(fù)合主鍵。它存在代表著表結(jié)構(gòu)的完整性,表的記錄必須得有唯一區(qū)分的字段,主鍵主要是用于其他表的外鍵關(guān)聯(lián),以及本記錄的修改與刪除。
4、主鍵的選擇
1)編號作主鍵
此方法就是采用實際業(yè)務(wù)中的唯一字段的“編號”作為主鍵設(shè)計,這在小型的項目中是推薦這樣做的,因為這可以使項目比較簡單化,但在使用中卻可能帶來一些麻煩,比如要進行“編號修改”時,可能要涉及到很多相關(guān)聯(lián)的其他表
2)自動編號主鍵
這種方法也是很多人在使用的,就是新建一個ID字段,自動增長,非常方便也滿足主鍵的原則
a、優(yōu)點:數(shù)據(jù)庫自動編號,速度快,而且是增量增長,聚集型主鍵按順序存放,對于檢索非常有利;數(shù)字型的,占用空間小,易排序,在程序中傳遞也方便;如果通過非系統(tǒng)增加記錄(比如手動錄入,或是用其他工具直接在表里插入新記錄,或老系統(tǒng)數(shù)據(jù)導(dǎo)入)時,非常方便,不用擔心主鍵重復(fù)問題。
b、缺點:其實缺點也就是來自其優(yōu)點,就是因為自動增長,在手動要插入指定ID的記錄時會顯得麻煩,尤其是當系統(tǒng)與其他系統(tǒng)集成時,需要數(shù)據(jù)導(dǎo)入時,很難保證原系統(tǒng)的ID不發(fā)生主鍵沖突(前提是老系統(tǒng)也是數(shù)字型的);如果其他系統(tǒng)主鍵不是數(shù)字型那就麻煩更大了,會導(dǎo)致修改主鍵數(shù)據(jù)類型了,這也會導(dǎo)致其他相關(guān)表的修改,后果同樣很嚴重;就算其他系統(tǒng)也是數(shù)字型的,在導(dǎo)入時,為了區(qū)分新老數(shù)據(jù),可能想在老數(shù)據(jù)主鍵前統(tǒng)一加一個“o”(old)來表示這是老數(shù)據(jù),那么自動增長的數(shù)字型又面臨一個挑戰(zhàn)。
3)Max加一
由于自動編號存在那些問題,所以有些人就采用自己生成,同樣是數(shù)字型的,只是把自動增長去掉了,采用在Insert時,讀取Max值后加一,這種方法可以避免自動編號的問題,但也存在一個效率問題,如果記錄非常大的話,那么Max()也會影響效率的;更嚴重的是并發(fā)性問題,如果同時有兩人讀到相同的Max后,加一后插入的ID值會重復(fù),這已經(jīng)是有經(jīng)驗教訓(xùn)的了。
4)自制加一
考慮Max加一的效率后,有人采用自制加一,也就是建一個特別的表,字段為:表名,當前序列值。這樣在往表中插入值時,先從此表中找到相應(yīng)表的最大值后加一,進行插入,有人可能發(fā)現(xiàn),也可能會存在并發(fā)處理,這個并發(fā)處理,可以采用lock線程的方式來避免,在生成此值的時,先Lock,取到值以后,再unLock出來,這樣不會有兩人同時生成了。這比Max加一的速度要快多了。但同樣存在一個問題:在與其他系統(tǒng)集成時,脫離了系統(tǒng)中的生成方法后,很麻煩保證自制表中的最大值與導(dǎo)入后的保持一致,而且數(shù)字型都存在上面講到的“o”老數(shù)據(jù)的導(dǎo)入問題。因此在“自制加一”中可以把主鍵設(shè)為字符型的。字符型的自制加一中應(yīng)該字符型主鍵可以應(yīng)付很多我們意想不到的情況。
5)GUID主鍵
目前一個比較好的主鍵是采用GUID,推薦主鍵還是字符型的,但值由GUID生成,GUID是可以自動生成,也可以程序生成,而且鍵值不可能重復(fù),可以解決系統(tǒng)集成問題,幾個系統(tǒng)的GUID值導(dǎo)到一起時,也不會發(fā)生重復(fù),就算有“o”老數(shù)據(jù)也可以區(qū)分,而且效率很高,在.NET里可以直接使用System.Guid.NewGuid()進行生成,在SQL里也可以使用NewID()生成。優(yōu)點是:
同IDENTITY 列相比,uniqueidentifier 列可以通過NewID() 函數(shù)提前得知新增加的行ID,為應(yīng)用程序的后續(xù)處理提供了很大方便。
a、優(yōu)點:便于數(shù)據(jù)庫移植,其它數(shù)據(jù)庫中并不一定具有IDENTITY 列,而Guid 列可以作為字符型列轉(zhuǎn)換到其它數(shù)據(jù)庫中,同時將應(yīng)用程序中產(chǎn)生的GUID 值存入數(shù)據(jù)庫,它不會對原有數(shù)據(jù)帶來影響。便于數(shù)據(jù)庫初始化,如果應(yīng)用程序要加載一些初始數(shù)據(jù),IDENTITY 列的處理方式就比較麻煩,而uniqueidentifier 列則無需任何處理,直接用T-SQL 加載即可。便于對某些對象或常量進行永久標識,如類的ClassID,對象的實例標識,UDDI 中的聯(lián)系人、服務(wù)接口、tModel標識定義等。
b:缺點是:
GUID 值較長,不容易記憶和輸入,而且這個值是隨機、無順序的
GUID 的值有16 個字節(jié),與其它那些諸如4 字節(jié)的整數(shù)相比要相對大一些。這意味著如果在數(shù)據(jù)庫中使用uniqueidentifier 鍵,可能會帶來兩方面的消極影響:存儲空間增大;索引時間較慢。
1.主鍵語法
①創(chuàng)建時:create table sc (
studentno int,
courseid int,
score int,
primary key (studentno) );
②修改時:ALTER TABLE table_name ADD CONSTRAINT pk_name PRIMARY KEY(列名);
前提是原先沒有設(shè)置主鍵。
2.外鍵語法
①創(chuàng)建時:create table sc (
studentno int,
courseid int,
score int,
foreign key (courseid) );
②修改時:
ALTER TABLE news_info[子表名] ADD CONSTRAINT FK_news_info_news_type[約束名] FOREIGN KEY (info_id)[子表列] REFERENCES news_type[主表名] (id)[主表列] ;
3.使用組合主鍵
如果一列不能唯一區(qū)分一個表里的記錄時,可以考慮多個列組合起來達到區(qū)分表記錄的唯一性,形式
①創(chuàng)建時:create table sc (
studentno int,
courseid int,
score int,
primary key (studentno,courseid) );
②修改時:alter table tb_name add primary key (字段1,字段2,字段3);
前提是原來表中沒有設(shè)置主鍵,若原先已有主鍵則會報錯。
聯(lián)合主鍵:把兩個列看成是一個整體,這個整體是不為空,唯一,不重復(fù)
1.創(chuàng)建表的同時創(chuàng)建聯(lián)合主鍵
語法1
語法2
2.針對已經(jīng)存在表,添加聯(lián)合主鍵