MySQL sql_safe_updates参数详解

 更新时间:2024年07月11日 11:18:02   作者:zxrhhm  
sql_safe_updates 是 MySQL 中的一个系统变量,用于控制 MySQL 服务器是否允许在没有使用 KEY 或 LIMIT 子句的 UPDATE 或 DELETE 语句上执行更新或删除操作,这篇文章主要介绍了MySQL sql_safe_updates参数,需要的朋友可以参考下

sql_safe_updates 是 MySQL 中的一个系统变量,用于控制 MySQL 服务器是否允许在没有使用 KEY 或 LIMIT 子句的 UPDATE 或 DELETE 语句上执行更新或删除操作。当这个变量被设置为 ON 时,MySQL 会拒绝那些可能影响到表中大量行的 UPDATE 或 DELETE 语句,除非这些语句明确使用了 WHERE 子句中的 KEY(如主键或唯一索引)或者 LIMIT 子句来限制影响的行数。

这样做的目的是为了防止由于疏忽或错误编写的 SQL 语句而导致大量数据的意外丢失或修改。

如何设置 sql_safe_updates

你可以通过几种方式设置 sql_safe_updates:

全局级别:

你可以通过修改 MySQL 的配置文件(如 my.cnf 或 my.ini,取决于你的操作系统和 MySQL 版本)来永久设置这个变量。但是,请注意,直接在配置文件中设置 sql_safe_updates 可能不被所有 MySQL 版本支持,或者可能需要以不同的方式配置(如通过插件或其他系统变量)。
一种更常见的方法是使用 MySQL 的 SET GLOBAL 语句在运行时设置它,但这只会影响新的连接。例如:

SET GLOBAL sql_safe_updates = 1;

但是,请注意,直接设置全局变量可能需要管理员权限,并且这个更改不会影响已经存在的会话。

会话级别:

你可以通过在你的 MySQL 会话中执行以下 SQL 语句来设置 sql_safe_updates:

SET SESSION sql_safe_updates = 1;
或者登录时加上--safe-updates 
mysql -uroot -p --safe-updates 

这会影响当前会话中的后续操作,但不会影响到其他会话或全局设置。

注意事项

在启用 sql_safe_updates 后,如果你尝试执行一个没有 KEY 或 LIMIT 的 UPDATE 或 DELETE 语句,MySQL 将拒绝该操作并返回错误。

(root@localhost)[superdb]> show index from dept;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| dept  |          0 | PRIMARY  |            1 | deptno      | A         |           4 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
1 row in set (0.13 sec)
(root@localhost)[superdb]> update dept set loc='sz';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. 
  • 并非所有 MySQL 部署都会默认启用 sql_safe_updates。它通常是由数据库管理员或开发者根据特定的安全要求来配置的。
  • 在某些情况下,你可能需要临时禁用 sql_safe_updates 以执行特定的批量更新或删除操作。在这种情况下,你可以在会话级别设置 sql_safe_updates = 0,但请务必小心,确保你的 SQL 语句是安全的,不会意外地影响大量数据。

总之,sql_safe_updates 是一个有用的安全特性,可以帮助防止由于疏忽或错误导致的数据丢失。然而,它也要求开发者和数据库管理员更加注意他们的 SQL 语句,以确保它们的安全性和准确性。

官方解释

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 DELETE statements where keys are not used properly and that would probably change or delete a large number of rows. The default value is 0.

当 sql_safe_updates 设置为 1 时。

  • update 语句必须满足如下条件之一才能执行成功:
    • update 语句使用 where,并且 where 条件中必须有索引列;
    • update 语句使用 limit;
    • update 语句同时使用 where 和 limit,此时 where 条件中可以不带有索引列;
(root@localhost)[superdb]> update dept set loc='sz' limit 1;
Query OK, 1 row affected (0.10 sec)
Rows matched: 1  Changed: 1  Warnings: 0
(root@localhost)[superdb]> select * from dept;
+--------+------------+---------+
| deptno | dname      | loc     |
+--------+------------+---------+
|     10 | ACCOUNTING | sz      |
|     20 | RESEARCH   | DALLAS  |
|     30 | SALES      | CHICAGO |
|     40 | OPERATIONS | BOSTON  |
+--------+------------+---------+
4 rows in set (0.00 sec)
(root@localhost)[superdb]> update dept set loc='NEW YORK' limit 1;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0
(root@localhost)[superdb]> update dept set loc='NEW YORK' where deptno=10;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0
(root@localhost)[superdb]> select * from dept;
+--------+------------+----------+
| deptno | dname      | loc      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
4 rows in set (0.00 sec)
(root@localhost)[superdb]> update dept set loc='NEW YORK' where deptno=10 limit 2;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0
(root@localhost)[superdb]> select * from dept;
+--------+------------+----------+
| deptno | dname      | loc      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
4 rows in set (0.00 sec)
  • delete 语句必须满足以下条件能执行成功:
  • delete 语句同时使用 where 条件中带有索引列
  • delete 语句同时使用 where 条件中带有索引列 及 limit
  • delete 语句同时使用 where 和 limit,此时 where 条件中可以不带有索引列;
