我曾经在许多数据库系统上工作,如果所有数据库密钥都是GUID/UUID值,那么在数据库之间移动条目会变得更容易.我曾经考虑过几次走这条路,但总会有一些不确定性,特别是在性能和未读出电话的URL方面.
有没有人在数据库中广泛使用GUID?通过这种方式我可以获得哪些优势,以及可能存在的陷阱是什么?
有没有办法获得Sql Server 2005+ Sequential Guid生成器的功能,而无需插入记录来回读往返或调用本机win dll调用?我看到有人回答使用rpcrt4.dll,但我不确定是否可以从我的托管环境中进行生产.
编辑:使用@John Boker的答案我试图把它变成GuidComb生成器的更多,而不是依赖于最后生成的Guid而不是重新开始.对于种子,而不是从我使用的Guid.Empty开始
public SequentialGuid()
{
var tempGuid = Guid.NewGuid();
var bytes = tempGuid.ToByteArray();
var time = DateTime.Now;
bytes[3] = (byte) time.Year;
bytes[2] = (byte) time.Month;
bytes[1] = (byte) time.Day;
bytes[0] = (byte) time.Hour;
bytes[5] = (byte) time.Minute;
bytes[4] = (byte) time.Second;
CurrentGuid = new Guid(bytes);
}
Run Code Online (Sandbox Code Playgroud)
我根据评论做了这个
// 3 - the least significant byte in Guid ByteArray
[for SQL Server ORDER BY clause]
// 10 - the most significant byte in Guid ByteArray …Run Code Online (Sandbox Code Playgroud) 我正在考虑将CQS应用于我的ASP.NET MVC网站,但这只是一件非常简单的事情.我不是指CQRS,因为我想为查询和命令部分使用相同的数据源,因此我不需要事件源和其他更复杂的模式.
所以,我的想法是:
我想要实现的主要是:
这有意义吗?
Jimmy Nilsson在这里讨论他的COMB指导概念.这个概念在NHibernate和其他圈子中很受欢迎,因为它比标准GUID具有更高的随机性.
但是,在测试中,情况似乎并非如此.我错过了什么吗?
测试用例:
我有一个名为temp的表(不是临时表,只是一个名为"temp"的表),其中包含585,000行.我有一个名为Codes的新表,并希望将所有585,000个代码值从临时表复制到代码表.我执行的测试SQL是:
set statistics time on;
truncate table codes;
DBCC DBREINDEX ('codes', '', 90);
insert into codes (codeid, codevalue)
select newid(), codevalue from temp
truncate table codes;
DBCC DBREINDEX ('codes', '', 90);
insert into codes (codeid, codevalue)
select CAST(CAST(NEWID() AS BINARY(10)) + CAST(GETDATE() AS BINARY(6)) AS UNIQUEIDENTIFIER), codevalue from temp
Run Code Online (Sandbox Code Playgroud)
标准GUID值的性能:
SQL Server执行时间:CPU时间= 17250 ms,已用时间= 15735 ms.
(受影响的585000行)
COMB GUID值的性能:
SQL Server执行时间:CPU时间= 17500毫秒,已用时间= 16419毫秒.
(受影响的585000行)
我错过了什么?COMB GUID值导致稍长的时间,可能是因为额外的转换.我认为重点是通过使用最后6个字节的日期对GUIDS进行半顺序来减少插入时间,但性能增益似乎不存在.
我们使用Guids作为数据库中实体的主键.传统上,我们遵循一种让INSERT期间数据库为实体设置ID的模式,我认为这主要是因为这通常是你使用自动增量字段或其他方式处理事物的方式.
我发现在对象构建过程中在代码中进行键分配更加方便,主要有两个原因:
有没有令人信服的理由不以这种方式做事?也就是说,当使用Guids作为密钥时,是否有充分的理由将密钥分配保留到数据库中?
编辑: 很多人对Guids是否应该用于PK(我知道)有强烈的意见,但这不是我的问题.
除了集群问题(如果正确设置索引似乎没有问题),我还没有看到避免在应用程序层中创建密钥的令人信服的理由.
考虑到我对Microsoft.NET框架上的顺序guid性能所做的帖子(请参阅Sequential Guid相对于标准Guid的性能改进是什么?)是否有人拥有相同算法的正确,可靠,快速和良好工作的Java实现在Windows DLL中实现?
关心马西莫
我们有一个数据库,其中所有PK都是GUID,大多数PK也是表的聚簇索引.我们知道这很糟糕(由于GUID的随机性).因此,似乎这里基本上有两个选项(完全没有将GUID作为PK扔掉,这是我们做不到的(至少目前不是这样)).
是否有可能在这种情况下提供任何一般性建议?
该应用程序有500多个表,最大的一个目前约150万行,几个表约50万行,其余表显着较低(大多数低于10K).
此外,该应用程序已安装在多个客户站点,因此我们必须考虑现有客户的任何可能的负面影响.
谢谢!
我正试图将我的设计敏感性从LAMP堆栈转移到Microsoft堆栈,我只想到了一些东西 - 我什么时候才能使用GUID?与旧的,可靠的自动递增的int相比,它有什么好处/缺点?
我有一个ASP.NET身份2实现(没有用户数据,只有基表),我有一个类型为UNIQUEIDENTIFIER的userId.
该应用程序首先是代码,我使用的是EF6.
这是DDL:
CREATE TABLE [dbo].[AspNetUsers] (
[Id] UNIQUEIDENTIFIER NOT NULL,
[FirstName] NVARCHAR (MAX) NULL,
[LastName] NVARCHAR (MAX) NULL,
[Email] NVARCHAR (256) NULL,
[EmailConfirmed] BIT NOT NULL,
[PasswordHash] NVARCHAR (MAX) NULL,
[SecurityStamp] NVARCHAR (MAX) NULL,
[PhoneNumber] NVARCHAR (MAX) NULL,
[PhoneNumberConfirmed] BIT NOT NULL,
[TwoFactorEnabled] BIT NOT NULL,
[LockoutEndDateUtc] DATETIME NULL,
[LockoutEnabled] BIT NOT NULL,
[AccessFailedCount] INT NOT NULL,
[UserName] NVARCHAR (256) NOT NULL,
[SubjectId] INT DEFAULT ((0)) NOT NULL,
[SubjectIds] VARCHAR (50) NULL,
[OrganizationId] INT DEFAULT ((0)) NOT NULL,
[OrganizationIds] …Run Code Online (Sandbox Code Playgroud) asp.net asp.net-mvc asp.net-mvc-5 asp.net-identity asp.net-identity-2
guid ×8
c# ×3
database ×2
sql ×2
sql-server ×2
.net ×1
asp.net ×1
asp.net-mvc ×1
command ×1
cqrs ×1
java ×1
linq-to-sql ×1
nhibernate ×1
performance ×1
sequence ×1
sequential ×1
t-sql ×1
uuid ×1