關系型數據庫的幾種常用主鍵


一般來說關系型數據庫,絕大多數表都有數據庫主鍵。

 

數據庫主鍵的創建,一般有如下幾種形式:

1. 使用數據庫自增長主鍵的語法。

有些數據庫,比如 MS SQL Server, MySQL ,都有對應的語法,可以在創建數據庫表的時候,指定某個字段為自增長主鍵。Oracle , PostgreSQL 則使用 sequence , 來達到類似的作用。

以下是 MS SQL Server 示例:

create table tb(id int identity(1,1) primary key );

 

以下是 PostgreSQL 示例:

//serial 並不是psql的類型,只是一個宏,
create table tablename ( colname serial ); //等價於 CREATE SEQUENCE tablename_colname_seq; CREATE TABLE tablename ( colname integer NOT NULL DEFAULT nextval('tablename_colname_seq') ); ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

 

自增長數據庫主鍵,一般是 int/long 之類的整數/長整數。理論上有數據最大容量限制。

在 java/c# 代碼中,可將這種主鍵字段,轉換為 long.

 

2. 使用數據庫的 GUID/UUID 之類的語法。

一般是數據字段類型 + 數據庫內置函數設置默認值,來定義一個列。

以下是 MS SQL Server 示例:

CREATE TABLE dbo.Globally_Unique_Data
(
    GUID UNIQUEIDENTIFIER
        CONSTRAINT Guid_Default DEFAULT
        NEWSEQUENTIALID() ROWGUIDCOL,
    Employee_Name VARCHAR(60)
    CONSTRAINT Guid_PK PRIMARY KEY (GUID)
);

在 java/c# 代碼中,可將這種主鍵字段,轉換為 string.

 

3. 使用字符串作為表主鍵,在java/c# 代碼中生成 uuid ,填充數值。

以下是 MS SQL Server 示例:

CREATE TABLE [dbo].[tt_process_request](
    [process_request_uuid] [varchar](40) NOT NULL,
...
    [created_time] [datetime] NULL,
    [created_by] [varchar](50) NULL,
    [updated_time] [datetime] NULL,
    [updated_by] [varchar](50) NULL,
    [updated_cnt] [bigint] NULL,
 CONSTRAINT [PK_tt_process_request] PRIMARY KEY CLUSTERED 
(
    [process_request_uuid] ASC
);

C# 生成 uuid 的代碼示例:

string fileUuid = System.Guid.NewGuid().ToString();

 

Java 生成 uuid 的代碼示例如下:

    public String createUuid() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

 

代碼生成的 uuid, 中間有 - 分割數據,可以保留,也可以替換/去掉。

 

4. 使用字符型字段作為數據庫表主鍵,對應某個業務數據。比如合同號: PS21152357。

這類數據中,往往其中的某幾位,有一定的業務業務含義,比如,此處 "PS" 為合同號的標識。其它位數,為順序號。

需要編寫 在 java/c# 代碼中,來生成這種編號,並做並發防范。

 

總結:

方法4 , 一般稱之為“業務主鍵”。對應的, 1-3 為“邏輯主鍵”

總體而言,應盡量避免使用“業務主鍵”。因為使用這種主鍵,有時並非系統自動生成,而是人工錄入(比如,數據源頭在 ERP,現要在另一個系統中錄入數據),人工錄入存在一定的出錯幾率,如果錄入出錯需要更改主鍵數據,則外鍵也要一並更改,往往比較麻煩。

 

1-3 的三種“邏輯主鍵”,我更傾向於第三種。

方法3" 使用字符串作為表主鍵,在java/c# 代碼中生成 uuid ,填充數值",不用考慮不同數據庫間的差異,可以認為任何數據庫都支持。使用起來也簡單。

如果是使用自動生成代碼工具,要看情況吧。可能有的工具,處理不了。我自己編寫的工具,處理起來沒問題。

 

至於 uuid 字段串,占用磁盤空間,比自增長整數/長整數占用的大的問題,其實我覺得並不是大問題。

這不會導致整個系統,磁盤空間需求,增加 1/4 或更多。一般可以忽略。

 

另,

數據庫主鍵的定義,在某些數據庫中,往往會自動帶上"按此字段進行順序存儲"之類的語法。比如,SQL Server ,以下是示例:

CREATE TABLE [dbo].[tt_process_request](
    [process_request_uuid] [varchar](40) NOT NULL,
...,
 CONSTRAINT [PK_tt_process_request] PRIMARY KEY CLUSTERED 
(
    [process_request_uuid] ASC
)
) ;

 

這可以通過更改創建表的 SQL, 使用 PRIMARY KEY NONCLUSTERED 語法

CREATE TABLE dbo.Department
(
    xxx VARCHAR(10) NOT NULL PRIMARY KEY NONCLUSTERED,
    ...
)
;

 

然后再加 CLUSTERED INDEX ,來解決此問題。

CREATE CLUSTERED INDEX IX_TestTable_TestCol1   
    ON dbo.TestTable (TestCol1);  

 

當然,數據庫表也可以既沒有 CLUSTERED key、 也沒有 CLUSTERED index 。

這種情況下,表的數據存儲,按 insert 的時間順序,從先到后。大多數情況下,這種數據存放方式,是可以接受的。

數據顯示時,再按照某個時間字段(交易數據, 比如銷售單的銷售時間),或者業務數據主鍵(主數據/系統配置等),進行查詢排序,查詢到排序后的數據,顯示給用戶。

 

===============歡迎轉載,轉載請注明出處:https://www.cnblogs.com/jacklondon/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM