关于SQL主键问题,使用时间和GUID
我在设计一个模块时,由于要考虑以后数据的迁移与保证和别的系统进行数据同步。所以在设计主键时不采用标识列。而采用GUID作为主键,但是感觉GUID作为主键时,太长了,又没规律性,当数据量很大时,按照主键排序就是一个大问题了,并且连聚集索引都起不了啥作用了不是?
针对这些问题,我自己写了个函数,用于生成自己的主键。因为时间具有连续性,所以就用时间加上GUID进行生成,但GUID又太长,所以只截取了前面八位字符,构成新的主键。 方法类似如下:
SELECT REPLACE(REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(100),GETDATE(),21),'-',''),':',''),'.',''),' ','')+'_'+left(CAST(NEWID() AS VARCHAR(36)),8)
不知道这样好不好,会有什么问题没,希望有经验的前辈指教,谢谢~ sql 经验 主键
[解决办法]
不要用newid()生成,可以用CREATE TABLE a (a UNIQUEIDENTIFIER)这种来生成,但是我觉得用业务键来做主键比较好
[解决办法]
用newid生成的,确实是唯一的,但是占36个字节,太长了,
你现在用时间+newid,然后取前8位,也会占用26个字符,也不少,这样倒是有点规律性了,至少前面部分能知道日期和时间,也能达到唯一性。
这样一考虑也算是个折中把,上面说要用UNIQUEIDENTIFIER,也可以达到唯一性,占用16字节,但值是无序,也无意义的值,不太适合你的情况。
[解决办法]
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
*/
1.使用业务数据做主键
2.每行数据增加guid列,以备数据复制迁移等。
[AdventureWorks2012].[Sales].[SalesOrderHeader] 就有[rowguid]列。