sql_safe_updates

                                                                                                      sql_safe_updates

1.官方文档

首先我们来看一下官方文档(5.6)对该参数的解释:

sql_safe_updates     Yes Both Yes
##因为sql_safe_updates是SYSTEM VAR,所以我们无法直接在mysql启动命令行和控制文件中添加该参数,只能在等能mysql实例后执行 set global/session sql_safe_updates=1;来设置。

但是我们可以通过init_connect参数来实现在控制文件中设置sql_safe_updates的目的,我们可以在控制文件中添加如下记录(注意init_connect对于有super权限的用户是无效的)

init_connect='SET SQL_SAFE_UPDATES=1'

 sql_safe_updates

If set to 1, MySQL aborts UPDATE or DELETE statements that do not use a key in the WHERE clause or a LIMIT clause. (Specifically, UPDATE statements must have a WHERE clause that uses a key or a LIMIT clause, or both. DELETE statements must have both.) This makes it possible to catch UPDATE or DELETEstatements where keys are not used properly and that would probably change or delete a large number of rows. The default value is 0.

##官方文档上的解释和我实际测试的结果有些出入,还是以实际测试结果为准


2.测试

2.1 测试库版本

mysql> select version();
+------------+
| version()  |
+------------+
| 5.6.26-log |
+------------+

2.2 update及delete测试

2.2.1 测试表结构如下

CREATE TABLE `insure_user_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `order_id` varchar(100) DEFAULT NULL,
  `insure_name` varchar(50) DEFAULT NULL',
  `insure_id_type` varchar(20) DEFAULT NULL,
  `insure_idcard` varchar(50) DEFAULT NULL,
  `insure_birthdate` date DEFAULT NULL,
  `insure_sex` varchar(10) DEFAULT,
  `insure_phone` decimal(20,0) DEFAULT,
  `insure_mail` varchar(100) DEFAULT NULL,
  `insure_province` varchar(100) DEFAULT,
  `insure_city` varchar(100) DEFAULT NULL,
  `insure_address` varchar(100) DEFAULT NULL,
  `invitation_code` varchar(100) DEFAULT NULL,
  `create_time` varchar(100) DEFAULT NULL,
  `is_Policy_send` varchar(10) DEFAULT '不寄送',
  PRIMARY KEY (`id`),
  KEY `idx_orderid` (`order_id`),
  KEY `ind_test_1` (`insure_idcard`,`insure_mail`)
) ENGINE=InnoDB AUTO_INCREMENT=66720 DEFAULT CHARSET=utf8


2.2.2 设置 sql_safe_updates参数为on

set session sql_safe_updates=1;

2.2.3 update测试

mysql> update insure_user_info set insure_name='fei';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
##直接update,不加where条件及limit,update语句执行失败

mysql> update insure_user_info set insure_name='fei' where id<10;
Query OK, 9 rows affected (0.01 sec)
Rows matched: 9  Changed: 9  Warnings: 0
##update 加上where 条件 并且id列为主键,update执行成功

mysql> update insure_user_info set insure_name='fei' limit 10;
Query OK, 10 rows affected (0.00 sec)
Rows matched: 10  Changed: 10  Warnings: 0
##update不加where条件,仅适用limit,update执行成功

mysql> update insure_user_info set insure_name='fei' where create_time <'2015-12-11 16:01:54';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
##update的加where条件,但是create_time列未建索引,update语句执行失败

mysql> update insure_user_info set insure_name='fei' where create_time <'2015-12-11 16:01:54' limit 10;
Query OK, 9 rows affected (0.21 sec)
Rows matched: 9  Changed: 9  Warnings: 0
##update加where条件,create_time列为非索引列,同时使用limit,update语句执行成功

mysql> update insure_user_info set insure_name='fei' where insure_idcard < '110000197609260652';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0
##update 加where子句,where子句中列为组合索引的prefix列,update执行成功

mysql> update insure_user_info set insure_name='fei' where insure_mail < '22@qq.com';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
##update 加where子句,where子句中列为组合索引的非prefix列,update执行失败

2.2.4 delete测试

mysql> delete from insure_user_info;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
##直接delete某张表,不加任何条件,delete语句执行失败

mysql> delete from insure_user_info limit 10;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
##delete 不加where字句,仅使用limit,delete语句失败

mysql> delete from insure_user_info where create_time <'2015-12-11 16:01:54';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
##delete 加where子句,但是where子句中create_time列不是索引列,delete执行失败

mysql> delete from insure_user_info where id <10;
Query OK, 9 rows affected (0.01 sec)
##delete 加where子句,where子句中 id 为主键索引,delete执行成功

mysql> delete from insure_user_info where create_time <'2015-12-11 16:01:54' limit 10;
Query OK, 9 rows affected (0.18 sec)
##delete 加where子句,但是where子句中create_time不是索引列,同时使用limit,delete执行成功

mysql> delete from insure_user_info where id <20 limit 10;
Query OK, 10 rows affected (0.00 sec)
##delete 加where子句,where子句中id列是主键,同时使用limit,delete执行成功

mysql> delete from insure_user_info where insure_idcard <'110000197609260652';
Query OK, 10 rows affected (0.00 sec)
##delete 加where子句,where子句中insure_phone列为组合索引的prefix列,delete执行成功

mysql> delete from insure_user_info where insure_mail<'435065315@163.com';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
##delete 加where子句,where子句中insure_mail为组合索引的非prefix列,delete执行成功

3.总结

3. 总结
如果设置了sql_safe_updates=1,那么update语句必须满足如下条件之一才能执行成功
1)使用where子句,并且where子句中列必须为prefix索引列
2)使用limit
3)同时使用where子句和limit(此时where子句中列可以不是索引列)

delete语句必须满足如下条件之一才能执行成功
1)使用where子句,并且where子句中列必须为prefix索引列
2)同时使用where子句和limit(此时where子句中列可以不是索引列)

NOTE: 所有第三方程序中的sql不受以上所说限制






  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

渔夫数据库笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值