mysql数据库insert插入重复问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql数据库insert插入重复问题相关的知识,希望对你有一定的参考价值。

要求:
ID不能递增。
点击保存按钮从数据库中取出目前最大数据 加1。如目前是A1033 下一个是A1034。
怎么保证多处同时点击保存ID不重复。。
不能使用锁表。
界面端需要返回这个ID。
需要在界面端知道这个ID. 保证不能主键冲突。
不能用触发器
----------------------------
这是排队机程序。
多种业务分A,B,C,D,每天计数从A001,B001,开始,现在是锁表解决唯一性,先锁表接着查出最大值再加1然后再解锁,但是锁表后并发高了会报错。
有多个取票端,所以在程序中递增是不可能的。
因为要接着打印出票号,需要在插入数据库前就得有这个票号,所以不能用id递增。
有多种票号类型都是不同的,数据都在一个表里,再次否决id递增。

这就是自己实现一个ID自增的东西。
比如的你有个公用类专门用来生成后面的数字,所有需要用到的方法都调用这个类的一个方法我们就叫它nextId吧,只要这个方法是线程安全的就可以了。
IdUtils.nextId()

int nextId()
lock(this)
return this.id++;



应用启动的时候从数据库查询一下id的最大值并设置给工具类的id,让它接着增长就行了。
具体实现看你用什么语言。

请仔细阅读别人回答的是什么意思。想想oracle的sequence的实现,是不是类似?追问

1、应用启动的时候从数据库查询一下id的最大值并设置给工具类的id,让它接着增长就行了。
这个方法单一客户端是完全解决,但是客户端是多个的。
2、用的是mysql 他没有sequence,就算有,里面的字段都是灵活配置的,每个类型都必须每天从一开始计数根据英文字母A,B,C,D进行类别区分。
A001 ,A002
B001,B002
C001 这种类型。

追答

    客户端多个的话你是让客户端带着这个(A001或者B001)标示来统一个数据库存储吗?

    如果是多种类型,那相当于你有多个工具类(这时候应该叫ID生成类)的是实例,设置初始值的时候去数据库里面查找对应类的最大值并设置。

    不知道我理解有没有问题。

参考技术A --自增ID 格式:yyyyMMdd***
--===================================================
--存储过程
CREATE PROCEDURE get_new_id
@NEW_ID VARCHAR(16) OUTPUT
AS
BEGIN
DECLARE @DATE DATETIME
DECLARE @YYYY VARCHAR(4)
DECLARE @MM VARCHAR(2)
DECLARE @DD VARCHAR(2)
--保存取得的当前时间
SET @DATE = GETDATE()
SET @YYYY = DATEPART(yyyy, @DATE)
SET @MM = DATEPART(mm, @DATE)
SET @DD = DATEPART(dd, @DATE)
--位数不够的前面补0
SET @YYYY = REPLICATE('0', 4 - LEN(@YYYY)) + @YYYY
SET @MM = REPLICATE('0', 2 - LEN(@MM)) + @MM
SET @DD = REPLICATE('0', 2 - LEN(@DD)) + @DD
--取出表中当前日期的已有的最大ID
SET @NEW_ID = NULL
SELECT TOP 1 @NEW_ID = [字段名] FROM [表名] WHERE [字段名] LIKE @YYYY+@MM+@DD+'%' ORDER BY [字段名] DESC
--如果未取出来
IF @NEW_ID IS NULL
--说明还没有当前日期的编号,则直接从1开始编号
SET @NEW_ID = (@YYYY+@MM+@DD+'001')
--如果取出来了
ELSE
BEGIN
DECLARE @NUM VARCHAR(3)
--取出最大的编号加上1
SET @NUM = CONVERT(VARCHAR, (CONVERT(INT, RIGHT(@NEW_ID, 3)) + 1))
--因为经过类型转换,丢失了高位的0,需要补上
SET @NUM = REPLICATE('0', 3 - LEN(@NUM)) + @NUM
--最后返回日期加编号
SET @NEW_ID = @YYYY+@MM+@DD + @NUM
END
END
GO
===================================================
--触发器
CREATE trigger [dbo].[触发器名] on [dbo].[表名]
instead of insert
AS
SET NOCOUNT ON ;
begin
declare @id varchar(16)
select * into # from inserted
EXECUTE get_new_id @id OUTPUT
update # set 字段名 = @id
insert 表名 select * from #
end
参考技术B 用触发器来实现每次新增数据都加1,每次添加时用触发器来生成id值 参考技术C 没具体明白你什么意思,
如果只是不想叫他重复,直接加个主键不就可以了,,,,

以上是关于mysql数据库insert插入重复问题的主要内容,如果未能解决你的问题,请参考以下文章

mysql数据库insert插入重复问题

MySQL 语句级避免重复插入—— Insert Select Not Exist

mysql 重复插入主键不报错方法

MySQL - 忽略插入错误:重复条目

mysql insert foreach 大数据量 重复

如何忽略MySQL中insert语句的连续重复