首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server uniqueidentifier 與 NEWID() 函數完整應用指南

     編輯:關於SqlServer

核心概念

  • uniqueidentifier:16 位元組二進位值,全域唯一識別碼 (GUID)
  • NEWID():產生唯一識別碼,基於網卡 MAC 位址 + CPU 時鐘
  • 與 IDENTITY 差異:不自動產生,需顯式呼叫 NEWID();無序、較大 (16 bytes vs 4/8 bytes)

基本語法與範例

建立資料表與預設值


CREATE TABLE MyUniqueTable (
    UniqueColumn UNIQUEIDENTIFIER DEFAULT NEWID(),
    Characters VARCHAR(10)
);
GO

-- 插入時自動產生 GUID
INSERT INTO MyUniqueTable (Characters) VALUES ('abc');
-- 或顯式指定
INSERT INTO MyUniqueTable VALUES (NEWID(), 'def');
GO

變數使用 NEWID()


DECLARE @myid UNIQUEIDENTIFIER;
SET @myid = NEWID();
PRINT 'Value of @myid is: ' + CONVERT(VARCHAR(255), @myid);
-- 輸出範例:6F9619FF-8B86-D011-B42D-00C04FC964FF

完整資料表範例:客戶主檔


CREATE TABLE cust (
    CustomerID UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID(),
    Company VARCHAR(30) NOT NULL,
    ContactName VARCHAR(60) NOT NULL,
    Address VARCHAR(30) NOT NULL,
    City VARCHAR(30) NOT NULL,
    StateProvince VARCHAR(10) NULL,
    PostalCode VARCHAR(10) NOT NULL,
    CountryRegion VARCHAR(20) NOT NULL,
    Telephone VARCHAR(15) NOT NULL,
    Fax VARCHAR(15) NULL
);
GO

INSERT INTO cust (CustomerID, Company, ContactName, Address, City, StateProvince, PostalCode, CountryRegion, Telephone, Fax)
VALUES (NEWID(), 'Wartian Herkku', 'Pirkko Koskitalo', 'Torikatu 38', 'Oulu', NULL, '90110', 'Finland', '981-443655', '981-443655');

INSERT INTO cust (CustomerID, Company, ContactName, Address, City, StateProvince, PostalCode, CountryRegion, Telephone, Fax)
VALUES (NEWID(), 'Wellington Importadora', 'Paula Parente', 'Rua do Mercado, 12', 'Resende', 'SP', '08737-363', 'Brasil', '(14) 555-8122', '');

-- 更多插入範例...
GO

指定特定 GUID 值 (測試/遷移用)


DECLARE @myid UNIQUEIDENTIFIER;
SET @myid = 'A972C577-DFB0-064E-1189-0154C99310DA'; -- 注意:標準 GUID 32 字元 + 4 連字號 = 36 字元
GO

進階應用場景

1. 分散式系統主鍵

  • 多伺服器/離線端獨立產生主鍵,合併時零衝突
  • 合併複寫、Peer-to-Peer 複寫必要條件

2. URL/API 公開識別碼

  • 避免連續數字被推測資料量/遍歷攻擊
  • 如:/api/orders/6F9619FF-8B86-D011-B42D-00C04FC964FF

3. 暫存表/暫存資料關聯

  • 跨 Session/Procedure 傳遞識別碼,不依賴序列

效能與儲存考量

面向uniqueidentifierINT IDENTITYBIGINT IDENTITY
儲存大小16 bytes4 bytes8 bytes
索引大小大小中
插入效能隨機 I/O、頁分裂多順序寫入、最佳順序寫入
碎片率高,需定期重建低低
適用場景分散式、合併、安全性單機、高寫入單機、極大資料量

緩解策略

  • NEWSEQUENTIALID() (僅限 DEFAULT 約束):
    • 產生有序 GUID,大幅減少頁分裂
    • 但可預測性稍高,不適用安全敏感場景
  • 叢集索引改用 INT/BIGINT 代理鍵,uniqueidentifier 做非叢集唯一索引
  • 填充因子 (Fill Factor) 設 80-90% 減少分裂

NEWID() vs NEWSEQUENTIALID()

特性NEWID()NEWSEQUENTIALID()
呼叫方式任意處可呼叫僅限 DEFAULT 約束
順序性完全隨機遞增 (重啟後可能重置)
頁分裂嚴重輕微
可預測性不可預測部分可預測
安全性高中

結語

uniqueidentifier + NEWID() 是分散式系統、合併複寫、公開 API 識別碼的標準解法。單機高寫入場景請優先考慮 INT/BIGINT IDENTITY 或 NEWSEQUENTIALID() + 非叢集索引架構。選型前務必評估:分散式需求、寫入量、索引維護成本、安全性要求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved