如何同时在共享数据库上生成唯一的用户名?

时间:2011-09-26 11:19:43

标签: sql-server database concurrency uniqueidentifier identifier

我需要自动生成帐户名称。它们将用于将访问我的服务的用户软件,因此它们不一定非常漂亮。我想任何字母数字字符串都足够长。假设我已经有一个能够产生足够好的字母数字字符串的算法。

有两个主要要求:它们必须是唯一的,并且它们将同时生成。具体来说,我的服务将在多台计算机上运行,​​所有副本将访问同一个共享数据库。我需要生成这些用户名,使得没有两个节点生成相同的用户名。

我该怎么做?我是否只是留下这个想法并使用GUID?对于这种情况,GUID是否有更漂亮的方式?

2 个答案:

答案 0 :(得分:2)

其中一个:

  • 使用GUID(uniqueidentifier数据类型)但不作为聚簇索引
  • 使用IDENTITY列

如果在多个节点上使用SQL Server复制(编辑:以前想的太多)

  • 使用IDENTITY列,每个节点设置范围(例如-1到-1000000,1到100000等)
  • IDENTITY列和NodeID列,用于分隔IDENTITY值

所有都是并发安全的

答案 1 :(得分:0)

CREATE TABLE dbo.CommonName
(
    CommonNameID INT IDENTITY(0,1) PRIMARY KEY
    ,Name NVARCHAR(50) NOT NULL
    ,LastID INT NOT NULL DEFAULT 0
);
INSERT  dbo.CommonName(Name)
VALUES  
 ('JAMES')  
,('JOHN')   
,('ROBERT') 
,('MICHAEL')    
,('WILLIAM')    
,('DAVID')  
,('RICHARD')    
,('CHARLES')    
,('JOSEPH') 
,('THOMAS');
GO

--Test
CREATE TABLE [User](Id INT IDENTITY(1,1) PRIMARY KEY, UserName NVARCHAR(60));
GO

UPDATE  dbo.CommonName WITH(ROWLOCK)
SET     
        LastID = LastID + 1
OUTPUT  inserted.Name+CAST(inserted.LastID AS NVARCHAR(10)) INTO [User](UserName)
WHERE   CommonNameID = ABS(CHECKSUM(NEWID())) % 10
GO 20 --We need 20 new users

SELECT  *
FROM    [User] u
ORDER BY u.Id;
--End of test
GO

DROP TABLE dbo.CommonName;
DROP TABLE dbo.[User];

示例输出:

Batch execution completed 20 times.
Id          UserName
----------- ------------------------------------------------------------
1           RICHARD1
2           MICHAEL1
3           ROBERT1
4           WILLIAM1
5           ROBERT2
6           JAMES1
7           CHARLES1
8           RICHARD2
9           JOSEPH1
10          THOMAS1
11          ROBERT3
12          MICHAEL2
13          WILLIAM2
14          MICHAEL3
15          THOMAS2
16          THOMAS3
17          WILLIAM3
18          RICHARD3
19          JAMES2
20          RICHARD4

(20 row(s) affected)

如果要测试此代码是否存在并发问题,可以在两个独立的窗口/查询中在SSMS中运行UPDATE ...; GO 100000UPDATE ...; GO 100,最后,您可以运行此查询{{1}查看是否可以找到重复项。