如何在MySQL的SQL语句中避免数据唯一性冲突

如何在MySQL的SQL语句中避免数据唯一性冲突,第1张

本文章来给大家提供三种在mysql中避免重复插入记录方法,主要是讲到了ignore,Replace,ON DUPLICATE KEY UPDATE三种方法,有需要的朋友可以参考一下\x0d\方案一:使用ignore关键字\x0d\\x0d\如果是用主键primary或者唯一索引unique区分了记录的唯一性,避免重复插入记录可以使用:\x0d\\x0d\代码如下:\x0d\ INSERT IGNORE INTO `table_name` (`email`, `phone`, `user_id`) VALUES ('test9@163com', '99999', '9999'); \x0d\ \x0d\这样当有重复记录就会忽略,执行后返回数字0\x0d\\x0d\还有个应用就是复制表,避免重复记录:\x0d\\x0d\代码如下:\x0d\ INSERT IGNORE INTO `table_1` (`name`) SELECT `name` FROM `table_2`; \x0d\ \x0d\方案二:使用Replace\x0d\\x0d\语法格式:\x0d\\x0d\代码如下:\x0d\REPLACE INTO `table_name`(`col_name`, ) VALUES ();\x0d\REPLACE INTO `table_name` (`col_name`, ) SELECT ;\x0d\REPLACE INTO `table_name` SET `col_name`='value', \x0d\\x0d\算法说明:\x0d\REPLACE的运行与INSERT很相像,但是如果旧记录与新记录有相同的值,则在新记录被插入之前,旧记录被删除,即:\x0d\\x0d\尝试把新行插入到表中 \x0d\当因为对于主键或唯一关键字出现重复关键字错误而造成插入失败时: \x0d\从表中删除含有重复关键字值的冲突行 \x0d\再次尝试把新行插入到表中 \x0d\旧记录与新记录有相同的值的判断标准就是:\x0d\表有一个PRIMARY KEY或UNIQUE索引,否则,使用一个REPLACE语句没有意义。该语句会与INSERT相同,因为没有索引被用于确定是否新行复制了其它的行。\x0d\\x0d\返回值:\x0d\REPLACE语句会返回一个数,来指示受影响的行的数目。该数是被删除和被插入的行数的和\x0d\受影响的行数可以容易地确定是否REPLACE只添加了一行,或者是否REPLACE也替换了其它行:检查该数是否为1(添加)或更大(替换)。\x0d\\x0d\示例:\x0d\# eg:(phone字段为唯一索引)\x0d\\x0d\代码如下:\x0d\REPLACE INTO `table_name` (`email`, `phone`, `user_id`) VALUES ('test569', '99999', '123');\x0d\\x0d\另外,在 SQL Server 中可以这样处理:\x0d\\x0d\代码如下:\x0d\if not exists (select phone from t where phone= '1') insert into t(phone, update_time) values('1', getdate()) else update t set update_time = getdate() where phone= '1'\x0d\\x0d\方案三:ON DUPLICATE KEY UPDATE\x0d\\x0d\如‍上所写,你也可以在INSERT INTO后面加上 ON DUPLICATE KEY UPDATE方法来实现。如果您指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则执行旧行UPDATE。\x0d\\x0d\例如,如果列a被定义为UNIQUE,并且包含值1,则以下两个语句具有相同的效果:\x0d\\x0d\代码如下:\x0d\INSERT INTO `table` (`a`, `b`, `c`) VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE `c`=`c`+1; \x0d\UPDATE `table` SET `c`=`c`+1 WHERE `a`=1;\x0d\\x0d\如果行作为新记录被插入,则受影响行的值为1;如果原有的记录被更新,则受影响行的值为2。\x0d\\x0d\注释:如果列b也是唯一列,则INSERT与此UPDATE语句相当:\x0d\\x0d\代码如下:\x0d\UPDATE `table` SET `c`=`c`+1 WHERE `a`=1 OR `b`=2 LIMIT 1;\x0d\\x0d\如果a=1 OR b=2与多个行向匹配,则只有一个行被更新。通常,您应该尽量避免对带有多个唯一关键字的表使用ON DUPLICATE KEY子句。\x0d\\x0d\您可以在UPDATE子句中使用VALUES(col_name)函数从INSERTUPDATE语句的INSERT部分引用列值。换句话说,如果没有发生重复关键字冲突,则UPDATE子句中的VALUES(col_name)可以引用被插入的col_name的值。本函数特别适用于多行插入。VALUES()函数只在INSERTUPDATE语句中有意义,其它时候会返回NULL。\x0d\\x0d\代码如下:\x0d\INSERT INTO `table` (`a`, `b`, `c`) VALUES (1, 2, 3), (4, 5, 6) ON DUPLICATE KEY UPDATE `c`=VALUES(`a`)+VALUES(`b`);\x0d\\x0d\本语句与以下两个语句作用相同:\x0d\\x0d\代码如下:\x0d\INSERT INTO `table` (`a`, `b`, `c`) VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE `c`=3; \x0d\INSERT INTO `table` (`a`, `b`, `c`) VALUES (4, 5, 6) ON DUPLICATE KEY UPDATE c=9;\x0d\\x0d\注释:当您使用ON DUPLICATE KEY UPDATE时,DELAYED选项被忽略。\x0d\\x0d\示例:\x0d\这个例子是我在实际项目中用到的:是将一个表的数据导入到另外一个表中,数据的重复性就得考虑(如下),唯一索引为:email:\x0d\\x0d\代码如下:\x0d\INSERT INTO `table_name1` (`title`, `first_name`, `last_name`, `email`, `phone`, `user_id`, `role_id`, `status`, `campaign_id`) \x0d\ SELECT '', '', '', `table_name2``email`, `table_name2``phone`, NULL, NULL, 'pending', 29 FROM `table_name2` \x0d\ WHERE `table_name2``status` = 1 \x0d\ON DUPLICATE KEY UPDATE `table_name1``status`='pending'\x0d\\x0d\再贴一个例子:\x0d\\x0d\代码如下:\x0d\ INSERT INTO `class` SELECT FROM `class1` ON DUPLICATE KEY UPDATE `class``course`=`class1``course`\x0d\\x0d\其它关键:DELAYED 做为快速插入,并不是很关心失效性,提高插入性能。 \x0d\IGNORE 只关注主键对应记录是不存在,无则添加,有则忽略。\x0d\\x0d\特别说明:在MYSQL中UNIQUE索引将会对null字段失效,也就是说(a字段上建立唯一索引):\x0d\\x0d\代码如下:\x0d\ INSERT INTO `test` (`a`) VALUES (NULL);\x0d\\x0d\是可以重复插入的(联合唯一索引也一样)。

