关于SQL主键问题,使用时间和GUID
我在设计一个模块时,由于要考虑以后数据的迁移与保证和别的系统进行数据同步。所以在设计主键时不采用标识列。而采用GUID作为主键,但是感觉GUID作为主键时,太长了,又没规律性,当数据量很大时,按照主键排序就是一个大问题了,并且连聚集索引都起不了啥作用了不是?
针对这些问题,我自己写了个函数,用于生成自己的主键。因为时间具有连续性,所以就用时间加上GUID进行生成,但GUID又太长,所以只截取了前面八位字符,构成新的主键。 方法类似如下:
 SELECT REPLACE(REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(100),GETDATE(),21),'-',''),':',''),'.',''),' ','')+'_'+left(CAST(NEWID() AS VARCHAR(36)),8) 
不知道这样好不好,会有什么问题没,希望有经验的前辈指教,谢谢~
              
------解决方案-------------------- 不要用newid()生成,可以用CREATE TABLE a (a UNIQUEIDENTIFIER)这种来生成,但是我觉得用业务键来做主键比较好
------解决方案-------------------- 用newid生成的,确实是唯一的,但是占36个字节,太长了,
你现在用时间+newid,然后取前8位,也会占用26个字符,也不少,这样倒是有点规律性了,至少前面部分能知道日期和时间,也能达到唯一性。
这样一考虑也算是个折中把,上面说要用UNIQUEIDENTIFIER,也可以达到唯一性,占用16字节,但值是无序,也无意义的值,不太适合你的情况。
------解决方案-------------------- 引用: 而我现在出来的是   20131017115630280_43AD9A64    有26个字符, 聚集索引的物理地址与排序的地址不就一致了?  
你说的没错,因为你前半部分的日期是不断增大的,所以聚集索引和实际排序后,是一致的。
------解决方案-------------------- 生成的UNIQUEIDENTIFIER类型的值好像是无序的哈,返回结果也是无序的
------解决方案-------------------- 其实不是完全无序的
CREATE TABLE myTable (ColumnA uniqueidentifier DEFAULT NEWSEQUENTIALID())  
INSERT INTO myTable DEFAULT VALUES 
GO 10 
 
SELECT * FROM myTable 
 
/* 
ColumnA 
------------------------------------ 
360E7FF1-EF36-E311-BEAB-A41731BD8A1E 
370E7FF1-EF36-E311-BEAB-A41731BD8A1E 
380E7FF1-EF36-E311-BEAB-A41731BD8A1E 
390E7FF1-EF36-E311-BEAB-A41731BD8A1E 
3A0E7FF1-EF36-E311-BEAB-A41731BD8A1E 
3B0E7FF1-EF36-E311-BEAB-A41731BD8A1E 
3C0E7FF1-EF36-E311-BEAB-A41731BD8A1E 
3D0E7FF1-EF36-E311-BEAB-A41731BD8A1E 
3E0E7FF1-EF36-E311-BEAB-A41731BD8A1E 
3F0E7FF1-EF36-E311-BEAB-A41731BD8A1E 
*/ ------解决方案-------------------- 可以吧,这样既保证了聚集索引的整体有序,避免页拆分,又有一定的可读性
------解决方案-------------------- 如果是我,就设计三个字段,GUID太长没关系。
1 自动编号,每台机器各自编号
2 GUID
3 客户端ID,数据来源机器ID
需要注意:
每台机器上的数据的自动编号和顺序是不一致的,
但同一个客户端ID的数据的顺序是一致的。
------解决方案-------------------- 所以我说用业务键会比较合适
------解决方案-------------------- 可能算吧,好像我上一家公司做ERP的,表里面几乎没有用什么自增键,都是用货号+其他什么号来标识,这种复合主键即使去到oracle也合适。并且基本上不存在重复或者冲突的问题
------解决方案-------------------- 建议:
 
1.使用业务数据做主键 
2.每行数据增加guid列,以备数据复制迁移等。 
 
[AdventureWorks2012].[Sales].[SalesOrderHeader] 就有[rowguid]列。
                         好日子,散分,散分.该如何处理