当前位置:文档之家› 关于SQL主键GUID和Identity的看法

关于SQL主键GUID和Identity的看法

据库中使用自增量字段与Guid字段主键的性能对比1.概述:在我们的数据库设计中,数据库的主键是必不可少的,主键的设计对整个数据库的设计影响很大.我就对自动增量字段与Guid字段的性能作一下对比,欢迎大家讨论.2.简介:1.自增量字段自增量字段每次都会按顺序递增,可以保证在一个表里的主键不重复。

除非超出了自增字段类型的最大值并从头递增,但这几乎不可能。

使用自增量字段来做主键是非常简单的,一般只需在建表时声明自增属性即可。

自增量的值都是需要在系统中维护一个全局的数据值,每次插入数据时即对此次值进行增量取值。

当在当量产生唯一标识的并发环境中,每次的增量取值都必须最此全局值加锁解锁以保证增量的唯一性。

这可能是一个并发的瓶颈,会牵扯一些性能问题。

在数据库迁移或者导入数据的时候自增量字段有可能会出现重复,这无疑是一场恶梦(本人已经深受其害).如果要搞分布式数据库的话,这自增量字段就有问题了。

因为,在分布式数据库中,不同数据库的同名的表可能需要进行同步复制。

一个数据库表的自增量值,就很可能与另一数据库相同表的自增量值重复了。

2.uniqueidentifier(Guid)字段在MS Sql 数据库中可以在建立表结构是指定字段类型为uniqueidentifier,并且其默认值可以使用NewID()来生成唯一的Guid(全局唯一标识符).使用NewID生成的比较随机,如果是SQL 2005可以使用NewSequentialid()来顺序生成,在此为了兼顾使用SQL 2000使用了NewID().Guid:指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的,其算法是通过以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字生成。

其格式为:04755396-9A29-4B8C-A38D-00042C1B9028.Guid的优点就是生成的id比较唯一,不管是导出数据还是做分步开发都不会出现问题.然而它生成的id比较长,占用的数据库空间也比较多,随着外存价格的下降,这个也无需考虑.另外Guid不便于记忆,在这方面不如自动增量字段,在作调试程序的时候不太方便。

