<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

    版權所有,轉載請注明出處

    1、 何謂數據庫主鍵

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

    1.1 主鍵的作用

    主鍵的主要作用如下:

    1)保證實體的完整性;

    2)加快數據庫的操作速度;

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

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

    1.2 主鍵的特點

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

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

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

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

    2、 主鍵的創建和更改

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

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

      標示為主鍵的字段需要使用“primary key”標識。

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

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

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

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

     3、 主鍵的選擇以及優缺點比較

    3.1 自增主鍵

           這種方式是使用數據庫提供的自增數值型字段作為自增主鍵,它的優點是:

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

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

    3)如果通過非系統增加記錄時,可以不用指定該字段,不用擔心主鍵重復問題。

    其實它的缺點也就是來自其優點,缺點如下:

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

    2)在系統集成或割接時,如果新舊系統主鍵不同是數字型就會導致修改主鍵數據類型,這也會導致其它有外鍵關聯的表的修改,后果同樣很嚴重;

    3)若系統也是數字型的,在導入時,為了區分新老數據,可能想在老數據主鍵前統一加一個字符標識(例如“o”,old)來表示這是老數據,那么自動增長的數字型又面臨一個挑戰。

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

    3.2 max+1主鍵

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

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

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

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

    3.3 自制+1主鍵

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

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

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

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

    3.4 具有實際意義的主鍵

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

             筆者建議有些表可以使用具有實際意義的主鍵,例如“用戶信息表”的“用戶登錄名”字段基本都是唯一的,而且幾乎不可能變成一個登錄名對應兩條記錄,因此可以使用其作為主鍵。另外,例如“一號通用戶信息表”中,“一號通號碼”肯定是唯一的,因此也可作為主鍵。

    3.5 GUID主鍵

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

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

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

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

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

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

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

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

    缺點是:

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

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

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

    3.6 自制唯一字符型主鍵

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

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

    這種方式的缺點是:

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

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

    3.7 總結

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

    4、 參考文檔

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

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

    2)《主關鍵字_百度百科》:

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

    3)《GUID_百度百科》:

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

     

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


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

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

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

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

    留言簿(263)

    隨筆分類

    隨筆檔案

    文章分類

    相冊

    關注blog

    積分與排名

    • 積分 - 2294312
    • 排名 - 3

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲乱码日产一区三区| 亚洲伊人久久大香线蕉啊| 久久免费高清视频| 亚洲成人免费电影| 四虎影库久免费视频| 久久精品国产免费一区| 亚洲一区二区三区91| 亚洲国产V高清在线观看| 久久久久久AV无码免费网站下载 | 91在线老王精品免费播放| 亚洲人成77777在线播放网站不卡| 一本色道久久88亚洲综合 | 韩国18福利视频免费观看| jizz中国免费| 亚洲av无码一区二区三区天堂古代| 免费va在线观看| 鲁大师在线影院免费观看| 亚洲av成人一区二区三区观看在线| 亚洲午夜国产精品无码| 18禁超污无遮挡无码免费网站国产| 国产精品1024在线永久免费 | 一级毛片免费毛片一级毛片免费| 亚洲性无码AV中文字幕| 亚洲av综合色区| 免费一看一级毛片| 8x8×在线永久免费视频| 成人国产网站v片免费观看| 亚洲最大成人网色香蕉| 亚洲va国产va天堂va久久| 全部免费a级毛片| 成人免费a级毛片| 9420免费高清在线视频| 一级做受视频免费是看美女| 亚洲av午夜成人片精品电影| a级毛片在线免费| 337P日本欧洲亚洲大胆精品| 亚洲网站在线播放| 亚洲国产成人片在线观看| 亚洲国产精品成人久久蜜臀| 一个人看的www在线观看免费| 国产成人精品免费久久久久|