在数据库中使用数字ID作为主键的表生成主键方法

    在数据库开发中,很多时候建一个表的时候会使用一个数字类型来作为主键,使用自增长类型自然会更方便,只是本人从来不喜欢有内容不在自己掌控之中,况且自增长类型在进行数据库复制时会比较麻烦。所以本人一直使用自己生成最大数字来保存主键。只是多任务同时写入数据库时,就偶尔会有主键冲突的情况出现了。因为得到最大数值时的查询语句如果同时进行就会出现相同的数字ID了。考虑到如果进行锁表的代价比较大,所以经过考虑,还是在一个表中保存最大ID这种速度快并且锁定的代价很小。本人使用SqlServer2008R2数据库,首先建立保存数字ID的表,如下所示,可以保存多个表的ID。字段分别代表表名、当前可用ID、ID对应字段名。

1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE [dbo].[TableKey](
    [TableName] [varchar](50) NOT NULL,
    [TableKeyID] [numeric](18, 0) NOT NULL,
    [KeyFieldName] [varchar](50) NOT NULL,
 CONSTRAINT [PK_TableKey] PRIMARY KEY CLUSTERED
(
    [TableName] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
 
GO

建立表之后,使用一个存储过程来取回某个表当前可用的最大ID号,并把ID号增长后保存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
CREATE PROCEDURE [dbo].[SP_GetNewID]
    @TableName varchar(50)
AS
BEGIN
 
    SET NOCOUNT ON;
     
    DECLARE @NextTKey BIGINT
     
    BEGIN TRAN TransID
     
    -- 得到最新ID,采用更新锁,并保持到事务完成
    SELECT @NextTKey = TableKeyID + 1 FROM TableKey WITH (UPDLOCK) WHERE TableName = @TableName
    IF @@ROWCOUNT = 0  
    BEGIN
        SET @NextTKey = 1
        INSERT INTO TableKey (TableName, TableKeyID) VALUES (@TableName, @NextTKey)
    END
    ELSE
    BEGIN
        -- 更新新的ID
        UPDATE TableKey SET TableKeyID = @NextTKey WHERE TableName = @TableName
    END
     
    COMMIT TRAN TransID
     
    RETURN @NextTKey
END
 
GO

使用这种方法后,得到最大ID应该就很少会出问题了。

 

posted @   蓝马  阅读(1848)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· .NET 进程 stackoverflow异常后,还可以接收 TCP 连接请求吗?
· SQL Server统计信息更新会被阻塞或引起会话阻塞吗?
阅读排行:
· 传国玉玺易主,ai.com竟然跳转到国产AI
· 本地部署 DeepSeek:小白也能轻松搞定!
· 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)
· 我们是如何解决abp身上的几个痛点
· 普通人也能轻松掌握的20个DeepSeek高频提示词(2025版)
点击右上角即可分享
微信分享提示