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

发布于 2024-12-06 15:57:46 字数 259 浏览 0 评论 0原文

我需要自动生成帐户名。它们将在访问我的服务的用户软件中使用,因此它们不一定很漂亮。我想任何足够长的字母数字字符串都可以。假设我已经有了一个可以生成足够好的字母数字字符串的算法。

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

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

I need to generate account names automatically. They will be used in user software that will access my service, so they are not necessarily pretty looking. I guess any alphanumeric string long enough will do. Assume I already have an algorithm that produces good enough alphanumeric string.

There're two major requirements: they must be unique and they will be generated concurrently. Specifically my service will run on multiple machines and all copies will access the same shared database. I need to generate those usernames in such way that no two nodes ever generate identical usernames.

How do I do this? Do I just leave this idea and use GUIDs? Is there a prettier way that GUIDs for this scenario?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沫离伤花 2024-12-13 15:57:46

其中之一:

  • 使用 GUID(唯一标识符数据类型),但不作为聚集索引
  • 使用 IDENTITY 列

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

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

所有这些都是并发安全的

One of:

  • Use GUIDs (uniqueidentifier data type) but not as a clustered index
  • Use an IDENTITY column

If SQL Server replication is used over multiple nodes (Edit: was thinking too much before)

  • Use IDENTITY columns with ranges set per node (eg -1 to -1000000, 1 to 100000 etc)
  • IDENTITY column and a NodeID column to separate the IDENTITY values

All are concurrency safe

烧了回忆取暖 2024-12-13 15:57:46
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)

如果您想测试此代码的并发问题,您可以运行 UPDATE ...; GO 100000更新...; GO 100 在 SSMS 中的两个单独的窗口/查询中,最后,您可以运行此查询 SELECT UserName, COUNT(*) Num FROM dbo.[User] ORDER BY COUNT(*) DESC< /code> 看看是否可以找到重复项。

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];

Sample output:

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)

If you want to test this code for concurrency issues you can run UPDATE ...; GO 100000 and UPDATE ...; GO 100 in SSMS in two separated windows/queries and, at the end, you can run this query SELECT UserName, COUNT(*) Num FROM dbo.[User] ORDER BY COUNT(*) DESC to see if you can find duplicates.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文