2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
sql_safe_updates on MySQL:n järjestelmämuuttuja, joka määrää, salliiko MySQL-palvelin päivittää tai poistaa UPDATE- tai DELETE-käskyjä, jotka eivät käytä KEY- tai LIMIT-lausetta. Kun tämä muuttuja on ON, MySQL hylkää UPDATE- tai DELETE-käskyt, jotka voivat vaikuttaa suureen määrään taulukon rivejä, elleivät nämä käskyt nimenomaisesti käytä KEY:tä (kuten ensisijaista avainta tai yksilöllistä indeksiä) WHERE-lauseessa tai LIMIT-lauseke rajoittaa vaikuttavien rivien määrää.
Tämän tarkoituksena on estää suurten tietomäärien tahaton menetys tai muuttaminen huolimattomien tai väärin kirjoitettujen SQL-käskyjen vuoksi.
Voit asettaa sql_safe_updates useilla tavoilla:
Voit asettaa tämän muuttujan pysyvästi muokkaamalla MySQL-määritystiedostoa (kuten my.cnf tai my.ini käyttöjärjestelmästäsi ja MySQL-versiosta riippuen). Huomaa kuitenkin, että kaikki MySQL-versiot eivät välttämättä tue sql_safe_updates-asetusta suoraan määritystiedostossa tai se on ehkä määritettävä eri tavalla (esimerkiksi laajennuksen tai muiden järjestelmämuuttujien kautta).
Yleisempi tapa on asettaa se ajon aikana MySQL:n SET GLOBAL -käskyllä, mutta tämä vaikuttaa vain uusiin yhteyksiin. Esimerkiksi:
SET GLOBAL sql_safe_updates = 1;
Huomaa kuitenkin, että globaalien muuttujien määrittäminen suoraan voi edellyttää järjestelmänvalvojan oikeuksia, eikä tämä muutos vaikuta olemassa oleviin istuntoihin.
Voit asettaa sql_safe_updates suorittamalla seuraavan SQL-käskyn MySQL-istunnossasi:
SET SESSION sql_safe_updates = 1;
或者登录时加上--safe-updates
mysql -uroot -p --safe-updates
Tämä vaikuttaa myöhempiin toimintoihin nykyisessä istunnossa, mutta ei muihin istuntoihin tai yleisiin asetuksiin.
(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.
Kaikki MySQL-asennukset eivät ota oletusarvoisesti käyttöön sql_safe_updates. Sen määrittää yleensä tietokannan ylläpitäjä tai kehittäjä tiettyjen suojausvaatimusten perusteella.
Joissakin tapauksissa saatat joutua poistamaan sql_safe_updates tilapäisesti käytöstä tiettyjen joukkopäivitys- tai poistotoimintojen suorittamiseksi. Tässä tapauksessa voit asettaa sql_safe_updates = 0 istuntotasolla, mutta varmista, että SQL-käskyt ovat turvallisia eivätkä vahingossa vaikuta suuriin tietomääriin.
Yhteenvetona voidaan todeta, että sql_safe_updates on hyödyllinen suojausominaisuus, joka voi auttaa estämään tahattomasta tai virheestä johtuvan tietojen katoamisen. Se edellyttää kuitenkin myös, että kehittäjät ja tietokannan ylläpitäjät kiinnittävät enemmän huomiota SQL-lauseisiinsa varmistaakseen niiden turvallisuuden ja tarkkuuden.
Jos arvo on 1, MySQL keskeyttää UPDATE- tai DELETE-käskyt, jotka eivät käytä avainta WHERE- tai LIMIT-lauseessa. (Erityisesti UPDATE-käskyissä on oltava WHERE-lause, joka käyttää avainta tai LIMIT-lausetta tai molempia. DELETE-käskyissä on oltava molemmat.) Tämä mahdollistaa UPDATE- tai DELETE-käskyjen saamisen, joissa avaimia ei käytetä oikein ja jotka todennäköisesti muuttuisivat. tai poista suuri määrä rivejä. Oletusarvo on 0.
(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)
(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)
Jos where-ehto tuo indeksisarakkeen, mutta optimoija lopulta skannaa ja valitsee koko taulukon indeksin sijaan, voimme käyttää pakottaa indeksiä ([index_name]) kertoaksemme optimoijalle, mitä indeksiä käyttää, jotta vältytään mahdolliselta koko taulukon lukitsemiselta. pöydän aiheuttamat piilotetut vaarat.