<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 297,  comments - 1618,  trackbacks - 0

    文:阿蜜果

    日期:2011-10-16

    版權(quán)所有,轉(zhuǎn)載請注明出處

    1、 何謂數(shù)據(jù)庫主鍵

    數(shù)據(jù)庫主鍵是指表中一個列或列的組合,其值能唯一地標(biāo)識表中的每一行。這樣的一列或多列稱為表的主鍵,通過它可強(qiáng)制表的實體完整性。當(dāng)創(chuàng)建或更改表時可通過定義 PRIMARY KEY 約束來創(chuàng)建主鍵。一個表只能有一個 PRIMARY KEY 約束,而且 PRIMARY KEY 約束中的列不能接受空值。由于 PRIMARY KEY 約束確保唯一數(shù)據(jù),所以經(jīng)常用來定義標(biāo)識列。

    1.1 主鍵的作用

    主鍵的主要作用如下:

    1)保證實體的完整性;

    2)加快數(shù)據(jù)庫的操作速度;

    3 在表中添加新記錄時,數(shù)據(jù)庫會自動檢查新記錄的主鍵值,不允許該值與其他記錄的主鍵值重復(fù);

    4) 數(shù)據(jù)庫自動按主鍵值的順序顯示表中的記錄。如果沒有定義主鍵,則按輸入記錄的順序顯示表中的記錄。

    1.2 主鍵的特點

    1)唯一性一個表中只能有一個主鍵。如果在其他字段上建立主鍵,則原來的主鍵就會取消。

    2)非空性:主鍵的值不可重復(fù),也不可為空;

    3)必要性:在有些數(shù)據(jù)庫中,雖然主鍵不是必需的,但最好為每個表都設(shè)置一個主鍵,不管是單主鍵還是復(fù)合主鍵。它存在代表著表結(jié)構(gòu)的完整性,表的記錄必須得有唯一區(qū)分的字段,主鍵主要是用于其他表的外鍵關(guān)聯(lián),以及本記錄的修改與刪除;

    4)無意義性:在開發(fā)過程中,讀者可能會看到將一些表使用有意義的字段表示主鍵,例如“用戶登錄信息表”將“登錄名”(英文名)作為主鍵,“訂單表”中將“訂單編號”作為主鍵,如此設(shè)計主鍵一般都是沒什么問題,因為將這些主鍵基本不具有“意義更改”的可能性。但是,也有一些例外的情況,例如“訂單表”需要支持需求“訂單可以作廢,并重新生成訂單,而且訂單號要保持原訂單號一致”,那將“訂單編號”作為主鍵就滿足不了要求了。因此讀者在使用具有實際意義的字段作為主鍵時,需要考慮是否存在這種可能性。

    2、 主鍵的創(chuàng)建和更改

      在MySQL中,創(chuàng)建時指定某字段為主鍵的舉例如下:

    create table article (
    id 
    int(4primary key not null auto_increment,
    name 
    varchar(100not null,
    author 
    varchar(32not null,
    publishTime 
    datetime default NULL
    );

      標(biāo)示為主鍵的字段需要使用“primary key”標(biāo)識。

    若要刪除某個表中之前的主鍵,并設(shè)置另外一個字段作為主鍵,參考語句如下:

    ALTER TABLE 表名 DROP PRIMARY KEYADD PRIMARY KEY (新的主鍵字段);

    主鍵可以在執(zhí)行create table操作時,在字段的后面使用“primary key”指定,也可以不位于字段后面,例如如下語句:

    create table ss_schedule
    (
        schedulekey            
    varchar(30not null,
        schedulename           
    varchar(255),
        updatekey              
    varchar(30),
        
    primary key (schedulekey)
    );

     3、 主鍵的選擇以及優(yōu)缺點比較

    3.1 自增主鍵

           這種方式是使用數(shù)據(jù)庫提供的自增數(shù)值型字段作為自增主鍵,它的優(yōu)點是:

    1)數(shù)據(jù)庫自動編號,速度快,而且是增量增長,按順序存放,對于檢索非常有利;

    2)數(shù)字型,占用空間小,易排序,在程序中傳遞也方便;

    3)如果通過非系統(tǒng)增加記錄時,可以不用指定該字段,不用擔(dān)心主鍵重復(fù)問題。

    其實它的缺點也就是來自其優(yōu)點,缺點如下:

    1)因為自動增長,在手動要插入指定ID的記錄時會顯得麻煩,尤其是當(dāng)系統(tǒng)與其它系統(tǒng)集成時,需要數(shù)據(jù)導(dǎo)入時,很難保證原系統(tǒng)的ID不發(fā)生主鍵沖突(前提是老系統(tǒng)也是數(shù)字型的)。特別是在新系統(tǒng)上線時,新舊系統(tǒng)并行存在,并且是異庫異構(gòu)的數(shù)據(jù)庫的情況下,需要雙向同步時,自增主鍵將是你的噩夢;

    2)在系統(tǒng)集成或割接時,如果新舊系統(tǒng)主鍵不同是數(shù)字型就會導(dǎo)致修改主鍵數(shù)據(jù)類型,這也會導(dǎo)致其它有外鍵關(guān)聯(lián)的表的修改,后果同樣很嚴(yán)重;

    3)若系統(tǒng)也是數(shù)字型的,在導(dǎo)入時,為了區(qū)分新老數(shù)據(jù),可能想在老數(shù)據(jù)主鍵前統(tǒng)一加一個字符標(biāo)識(例如“o”,old)來表示這是老數(shù)據(jù),那么自動增長的數(shù)字型又面臨一個挑戰(zhàn)。

    MySQLauto_increment)、SQL ServerIDENTITY)、InformixOracle(首先創(chuàng)建自增序列,接著為自增主鍵的表創(chuàng)建插入時的觸發(fā)器,給自增主鍵ID賦值)等數(shù)據(jù)庫都支持這種自增主鍵,這種主鍵在各種系統(tǒng)中應(yīng)用廣泛,但是如果考慮到有新舊系統(tǒng)并存等問題,為了避免不必要的麻煩,使用自增主鍵要三思。

    3.2 max+1主鍵

    由于增主鍵存在的缺點,所以有些開發(fā)人員就采用自己生成同樣是數(shù)字型的的主鍵,但不是系統(tǒng)自動生成的。具體的方式是:在INSERT時,讀取主鍵IDMax值后,加1,這種方法可以避免自動編號的問題,但是也存在各種缺點:

    1)效率問題:如果記錄非常大的話,那么Max()也會影響效率的;

    2)并發(fā)性問題:如果同時有兩人讀到相同的Max后,加一后插入的ID值會重復(fù)。

    基于這些明顯的缺點,筆者不提倡使用此種方式。

    3.3 自制+1主鍵

    考慮max+1的效率后,有的開發(fā)人員采用自制加1,也就是建一個特別的表,字段為:表名、當(dāng)前序列值。這樣在往表中插入值時,先從此表中找到相應(yīng)表的最大值后加一,進(jìn)行插入,但也可能會存在并發(fā)處理,但是開發(fā)人員可以采用lock線程的方式來避免:在生成此值的時,先Lock,取到值以后,再unLock出來,這樣不會有兩人同時生成了。這比max+1的速度要快多了。

    就算解決了并發(fā)的問題,但此種方式同樣存在致命的缺點:

    1)在與其他系統(tǒng)集成時,脫離了系統(tǒng)中的生成方法后,很麻煩保證自制表中的最大值與導(dǎo)入后的保持一致。

    因為此種還需要創(chuàng)建新表,比較麻煩,因此筆者也不推薦此種方式。

    3.4 具有實際意義的主鍵

             有些表可以使用具有實際意義的主鍵,但這種表為數(shù)不多,因為要保證該字段長久的具有行記錄唯一的特點,如若有可能變成該表中的非唯一字段,那它就不適合將其變成主鍵。

             筆者建議有些表可以使用具有實際意義的主鍵,例如“用戶信息表”的“用戶登錄名”字段基本都是唯一的,而且?guī)缀醪豢赡茏兂梢粋€登錄名對應(yīng)兩條記錄,因此可以使用其作為主鍵。另外,例如“一號通用戶信息表”中,“一號通號碼”肯定是唯一的,因此也可作為主鍵。

    3.5 GUID主鍵

    目前一個比較好的主鍵是采用GUIDGlobally Unique Identifier,全球唯一標(biāo)識符),GUID的特點如下:

    (1)   在空間上和時間上具有唯一性,保證同一時間不同地方產(chǎn)生的數(shù)字不同;

    (2)   世界上的任何兩臺計算機(jī)都不會生成重復(fù)的GUID值;

    (3)   需要GUID的時候,可以完全由算法自動生成,不需要一個權(quán)威機(jī)構(gòu)來管理;

    (4)   GUID的長度固定,并且相對而言較短小,非常適合于排序、標(biāo)識和存儲。

    可以將GUID主鍵定義為字符型,但值由GUID生成,GUID是可以自動生成,也可以程序生成,而且鍵值不可能重復(fù),可以解決系統(tǒng)集成問題,幾個系統(tǒng)的GUID值導(dǎo)到一起時,也不會發(fā)生重復(fù),就算有“o”老數(shù)據(jù)也可以區(qū)分,而且效率很高。在SQL里也可以使用 NewID()生成。主要優(yōu)點是:

    1)同 IDENTITY 列相比,uniqueidentifier 列可以通過 NewID() 函數(shù)提前得知新增加行的ID,為應(yīng)用程序的后續(xù)處理提供很大方便;

    2)便于數(shù)據(jù)庫移植,其它數(shù)據(jù)庫中并不一定具有 IDENTITY 列,而 GUID列可以作為字符型列轉(zhuǎn)換到其它數(shù)據(jù)庫中,同時將應(yīng)用程序中產(chǎn)生的GUID值存入數(shù)據(jù)庫,它不會對原有數(shù)據(jù)帶來影響。

    缺點是:

    1GUID值較長,不容易記憶和輸入,而且這個值是隨機(jī)、無順序的。

    2GUID的值有16個字節(jié),與其它諸如 4 字節(jié)的整數(shù)相比要相對大一些。這意味著如果在數(shù)據(jù)庫中使用 uniqueidentifier 鍵,可能會帶來兩方面的消極影響:存儲空間增大、索引時間較慢。

    基于上面的分析,使用GUID的利大于弊,筆者推薦可以采用此種方式。

    3.6 自制唯一字符型主鍵

             為了系統(tǒng)集成等的方便,筆者建議將主鍵定義成字符型,可以使用GUID作為主鍵,也可以定義一個字符型的主鍵字段,但是它的值使用變成編程指定。該種方式的優(yōu)點是:

    1)在異庫異構(gòu)數(shù)據(jù)庫的情況下,若舊系統(tǒng)這些表的主鍵ID是自增的(數(shù)值型),而新系統(tǒng)生成的主鍵是比較長的字符串型(例如15位),那樣舊系統(tǒng)生成或之前的舊數(shù)據(jù)同步到新系統(tǒng)時,都不會沖突。

    這種方式的缺點是:

    (1)       需要程序能生成定長的唯一字符串,例如:當(dāng)前時間+自動機(jī)號+進(jìn)程ID+……;

    (2)       由第三方系統(tǒng)生成或手動生成該主鍵時,處理比較麻煩。

    3.7 總結(jié)

             在上面幾種主鍵中,較為常用的是“3.1 自增主鍵”和“3.5 GUID主鍵”,當(dāng)在有些特殊的表和某些特定情況中,也可以采用“3.4 具有實際意義的主鍵”和“3.6 自制唯一的字符型主鍵”。

    4、 參考文檔

    1)《主鍵設(shè)計用什么字段類型比較好》:

    http://www.th7.cn/Article/bc/de/200902/20090220080511.html

    2)《主關(guān)鍵字_百度百科》:

    http://baike.baidu.com/view/68068.htm

    3)《GUID_百度百科》:

    http://baike.baidu.com/view/185358.htm

     

    posted on 2011-10-16 13:10 阿蜜果 閱讀(3690) 評論(4)  編輯  收藏 所屬分類: database


    FeedBack:
    # re: 蜜果私塾:數(shù)據(jù)庫主鍵的設(shè)計和思考
    2011-10-17 09:56 | jeffma
    太好了,困擾了我很久的主鍵問題。
    我的理解:能使用有意義的鍵做主鍵的,就使用有意義的鍵做主鍵,常見的如組織機(jī)構(gòu)、用戶、權(quán)限、角色、菜單等,方便系統(tǒng)初始化時基本數(shù)據(jù)的導(dǎo)入,如果使用自增長主鍵,很難設(shè)置這些數(shù)據(jù)關(guān)聯(lián)的外鍵;不能使用有意義主鍵,如為了避免復(fù)合主鍵,可以考慮使用自增長或GUID。  回復(fù)  更多評論
      
    # re: 蜜果私塾:數(shù)據(jù)庫主鍵的設(shè)計和思考
    2011-10-17 09:59 | 阿蜜果
    @jeffma
    其實我是推薦盡量少用有意義的主鍵,其實可以用這種有意義的主鍵的表是很少的,例如“用戶信息表”的“用戶名”等,你說的權(quán)限、角色、菜單等其實最好用GUID或自增主鍵。  回復(fù)  更多評論
      
    # re: 蜜果私塾:數(shù)據(jù)庫主鍵的設(shè)計和思考
    2011-10-17 22:09 | tb
    恩 很不錯   回復(fù)  更多評論
      
    # re: 蜜果私塾:數(shù)據(jù)庫主鍵的設(shè)計和思考
    2011-10-20 17:54 | jeffma
    像組織機(jī)構(gòu)、菜單這些都是樹狀結(jié)構(gòu)的數(shù)據(jù),可能會在系統(tǒng)初始化時先以SQL插入,但是如果主鍵使用GUID或自增主鍵其中的parent字段如何填寫?

    code name parent
    14010000 省公司 null
    14010100 xx市 14010000
    14010200 yy市 14010000
    14010101 xx縣 14010100  回復(fù)  更多評論
      
    <2011年10月>
    2526272829301
    2345678
    9101112131415
    16171819202122
    23242526272829
    303112345

          生活將我們磨圓,是為了讓我們滾得更遠(yuǎn)——“圓”來如此。
          我的作品:
          玩轉(zhuǎn)Axure RP  (2015年12月出版)
          

          Power Designer系統(tǒng)分析與建模實戰(zhàn)  (2015年7月出版)
          
         Struts2+Hibernate3+Spring2   (2010年5月出版)
         

    留言簿(263)

    隨筆分類

    隨筆檔案

    文章分類

    相冊

    關(guān)注blog

    積分與排名

    • 積分 - 2294895
    • 排名 - 3

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲精品一二三区| 亚洲成AV人片天堂网无码| 亚洲综合久久1区2区3区| 日本黄色动图免费在线观看| 亚洲婷婷五月综合狠狠爱| 国产无限免费观看黄网站| 国产精品亚洲аv无码播放| 精品免费tv久久久久久久| 亚洲妇熟XXXX妇色黄| 一区二区三区福利视频免费观看| 亚洲AV日韩AV天堂久久| 久久久久免费精品国产小说| 亚洲美女视频网址| 久久久久久久久免费看无码| 亚洲高清国产拍精品熟女| 免费一看一级毛片| 久久免费国产精品| 亚洲精品美女在线观看| 国内外成人免费视频| 全部在线播放免费毛片| 久久久影院亚洲精品| 西西大胆无码视频免费| 老司机精品视频免费| 亚洲AV无码久久寂寞少妇| 国产福利在线观看免费第一福利| 亚洲妇女无套内射精| 亚洲精品无码久久千人斩| 99re在线这里只有精品免费| 亚洲精品av无码喷奶水糖心| 国产精品V亚洲精品V日韩精品| 无码精品国产一区二区三区免费| 亚洲精品中文字幕无乱码麻豆| 一区二区三区亚洲视频| 日本xxxx色视频在线观看免费| 亚洲精品无码av片| 亚洲av永久无码精品漫画| 成人免费无遮挡无码黄漫视频| 日本中文字幕免费看| 亚洲成人在线免费观看| 亚洲国产天堂久久久久久| 91成人在线免费观看|