Which one is the best choice for primary key in SQL Server?

100

e.g.

CREATE TABLE new_employees
   (employeeId   UNIQUEIDENTIFIER      DEFAULT NEWID(),
   fname      VARCHAR(20) )
GO
INSERT INTO new_employees(fname) VALUES ('Karin')
GO

100

e.g.

 CREATE TABLE new_employees
 (
  employeeId int IDENTITY(1,1),
  fname varchar (20)
 );

 INSERT new_employees
    (fname)
 VALUES
    ('Karin');

[Material Code](or Business Code,which identity of a material. e.g. customer identifier)

e.g.

CREATE TABLE new_employees(
    [ClientId] [varchar](20) NOT NULL,
    [fName] [varchar](20) NULL      
 )

 INSERT new_employees
    (ClientID, fname)
 VALUES
    ('C0101000001',--customer identifier,e.g.'C0101000001' a user-defined code.
     'Karin');

请给我一些建议,从三个类型标识列中 Select 主键,或者其他 Select .

谢谢!

推荐答案

GUID似乎是您的主键的自然 Select -如果您真的必须这样做,您可能会主张将它用作表的主键.我强烈建议not to do使用GUID列作为clustering key,这是SQL Server默认使用的,除非您特别告诉它不要这样做.

你真的需要把两个问题分开:

  1. primary key是一个逻辑 struct -唯一且可靠地标识表中每一行的候选键之一.这可以是任何东西,真的-INTGUID、字符串- Select 对您的场景最有意义的.

  2. clustering key(定义表上的"聚集索引"的一列或多列)-这是与physical存储相关的内容,在这里,一个小的、稳定的、不断增加的数据类型是您的最佳 Select -INTBIGINT作为默认选项.

默认情况下,SQL Server表上的主键也用作集群键——但不需要这样!我个人看到,将以前基于GUID的主键/聚集键拆分为两个单独的键时,性能有了巨大的提高——GUID上的主键(逻辑键)和INT IDENTITY(1,1)列上的聚集键(排序键).

正如Kimberly Tripp-Queen of Indexing-和其他人多次声明的那样,GUID作为聚集键并不是最佳的,因为由于它的随机性,它将导致大量的页面和索引碎片,并且通常会导致较差的性能.

是的,我知道——SQLServer2005和更高版本中有newsequentialid()个——但即使是这样,也不是真正的、完全连续的,因此也存在着与GUID相同的问题——只是不太明显.

然后还有另一个问题需要考虑:表上的聚集键也将被添加到表上每个非聚集索引的每个条目中-因此您确实希望确保它尽可能小.通常,包含20多亿行的INT行应该足以容纳绝大多数表-与作为聚集键的GUID相比,您可以在磁盘和服务器内存中节省数百兆字节的存储.

快速计算-使用INTGUID作为主键和聚类键:

  • 包含1‘000’000行的基表(3.8MB与15.26MB)
  • 6个非聚集索引(22.89MB与91.55MB)

TOTAL: 25 MB vs. 106 MB-这只是在一张桌子上!

更多值得深思的东西-金伯利·特里普(Kimberly Tripp)写的精彩文章-读一读,再读一遍,再消化一下!这是SQL Server索引的福音,真的.

除非您有very good reason,否则我认为对于几乎每个"真实"的数据表,都应该使用INT IDENTITY作为其主键的默认值-它是唯一的、稳定的(永远不变)、狭窄的、不断增加的-所有您希望在聚集键中包含的good properties,以实现SQL Server表的快速和可靠的性能!

如果某个"自然"键值也具有所有这些属性,那么也可以使用该键值而不是代理键.但在我看来,two个长度可变的字符串(每个最多20个字符)不符合这些要求.

Database相关问答推荐

如何使用存储在数据库表中的属性配置 Spring bean

在 bindParam 中使用 LIKE 进行 MySQL PDO 查询

仅对表中的一列授予更改

无法使用命令行运行 liquibase

repeating groups是什么意思?

PostgreSQL 是否对只读事务进行了一些性能优化

SQL Server 2008如何同步不同服务器中的数据库?

如何避免使用 LINQ-To-SQL 的内存泄漏?

CouchDB 和 Lotus Notes 有什么区别?

在 SQL 中与 NULL 值连接

Redis: Get key and value on expiration

使用 PDO 获取单行单列

如何从 Django 中的 sql 模式生成数据模型?

如何取消长时间运行的数据库操作?

在哪里可以找到 neo4j 快速教程?

在mysql中 Select 不同的2列组合

Android SQLite 数据库,为什么要删除表并在升级时重新创建

使用 PHP/MySQL 导入 CSV 数据

什么是 ACID 的真实示例?

Cassandra - 事务支持