3.测试:1.测试环境操作系统:windows server 2003 R2 Enterprise Edition Service Pack 2 数据库:MS SQL 2005CPU:Intel(R) Pentium(R) 4 CPU 3.40GHz内存:DDRⅡ667 1G硬盘:WD 80G2.数据库脚本--自增量字段表CREATE TABLE[dbo].[Table_Id]([Id][int]IDENTITY(1,1) NOT NULL,[Value][varchar](50) COLLATE Chinese_PRC_CI_AS NULL,CONSTRAINT[PK_Table_Id]PRIMARY KEY CLUSTERED([Id]ASC)WITH (IGNORE_DUP_KEY =OFF) ON[PRIMARY]) ON[PRIMARY]GO--Guid字段表CREATE TABLE[dbo].[Table_Guid]([Guid][uniqueidentifier]NOT NULL CONSTRAINT[DF_Table_G uid_Guid]DEFAULT (newid()),[Value][varchar](50) COLLATE Chinese_PRC_CI_AS NULL,CONSTRAINT[PK_Table_Guid]PRIMARY KEY CLUSTERED([Guid]ASC)WITH (IGNORE_DUP_KEY =OFF) ON[PRIMARY]) ON[PRIMARY]GO测试代码1using System;2using System.Collections.Generic;3using System.Text;4using System.Data.SqlClient;5using System.Diagnostics;6using System.Data;78namespace GuidTest9{10class Program11 {12string Connnection = "server=.;database=GuidTest;I ntegrated Security=true;";13static void Main(string[] args)14 {15 Program app = new Program();16int Count = 10000;17 Console.WriteLine("数据记录数为{0}",Count);18//自动id增长测试;19 Stopwatch WatchId = new Stopwatch();20 Console.WriteLine("自动增长id测试");21 Console.WriteLine("开始测试");22 WatchId.Start();23 Console.WriteLine("测试中");2425 app.Id_InsertTest(Count);26//app.Id_ReadToTable(Count);27 //app.Id_Count();2829 //查询第300000条记录;30 //app.Id_SelectById();3132 WatchId.Stop();33 Console.WriteLine("时间为{0}毫秒",WatchId.ElapsedMilliseconds);34 Console.WriteLine("测试结束");3536 Console.WriteLine("-----------------------------------------");37//Guid测试;38 Console.WriteLine("Guid测试");39 Stopwatch WatchGuid = new Stopwatch();40 Console.WriteLine("开始测试");41 WatchGuid.Start();42 Console.WriteLine("测试中");4344 app.Guid_InsertTest(Count);45//app.Guid_ReadToTable(Count);46 //app.Guid_Count();4748 //查询第300000条记录;49 //app.Guid_SelectById();5051 WatchGuid.Stop();52 Console.WriteLine("时间为{0}毫秒", WatchGuid.Ela psedMilliseconds);53 Console.WriteLine("测试结束");54 Console.Read();55 }5657///<summary>58///自动增长id测试59///</summary>60private void Id_InsertTest(int count)61 {62string InsertSql="insert into Table_Id ([Valu e]) values ({0})";63using (SqlConnection conn = new SqlConnection(Connnection))64 {65 conn.Open();66 SqlCommand com = new SqlCommand();67for (int i = 0; i < count; i++)68 {69 com.Connection = conn;70 mandText = string.Format(Insert Sql, i);71 com.ExecuteNonQuery();72 }73 }74 }7576///<summary>77///将数据读到Table78///</summary>79private void Id_ReadToTable(int count)80 {81string ReadSql = "select top " + count.ToStrin g() + " * from Table_Id";82using (SqlConnection conn = new SqlConnection (Connnection))83 {84 SqlCommand com = new SqlCommand(ReadSql, c onn);85 SqlDataAdapter adapter = new SqlDataAdapte r(com);86 DataSet ds = new DataSet();87 adapter.Fill(ds);88 Console.WriteLine("数据记录数为:{0}", ds.Tab les[0].Rows.Count);89 }90 }9192///<summary>93///数据记录行数测试94///</summary>95private void Id_Count()96 {97string ReadSql = "select Count(*) from Table_I d";98using (SqlConnection conn = new SqlConnection (Connnection))99 {100 SqlCommand com = new SqlCommand(ReadSql, c onn);101 conn.Open();102object CountResult = com.ExecuteScalar(); 103 conn.Close();104 Console.WriteLine("数据记录数为:{0}",CountRe sult);105 }106 }107108///<summary>109///根据id查询;110///</summary>111private void Id_SelectById()112 {113string ReadSql = "select * from Table_Id wher e Id="+300000;114using (SqlConnection conn = new SqlConnection (Connnection))115 {116 SqlCommand com = new SqlCommand(ReadSql, c onn);117 conn.Open();118object IdResult = com.ExecuteScalar();119 Console.WriteLine("Id为{0}", IdResult);120 conn.Close();121 }122 }123124///<summary>125/// Guid测试;126///</summary>127private void Guid_InsertTest(int count)128 {129string InsertSql = "insert into Table_Guid ([V alue]) values ({0})";130using (SqlConnection conn = new SqlConnection (Connnection))131 {132 conn.Open();133 SqlCommand com = new SqlCommand();134for (int i = 0; i < count; i++)135 {136 com.Connection = conn;137 mandText = string.Format(Insert Sql, i);138 com.ExecuteNonQuery();139 }140 }141 }142143///<summary>144/// Guid格式将数据库读到Table145///</summary>146private void Guid_ReadToTable(int count)147 {148string ReadSql = "select top "+count.ToString()+" * from Table_GuID";149using (SqlConnection conn = new SqlConnection (Connnection))150 {151 SqlCommand com = new SqlCommand(ReadSql, c onn);152 SqlDataAdapter adapter = new SqlDataAdapte r(com);153 DataSet ds = new DataSet();154 adapter.Fill(ds);155 Console.WriteLine("数据记录为:{0}", ds.Table s[0].Rows.Count);156 }157 }158159///<summary>160///数据记录行数测试161///</summary>162private void Guid_Count()163 {164string ReadSql = "select Count(*) from Table_G uid";165using (SqlConnection conn = new SqlConnection (Connnection))166 {167 SqlCommand com = new SqlCommand(ReadSql, c onn);168 conn.Open();169object CountResult = com.ExecuteScalar(); 170 conn.Close();171 Console.WriteLine("数据记录为:{0}", CountRes ult);172 }173 }174175///<summary>176///根据Guid查询;177///</summary>178private void Guid_SelectById()179 {180string ReadSql = "select * from Table_Guid whe re Guid='C1763624-036D-4DB9-A1E4-7E16318C30DE'";181using (SqlConnection conn = new SqlConnection (Connnection))182 {183 SqlCommand com = new SqlCommand(ReadSql, c onn);184 conn.Open();185object IdResult = com.ExecuteScalar(); 186 Console.WriteLine("Guid为{0}", IdResult); 187 conn.Close();188 }189 }190 }191192}1933.数据库的插入测试测试1数据库量为:100条运行结果测试2数据库量为:10000条运行结果测试3数据库量为:100000条运行结果测试4数据库量为:500000条运行结果4.将数据读到DataSet中测试1读取数据量:100运行结果测试2读取数据量:10000 运行结果测试3读取数据量:100000 运行结果测试4读取数据量:500000 运行结果4.记录总数测试测试结果5.指定条件查询测试查询数据库中第300000条记录,数量记录量为610300.4.总结:使用Guid作主键速度并不是很慢,它反而要比使用自动增长型的增量速度还要快.。

相关主题