数据库自增字段解决方案

本文详细介绍了Oracle、MySQL、SQL Server和DB2中实现自增字段的方法。在Oracle中使用序列,MySQL通过auto_increment,SQL Server依赖identity,DB2支持identity和sequence。同时讨论了各数据库中自增字段的特性、限制以及如何在Hibernate中使用这些机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Oracle
序列:是Oracle提供的用于产生一系列唯一数字的数据库对象。
其作用在于:1、自动提供唯一的数值;2、共享对象;3、主要用于提供主键值
在Oracle数据库中创建序列需要一定的权限 create sequence 或 create any sequence
创建语法:
CREATE SEQUENCE sequence - 序列名称
【INCREMENT BY n】- 步长,如果n是正数则递增,如果n是负数则递减,n默认值是1
【START WITH n】 - 开始的值,递增默认是minvalue,递减默认是maxvalue
【{MAXVALUE n | NOMAXVALUE}】 - 最大值
【{MINVALUE n | NOMINVALUE}】 - 最小值
【{CYCLE | NOCYCLE}】 - 循环/不循环
【{CACHE n | NOCACHE}】 - 分配并存入内存中(一般不存入内存),默认缓存20

NEXTVAL 返回序列中下一个有效的值,任何用户都可以引用
CURRVAL 序列当前值
NEXTVAL应在CURRVAL之前指定,二者应同时有效

序列在下列情况下会出现裂缝:1、回滚;2、系统异常
修改序列:
语法与创建一致,将CREATE更换为ALTER
修改序列的注意事项:
1、必须是序列的拥有者或者对序列具有ALTER权限才能进行修改
2、只有将来的序列值会被改变,对已有的序列值不会影响
3、改变序列的初始值只能通过删除序列之后重建序列的方法实现
删除序列:使用DROP SEQUENCE语句删除

在hibernate中可以使用 seqhilo和sequence两种形式实现使用序列生成ID,需要先在数据库中创建sequence才行。

MySQL
MySQL自增列使用auto_increment标识字段达到自增,在创建表时将某一列定义为auto_increment,则该列为自增列。
指定了auto_increment的列必须要建立索引
AUTO_INCREMENT说明:
1、如果把一个NULL插入到一个AUTO_INCREMENT数据列里去,MySQL将自动生成下一个序列编号。编号从1开始,并1为基数递增。
2、把0插入AUTO_INCREMENT数据列的效果与插入NULL值一样。但不建议这样做。
3、当插入记录时,没有为AUTO_INCREMENT明确指定值,则等同插入NULL值。
4、当插入记录时,如果为AUTO_INCREMENT数据列明确指定了一个数值,则会出现两种情况,情况一,如果插入的值与已有的编号重复,则会出现出错信息,因为AUTO_INCREMENT数据列的值必须是唯一的;情况二,如果插入的值大于已编号的值,则会把该插入到数据列中,并使在下一个编号将从这个新值开始递增。也就是说,可以跳过一些编号。
5、对于MyISAM表,如果用UPDATE命令更新自增列,如果列值与已有的值重复,则会出错。如果大于已有值,则下一个编号从该值开始递增。但是对于innodb表,update auto_increment字段,会导致发生报错。

可用alter table table_name AUTO_INCREMENT=n命令来重设自增的起始值。但是如果设置的起始值比目前的数值小的话,执行SQL不会报错,但不会生效。

auto_increment_increment 和 auto_increment_offset属性可以控制自增列auto_increment的行为,用于master-master之间的复制,防止出现重复值。
auto_increment_increment:自增值的自增量,即步长
auto_increment_offset:自增值的偏移量,即起始值

两个变量均可以设置为全局或局部变量,并且假定每个值都可以为1到65,535之间的整数值。将其中一个变量设置为0会使该变量为1。如果试图将这些变量设置为大于65,535或小于0的值,则会将该值设置为65,535。如果向将auto_increment_increment或auto_increment_offset设置为非整数值,则会给出错误,并且变量的实际值在这种情况下保持不变。