(root@localhost)[superdb]> insert into dept values(50,'sz','hk');
Query OK, 1 row affected (0.01 sec)
-- 同时使用 where 和 limit,此时 where 条件中可以有索引列
(root@localhost)[superdb]> delete from dept where deptno=50 limit 1;
Query OK, 1 row affected (0.00 sec)
(root@localhost)[superdb]> insert into dept values(50,'sz','hk');
Query OK, 1 row affected (0.00 sec)
-- 仅使用 where条件中是索引列
(root@localhost)[superdb]> delete from dept where deptno=50;
Query OK, 1 row affected (0.01 sec)
(root@localhost)[superdb]> insert into dept values(50,'sz','hk');
Query OK, 1 row affected (0.00 sec)
-- dname不是索引列,因此无法删除操作
(root@localhost)[superdb]> delete from dept where dname='sz';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. 
-- 同时使用 where 和 limit,此时 where 条件中没有索引列
(root@localhost)[superdb]> delete from dept where dname='sz' limit 1;
Query OK, 1 row affected (0.05 sec)
(root@localhost)[superdb]> select * from dept;
+--------+------------+----------+
| deptno | dname      | loc      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
4 rows in set (0.00 sec)
(root@localhost)[superdb]> show index from dept;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| dept  |          0 | PRIMARY  |            1 | deptno      | A         |           4 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
1 row in set (0.13 sec)

如果 where 条件带上了索引列,但是优化器最终扫描选择的是全表,而不是索引的话,我们可以使用 force index([index_name]) 可以告诉优化器使用哪个索引,以此避免有几率锁全表带来的隐患。

到此这篇关于MySQL sql_safe_updates参数的文章就介绍到这了,更多相关mysql sql_safe_updates参数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mysql实现随机查询经验谈

    mysql实现随机查询经验谈

    官方文档中进行说明:Order By和RAND()连用,会多次扫描表,导致速度变慢,下面看下一些测试详解
    2013-10-10
  • Mysql离线安装8.0.26的图文教程

    Mysql离线安装8.0.26的图文教程

    这篇文章主要介绍了Mysql离线安装8.0.26的图文教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • Mysql数据库表中为什么有索引却没有提高查询速度

    Mysql数据库表中为什么有索引却没有提高查询速度

    你有没有想起过为什么明明再数据库中有索引,但是查询速度却并没有希望的那样快?本篇文章将带给你答案,跟小编一起看看吧
    2022-02-02
  • MySQL百万级数据,怎样做分页查询

    MySQL百万级数据,怎样做分页查询

    这篇文章主要介绍了MySQL百万级数据,怎样做分页查询?今天咱们就来聊聊这个话题,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • MySQL中order by的使用详情

    MySQL中order by的使用详情

    在使用select语句时可以结合order by对查询的数据进行排序。如果不使用order by默认情况下MySQL返回的数据集,与它在底层表中的顺序相同,可能与你添加数据到表中的顺序一致,也可能不一致,如果希望得到的数据有顺序,就该明确排序方式,下面详细内容需要的朋友可以参考一下
    2021-11-11
  • phplib中的一些基本语法和函数

    phplib中的一些基本语法和函数

    phplib中常用的方法有set_file,set_block,set_var,parse,ppasre,p,get等。
    2010-04-04
  • MySQL中sql_mode模式的使用

    MySQL中sql_mode模式的使用

    mysql为了支持在不同的环境下运行,允许我们给它设置不同的运行模式,本文主要介绍了MySQL中sql_mode模式的使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-08-08
  • mysql慢查询日志轮转_MySQL慢查询日志实操

    mysql慢查询日志轮转_MySQL慢查询日志实操

    这篇文章主要介绍了mysql慢查询日志轮转_MySQL慢查询日志实操,文章围绕主题展开详细的内容戒杀,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • MySQL基础教程第一篇 mysql5.7.18安装和连接教程

    MySQL基础教程第一篇 mysql5.7.18安装和连接教程

    这篇文章主要为大家详细介绍了MySQL基础教程第一篇,mysql5.7.18安装和连接教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • MySQL千万级大表进行数据清理的几种常见方案

    MySQL千万级大表进行数据清理的几种常见方案

    当MySQL数据库中的表数据量达到千万级别时,直接对数据进行删除操作将面临严重的性能问题,可能会导致数据库长时间的锁表,因此,如何安全高效地进行数据清理成为一个亟需解决的问题,下面我将分享几种常见的数据清理方案,需要的朋友可以参考下
    2023-11-11

最新评论