τα στοιχεία επικοινωνίας μου
Ταχυδρομείο[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Το sql_safe_updates είναι μια μεταβλητή συστήματος στη MySQL που ελέγχει εάν ο διακομιστής MySQL επιτρέπει λειτουργίες ενημέρωσης ή διαγραφής σε δηλώσεις UPDATE ή DELETE που δεν χρησιμοποιούν ρήτρα KEY ή LIMIT. Όταν αυτή η μεταβλητή έχει οριστεί σε ON, η MySQL θα απορρίψει δηλώσεις UPDATE ή DELETE που ενδέχεται να επηρεάσουν μεγάλο αριθμό σειρών στον πίνακα, εκτός εάν αυτές οι δηλώσεις χρησιμοποιούν ρητά το KEY (όπως πρωτεύον κλειδί ή μοναδικό ευρετήριο) στον όρο WHERE ή στο Όρος LIMIT για τον περιορισμό του αριθμού των σειρών που επηρεάζονται.
Σκοπός αυτού είναι να αποτραπεί η τυχαία απώλεια ή τροποποίηση μεγάλων ποσοτήτων δεδομένων λόγω απρόσεκτων ή εσφαλμένων γραπτών δηλώσεων SQL.
Μπορείτε να ορίσετε το sql_safe_updates με διάφορους τρόπους:
Μπορείτε να ορίσετε μόνιμα αυτήν τη μεταβλητή τροποποιώντας το αρχείο διαμόρφωσης MySQL (όπως my.cnf ή my.ini, ανάλογα με το λειτουργικό σας σύστημα και την έκδοση MySQL). Ωστόσο, σημειώστε ότι η ρύθμιση του sql_safe_updates απευθείας στο αρχείο διαμόρφωσης ενδέχεται να μην υποστηρίζεται από όλες τις εκδόσεις της MySQL ή μπορεί να χρειαστεί να ρυθμιστεί διαφορετικά (όπως μέσω μιας προσθήκης ή άλλων μεταβλητών συστήματος).
Μια πιο συνηθισμένη προσέγγιση είναι να το ρυθμίσετε κατά το χρόνο εκτέλεσης χρησιμοποιώντας τη δήλωση SET GLOBAL της MySQL, αλλά αυτό επηρεάζει μόνο τις νέες συνδέσεις. Για παράδειγμα:
SET GLOBAL sql_safe_updates = 1;
Ωστόσο, σημειώστε ότι η απευθείας ρύθμιση καθολικών μεταβλητών ενδέχεται να απαιτεί δικαιώματα διαχειριστή και αυτή η αλλαγή δεν θα επηρεάσει τις υπάρχουσες συνεδρίες.
Μπορείτε να ορίσετε sql_safe_updates εκτελώντας την ακόλουθη δήλωση SQL στην περίοδο λειτουργίας MySQL:
SET SESSION sql_safe_updates = 1;
或者登录时加上--safe-updates
mysql -uroot -p --safe-updates
Αυτό επηρεάζει τις επόμενες λειτουργίες στην τρέχουσα περίοδο λειτουργίας, αλλά όχι άλλες περιόδους σύνδεσης ή καθολικές ρυθμίσεις.
(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 για να διασφαλίσουν την ασφάλεια και την ακρίβειά τους.
Εάν οριστεί σε 1, η MySQL ματαιώνει τις προτάσεις UPDATE ή DELETE που δεν χρησιμοποιούν κλειδί στον όρο WHERE ή όρο LIMIT. (Συγκεκριμένα, οι δηλώσεις UPDATE πρέπει να έχουν μια ρήτρα WHERE που χρησιμοποιεί ένα κλειδί ή μια ρήτρα LIMIT ή και τα δύο. Οι δηλώσεις DELETE πρέπει να έχουν και τα δύο.) Αυτό καθιστά δυνατή την σύλληψη των δηλώσεων UPDATE ή DELETE όπου τα κλειδιά δεν χρησιμοποιούνται σωστά και αυτό πιθανότατα θα άλλαζε ή να διαγράψετε μεγάλο αριθμό σειρών. Η προεπιλεγμένη τιμή είναι 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)
Εάν η συνθήκη όπου φέρνει μια στήλη ευρετηρίου, αλλά ο βελτιστοποιητής τελικά σαρώνει και επιλέξει ολόκληρο τον πίνακα αντί για το ευρετήριο, μπορούμε να χρησιμοποιήσουμε το δείκτη δύναμης ([index_name]) για να πούμε στον βελτιστοποιητή ποιο ευρετήριο να χρησιμοποιήσει για να αποφύγει την πιθανότητα κλειδώματος ολόκληρου κρυφούς κινδύνους που προκαλούνται από το τραπέζι.