设置了这两个值后自增字段值限定为:auto_increment_offset + auto_increment_increment*N但上限还是受字段类型限制

在hibernate中可以使用identity实现ID自增

SQL Server
在SQL server中,对于ID自增采用的是identity的方式,通过在某一列上设置identity属性实现自增。
CREATE TABLE dbo.Identity_test  (      
       ID INT IDENTITY(1,1),  --从1开始,每次增加1
       Content NVARCHAR(200)  
)

一张表最多只能有一个自增列,且表中的自增列一旦创建就不能更改起始值和自增值了,只能更改当前值。如果要修改只能先删除再重建。

如果设置了自增列,则不能插入自增列的数据,否则会出错。

在必要的時候,可以用DBCC CHECKIDENT命令來重置表中自增列的當前ID值。
如 DBCC CHECKIDENT('dbo.Identity_test', RESEED, 10) --重置自增列为10,下次从11开始

在hibernate中可以使用identity实现ID自增

DB2
DB2提供两种方式实现列的自增:
定义identity标识列的方式
创建sequence序列对象

identity
在DB2中提供了两种标识列值
--GENERATED ALWAYS AS IDENTITY (start with n, increment by m)
--GENERATED BY DEFAULT AS IDENTITY (start with n, increment by m)
两者间的区别在于always方式的值由DB2生成,不允许用户直接赋值,而by default方式则允许用户直接赋值。两种方式都不能保证生成的值唯一,如果要保证唯一性必须对该列做唯一性索引。

标识列生成的顺序数字具有下列附加属性:
--值可以是任何小数位为零的精确数字数据类型;即,小数位为零的 SMALLINT、INTEGER、BIGINT 或 DECIMAL。(单精度和双精度浮点类型被认为是近似数字数据类型。)
--连续值之间可以有任何指定的整数增量。缺省增量是 1。
--标识列的计数器值是可恢复的。若发生故障,则从日志重新构造计数器值,因此可以保证继续生成唯一的值。
--可以将标识列值存入高速缓存,以获得更好的性能。

标识列具有下列特征:
--仅当创建了表时,才可以将标识列定义为表的一部分。一旦创建了表,就不能改变它来添加一个标识列。(然而,可以改变现有的标识列特征)
--标识列自动为单个表生成值。
--当将标识列定义为 GENERATED ALWAYS 时,始终由数据库管理器生成所用的值。在修改表的内容期间,不允许应用程序来提供它们自己的值。

sequence序列

创建语法:
CREATE SEQUENCE sequence - 序列名称
AS INTEGER - 数据类型
【START WITH n】 - 起始值
【INCREMENT BY n】- 步长
【{MAXVALUE n | NO MAXVALUE}】 - 最大值
【{MINVALUE n | NO MINVALUE}】 - 最小值
【{CYCLE | NO CYCLE}】 - 循环/不循环
【{CACHE n | NO CACHE}】 - 分配并存入内存中(一般不存入内存),默认缓存20
创建语法与Oracle的创建基本一致,不同在于DB2设定了数据类型

序列对象具有下列特征:
--序列对象是未与任何一个表关联的数据库对象。
--序列对象生成可在任何 SQL 或 XQuery 语句中使用的顺序值。
--由于任何应用程序可以使用序列对象,所以有两种表达式可用来控制如何检索指定序列中的下一个值和在正在执行的语句之前生成的值。对于当前会话中的先前语句,PREVIOUS VALUE
表达式对指定序列返回最新生成的值。NEXT VALUE 表达式对指定序列返回下一个值。使用这些表达式允许在几个表内的几个 SQL 和 XQuery 语句中使用相同值。

在hibernate中由于DB2支持identity及sequence两种方式的自增,所以使用两种的其中一种都可以实现自增。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值