社区
疑难问题
帖子详情
在高并发的系统怎样获取一个全局唯一的编号?
zzxap
2009-05-22 04:59:47
我有一个界面同事保存数据到两个表,一个父表一个子表。
父子表的编号要唯一和对应。
其它用户也要获取一个流水号,用于新增数据。
怎样在高并发的时候获取到全局唯一的编号?
select max(id) 会取到同一个编号
...全文
304
16
打赏
收藏
在高并发的系统怎样获取一个全局唯一的编号?
我有一个界面同事保存数据到两个表,一个父表一个子表。 父子表的编号要唯一和对应。 其它用户也要获取一个流水号,用于新增数据。 怎样在高并发的时候获取到全局唯一的编号? select max(id) 会取到同一个编号
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
16 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
饮水需思源
2009-05-23
打赏
举报
回复
用一张单据最大单号表来存放每一种单据的最大编号,每次保存时从此表中读取并加1作为本次保存的最大号,保存成功后再将本次保存的最大编号回写到此表,当然保存时要用事务来处理
hery2002
2009-05-23
打赏
举报
回复
使用数据库事务,隔离事务级别.在数据写入时直接在数据库端操作,
在从系统中抓取一个最大值处理,同时使用存储过程来完成。
Q832198
2009-05-23
打赏
举报
回复
[Quote=引用 13 楼 sparklerl 的回复:]
用GUID号来[/Quote] 这个不错 考虑一下.
sparklerl
2009-05-22
打赏
举报
回复
用GUID号来
jiangshun
2009-05-22
打赏
举报
回复
[Quote=引用 9 楼 zzxap 的回复:]
除了设置递增列和用@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT
有没有其他方法获取一个唯一编号呢?
[/Quote]
以添加数据的时间来生成一个编号?
JonasFeng
2009-05-22
打赏
举报
回复
我现在的项目就是一个界面 父表和子表一同保存的。
也没见有什么问题呀。
只是要在保存的时候判断,系统中该信编号是否存在,如果存在,系统自动取最新的编号。
存储过程用事务,用@@IDENTITY就可以了。这样不会有什么问题的。
zzxap
2009-05-22
打赏
举报
回复
[code=SQL]
@@IDENTITY
返回最后插入的标识值。
语法
@@IDENTITY
返回类型
numeric
注释
在一条 INSERT、SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含此语句产生的最后的标识值。若此语句没有影响任何有标识列的表,则 @@IDENTITY 返回 NULL。若插入了多个行,则会产生多个标识值,@@IDENTITY 返回最后产生的标识值。如果此语句激发一个或多个执行产生标识值的插入操作的触发器,则语句执行后立即调用 @@IDENTITY 将返回由触发器产生的最后的标识值。若 INSERT 或 SELECT INTO 语句失败或大容量复制失败,或事务被回滚,则 @@IDENTITY 值不会还原为以前的设置。
在返回插入到表的 @@IDENTITY 列的最后一个值方面,@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 函数类似。
@@IDENTITY 和 SCOPE_IDENTITY 将返回在当前会话的所有表中生成的最后一个标识值。但是,SCOPE_IDENTITY 只在当前作用域内返回值,而 @@IDENTITY 不限于特定的作用域。
IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回任何会话和任何作用域中为特定表生成的标识值。有关更多信息,请参见 IDENT_CURRENT。
---------------------------------------------------------------
我总结的3种返回最大标识值的方法的不同点:
IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值。
@@IDENTITY 返回为当前会话的所有作用域中的任何表最后生成的标识值。
SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值。(防止返回触发器中的insert的IDENTITY值)
---------------------------------------------------------------
@@IDENTITY
返回最后插入的标识值。
语法
@@IDENTITY
返回类型
numeric
注释
在一条 INSERT、SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含此语句产生的最后的标识值。若此语句没有影响任何有标识列的表,则 @@IDENTITY 返回 NULL。若插入了多个行,则会产生多个标识值,@@IDENTITY 返回最后产生的标识值。如果此语句激发一个或多个执行产生标识值的插入操作的触发器,则语句执行后立即调用 @@IDENTITY 将返回由触发器产生的最后的标识值。若 INSERT 或 SELECT INTO 语句失败或大容量复制失败,或事务被回滚,则 @@IDENTITY 值不会还原为以前的设置。
在返回插入到表的 @@IDENTITY 列的最后一个值方面,@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 函数类似。
@@IDENTITY 和 SCOPE_IDENTITY 将返回在当前会话的所有表中生成的最后一个标识值。但是,SCOPE_IDENTITY 只在当前作用域内返回值,而 @@IDENTITY 不限于特定的作用域。
IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回任何会话和任何作用域中为特定表生成的标识值。有关更多信息,请参见 IDENT_CURRENT。
示例
下面的示例向带有标识列的表中插入一行,并用 @@IDENTITY 显示在新行中使用的标识值。
INSERT INTO jobs (job_desc,min_lvl,max_lvl)
VALUES ('Accountant',12,125)
SELECT @@IDENTITY AS 'Identity'
SQL Server 2000中,有三个比较类似的功能:他们分别是:SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY,它们都返回插入到 IDENTITY 列中的值。
IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值。IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。
@@IDENTITY 返回为当前会话的所有作用域中的任何表最后生成的标识值。
SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值
SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。
例如,有两个表 T1 和 T2,在 T1 上定义了一个 INSERT 触发器。当将某行插入 T1 时,触发器被激发,并在 T2 中插入一行。此例说明了两个作用域:一个是在 T1 上的插入,另一个是作为触发器的结果在 T2 上的插入。
假设 T1 和 T2 都有 IDENTITY 列,@@IDENTITY 和 SCOPE_IDENTITY 将在 T1 上的 INSERT 语句的最后返回不同的值。
@@IDENTITY 返回插入到当前会话中任何作用域内的最后一个 IDENTITY 列值,该值是插入 T2 中的值。
SCOPE_IDENTITY() 返回插入 T1 中的 IDENTITY 值,该值是发生在相同作用域中的最后一个 INSERT。如果在作用域中发生插入语句到标识列之前唤醒调用 SCOPE_IDENTITY() 函数,则该函数将返回 NULL 值。
而IDENT_CURRENT('T1') 和 IDENT_CURRENT('T2') 返回的值分别是这两个表最后自增的值。
ajqc的实验:(40条本地线程,40+40条远程线程同时并发测试,插入1200W行),得出的结论是:
1.在典型的级联应用中.不能用@@IDENTITY,在CII850,256M SD的机器上1W多行时就会并发冲突.在P42.8C,512M DDR上,才6000多行时就并发冲突.
2.SCOPE_IDENTITY()是绝对可靠的,可以用在存储过程中,连触发器也不用建,没并发冲突
[/CODE]
zzxap
2009-05-22
打赏
举报
回复
除了设置递增列和用@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT
有没有其他方法获取一个唯一编号呢?
zzxap
2009-05-22
打赏
举报
回复
insert into t1(name,sex) values (1,2)
select SCOPE_IDENTITY() as aa
zzxap
2009-05-22
打赏
举报
回复
没有设置递增列,sorry
zzxap
2009-05-22
打赏
举报
回复
insert into t1(id,name) values (1,2)
select @@IDENTITY from t1
为什么得到一列null
sdhdy
2009-05-22
打赏
举报
回复
楼主可以参考一下这个:
http://blog.csdn.net/sdhdy/archive/2009/04/26/4126265.aspx
--小F--
2009-05-22
打赏
举报
回复
@@IDENTITY
昵称被占用了
2009-05-22
打赏
举报
回复
自增字段,插入父表自动保持唯一,插入后用SCOPE_IDENTITY 函数取出刚刚插入的号,用来插入子表,就保证一致了
jiangshun
2009-05-22
打赏
举报
回复
@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 函数
jiangshun
2009-05-22
打赏
举报
回复
@@IDENTITY
Springboot
唯一
编号
整合,vesta
全局
唯一
id生成器
适用于Java分布式
高并发
的
全局
唯一
ID生成器;结合Springboot和SpringCloud
如何在
高并发
分布式
系统
中生成
全局
唯一
Id
博文示例: 1. GUID生成Int64值后是否还具有
唯一
性测试 2. Random生成高
唯一
性随机码 今天分享的主题是:如何在
高并发
分布式
系统
中生成
全局
唯一
Id。 但这篇博文实际上是“半分享半讨论”的博文: 1) 半分享是我将说下我所了解到的关于今天主题所涉及的几种方案。 2) 半讨论是我希望大家对各个方案
集群
高并发
情况下如何保证分布式
唯一
全局
ID生成?
高可用、低延迟、高QPS 第一种:mysql数据库实现。不太适合 在分布式里面,数据库的自增ID机制的主要原理是:数据库自增ID和mysql数据库的replace into实现的。 这里的repalace into 跟insert功能类似, 不同点在于:replae into 首先尝试插入数据列表中,如果发现表中已经有此行数据(根据主键或者
唯一
索引判断)则先删除,在插入。否则直接插入新数据。这样就保证了每次生成的ID是递增
唯一
的。 测试用例: 不适合使用: 高可用:集群复杂,维护起来复杂难
集群、分布式
高并发
的情况下如何生成
全局
唯一
ID
集群
高并发
的情况下如何生成
全局
唯一
ID 1,ID生成规则的硬性要求:
全局
唯一
趋势递增 单调递增 信息安全 含时间戳 2,ID生成
系统
的可用性要求: 高可用 低延迟 高QPS:10万个的请求同时过来。 3,生成
全局
唯一
ID的主要方案: 中间件方式:可以通过数据库或 redis 缓存作为媒介,通过数据库生成自增ID来作为
唯一
ID。数据库的自增ID机制的原理是:数据库自增ID的mysql 的 repalce into 实现的(没有新增有则替换,字段创建
唯一
索引),缺点:
系统
水平扩展困难,依赖中间件
高并发
系统
设计八-发号器-如何保证分库分表后ID的
全局
唯一
性
1、分库分表后带来的问题 查询的时候必须带着分区键字段
一个
聚合类查询性能比较差,需要考虑使用计数器等其他的解决方案 主键的
全局
唯一
性问题 2、数据库中的主键要如何选择 数据库中的每一条记录都需要有
一个
唯一
的标识,依据数据库的第二范式,数据库中每
一个
表中都需要有
一个
唯一
的主键,其他数据元素和主键一一对应。 使用业务字段作为主键 比如用户表中使用手机号码,email或者身份证号码作为主键...
疑难问题
22,298
社区成员
121,733
社区内容
发帖
与我相关
我的任务
疑难问题
MS-SQL Server 疑难问题
复制链接
扫一扫
分享
社区描述
MS-SQL Server 疑难问题
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章