MySQL sql_safe_updates參數(shù)詳解
sql_safe_updates 是 MySQL 中的一個系統(tǒng)變量,用于控制 MySQL 服務(wù)器是否允許在沒有使用 KEY 或 LIMIT 子句的 UPDATE 或 DELETE 語句上執(zhí)行更新或刪除操作。當這個變量被設(shè)置為 ON 時,MySQL 會拒絕那些可能影響到表中大量行的 UPDATE 或 DELETE 語句,除非這些語句明確使用了 WHERE 子句中的 KEY(如主鍵或唯一索引)或者 LIMIT 子句來限制影響的行數(shù)。
這樣做的目的是為了防止由于疏忽或錯誤編寫的 SQL 語句而導(dǎo)致大量數(shù)據(jù)的意外丟失或修改。
如何設(shè)置 sql_safe_updates
你可以通過幾種方式設(shè)置 sql_safe_updates:
全局級別:
你可以通過修改 MySQL 的配置文件(如 my.cnf 或 my.ini,取決于你的操作系統(tǒng)和 MySQL 版本)來永久設(shè)置這個變量。但是,請注意,直接在配置文件中設(shè)置 sql_safe_updates 可能不被所有 MySQL 版本支持,或者可能需要以不同的方式配置(如通過插件或其他系統(tǒng)變量)。
一種更常見的方法是使用 MySQL 的 SET GLOBAL 語句在運行時設(shè)置它,但這只會影響新的連接。例如:
SET GLOBAL sql_safe_updates = 1;
但是,請注意,直接設(shè)置全局變量可能需要管理員權(quán)限,并且這個更改不會影響已經(jīng)存在的會話。
會話級別:
你可以通過在你的 MySQL 會話中執(zhí)行以下 SQL 語句來設(shè)置 sql_safe_updates:
SET SESSION sql_safe_updates = 1; 或者登錄時加上--safe-updates mysql -uroot -p --safe-updates
這會影響當前會話中的后續(xù)操作,但不會影響到其他會話或全局設(shè)置。
注意事項
在啟用 sql_safe_updates 后,如果你嘗試執(zhí)行一個沒有 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。它通常是由數(shù)據(jù)庫管理員或開發(fā)者根據(jù)特定的安全要求來配置的。
- 在某些情況下,你可能需要臨時禁用 sql_safe_updates 以執(zhí)行特定的批量更新或刪除操作。在這種情況下,你可以在會話級別設(shè)置 sql_safe_updates = 0,但請務(wù)必小心,確保你的 SQL 語句是安全的,不會意外地影響大量數(shù)據(jù)。
總之,sql_safe_updates 是一個有用的安全特性,可以幫助防止由于疏忽或錯誤導(dǎo)致的數(shù)據(jù)丟失。然而,它也要求開發(fā)者和數(shù)據(jù)庫管理員更加注意他們的 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 設(shè)置為 1 時。
- update 語句必須滿足如下條件之一才能執(zhí)行成功:
- 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 語句必須滿足以下條件能執(zhí)行成功:
- 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 條件帶上了索引列,但是優(yōu)化器最終掃描選擇的是全表,而不是索引的話,我們可以使用 force index([index_name]) 可以告訴優(yōu)化器使用哪個索引,以此避免有幾率鎖全表帶來的隱患。
到此這篇關(guān)于MySQL sql_safe_updates參數(shù)的文章就介紹到這了,更多相關(guān)mysql sql_safe_updates參數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mysql數(shù)據(jù)庫表中為什么有索引卻沒有提高查詢速度
你有沒有想起過為什么明明再數(shù)據(jù)庫中有索引,但是查詢速度卻并沒有希望的那樣快?本篇文章將帶給你答案,跟小編一起看看吧2022-02-02

MySQL基礎(chǔ)教程第一篇 mysql5.7.18安裝和連接教程

MySQL千萬級大表進行數(shù)據(jù)清理的幾種常見方案