如何处理大量数据并发 *** 作

文件缓存,数据库缓存,优化sql,数据分流,数据库表的横向和纵向划分,优化代码结构!

锁述的概

一 为什么要引入锁

多个用户同时对数据库的并发 *** 作时会带来以下数据不一致的问题:

丢失更新

A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系统

脏读

A用户修改了数据,随后B用户又读出该数据,但A用户因为某些原因取消了对数据的修改,数据恢复原值,此时B得到的数据就与数据库内的数据产生了不一致

不可重复读

A用户读取数据,随后B用户读出该数据并修改,此时A用户再读取数据时发现前后两次的值不一致

并发控制的主要方法是封锁,锁就是在一段时间内禁止用户做某些 *** 作以避免产生数据不一致

二 锁的分类

锁的类别有两种分法:

1 从数据库系统的角度来看:分为独占锁(即排它锁),共享锁和更新锁

MS-SQL Server 使用以下资源锁模式。

锁模式 描述

共享 (S) 用于不更改或不更新数据的 *** 作(只读 *** 作),如 SELECT 语句。

更新 (U) 用于可更新的资源中。防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常见形式的死锁。

排它 (X) 用于数据修改 *** 作,例如 INSERT、UPDATE 或 DELETE。确保不会同时同一资源进行多重更新。

意向锁 用于建立锁的层次结构。意向锁的类型为:意向共享 (IS)、意向排它 (IX) 以及与意向排它共享 (SIX)。

架构锁 在执行依赖于表架构的 *** 作时使用。架构锁的类型为:架构修改 (Sch-M) 和架构稳定性 (Sch-S)。

大容量更新 (BU) 向表中大容量复制数据并指定了 TABLOCK 提示时使用。

共享锁

共享 (S) 锁允许并发事务读取 (SELECT) 一个资源。资源上存在共享 (S) 锁时,任何其它事务都不能修改数据。一旦已经读取数据,便立即释放资源上的共享 (S) 锁,除非将事务隔离级别设置为可重复读或更高级别,或者在事务生存周期内用锁定提示保留共享 (S) 锁。

更新锁

更新 (U) 锁可以防止通常形式的死锁。一般更新模式由一个事务组成,此事务读取记录,获取资源(页或行)的共享 (S) 锁,然后修改行,此 *** 作要求锁转换为排它 (X) 锁。如果两个事务获得了资源上的共享模式锁,然后试图同时更新数据,则一个事务尝试将锁转换为排它 (X) 锁。共享模式到排它锁的转换必须等待一段时间,因为一个事务的排它锁与其它事务的共享模式锁不兼容;发生锁等待。第二个事务试图获取排它 (X) 锁以进行更新。由于两个事务都要转换为排它 (X) 锁,并且每个事务都等待另一个事务释放共享模式锁,因此发生死锁。

若要避免这种潜在的死锁问题,请使用更新 (U) 锁。一次只有一个事务可以获得资源的更新 (U) 锁。如果事务修改资源,则更新 (U) 锁转换为排它 (X) 锁。否则,锁转换为共享锁。

排它锁

排它 (X) 锁可以防止并发事务对资源进行访问。其它事务不能读取或修改排它 (X) 锁锁定的数据。

意向锁

意向锁表示 SQL Server 需要在层次结构中的某些底层资源上获取共享 (S) 锁或排它 (X) 锁。例如,放置在表级的共享意向锁表示事务打算在表中的页或行上放置共享 (S) 锁。在表级设置意向锁可防止另一个事务随后在包含那一页的表上获取排它 (X) 锁。意向锁可以提高性能,因为 SQL Server 仅在表级检查意向锁来确定事务是否可以安全地获取该表上的锁。而无须检查表中的每行或每页上的锁 以确定事务是否可以锁定整个表。

以上就是关于如何在MySQL的SQL语句中避免数据唯一性冲突全部的内容,包括:如何在MySQL的SQL语句中避免数据唯一性冲突、耗时的并发写 *** 作怎么防止数据重复、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/10185043.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-06
下一篇 2023-05-06

发表评论

登录后才能评论

评论列表(0条)

保存