Rumah  >  Artikel  >  pangkalan data  >  Analisis mendalam tentang 6 jenis kekangan biasa dalam MySQL

Analisis mendalam tentang 6 jenis kekangan biasa dalam MySQL

青灯夜游
青灯夜游ke hadapan
2021-09-16 19:55:033117semak imbas

Analisis mendalam tentang 6 jenis kekangan biasa dalam MySQL

Maksud literal kekangan adalah untuk menetapkan atau mengehadkan bagaimana sesuatu harus dilakukan Dalam MySQL, kekangan adalah untuk menentukan peraturan untuk data dalam jadual data, iaitu, untuk mengehadkan data. Ini adalah untuk memastikan kebolehpercayaan Sebagai contoh, nilai Null tidak dibenarkan muncul dalam lajur tertentu, kita akan menghadapi jenis kekangan berikut.

  • NOT NULL: Pastikan lajur tidak boleh mempunyai nilai NULL
  • CHECK: Pastikan nilai dalam lajur memenuhi syarat tertentu
  • UNIQUE: Pastikan nilai dalam lajur Semua nilai
  • PRIMARY KEY adalah berbeza: Gabungan NOT NULL dan UNIQUE secara unik mengenal pasti setiap baris dalam jadual
  • FOREIGN KEY: Kekangan kunci asing
  • DEFAULT: Jika tiada nilai dinyatakan, tetapkan nilai lalai untuk lajur

[Cadangan berkaitan: tutorial video mysql]

Kekangan

1.NULL

MySQL menggunakan NOT NULL untuk memastikan nilai Null akan tidak muncul dalam lajur. Semasa membuat jadual, formatnya adalah seperti berikut:

mysql> create table user(name varchar(255)not null);
Query OK, 0 rows affected (0.06 sec)

Jika anda cuba memasukkan nilai nol, pengecualian akan dilemparkan.

mysql> insert user values(null);
ERROR 1048 (23000): Column 'name' cannot be null

atau tambahkan kekangan NOT NULL baharu pada jadual sedia ada.

mysql> alter table user modify name varchar(255) not null;
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0

Padamkan kekangan NOT NULL.

mysql> alter table user modify name varchar(255)  null;
Query OK, 0 rows affected (0.09 sec)
Records: 0  Duplicates: 0  Warnings: 0

2.SEMAK

Jika anda ingin menentukan kekangan bersyarat pada lajur, anda boleh menggunakan CHECK, seperti berikut untuk memaksa medan umur untuk lebih besar daripada 18 dan kurang daripada 80, Jika tidak, ralat akan dilaporkan.

mysql> create table user(age int(11) check(age>18 and age <80));
Query OK, 0 rows affected, 1 warning (0.06 sec)

Ujian sisipan, anda boleh menemui pengecualian lontaran 9 dan 81 semasa memasukkan.

mysql> insert user values(9);
ERROR 3819 (HY000): Check constraint &#39;user_chk_1&#39; is violated.

mysql> insert user values(19);
Query OK, 1 row affected (0.01 sec)

mysql> insert user values(81);
ERROR 3819 (HY000): Check constraint &#39;user_chk_1&#39; is violated.
mysql>

Anda juga boleh melakukan kekangan berbilang lajur, seperti umur mestilah lebih daripada 18 tahun dan bandar itu mestilah China.

mysql> create table user(age int(11),city varchar(255) ,check(age>18 and city=&#39;中国&#39;));
Query OK, 0 rows affected, 1 warning (0.05 sec)

Sisipkan ujian.

mysql> insert user values(81,&#39;2&#39;);
ERROR 3819 (HY000): Check constraint &#39;user_chk_1&#39; is violated.
mysql> insert user values(8,&#39;2&#39;);
ERROR 3819 (HY000): Check constraint &#39;user_chk_1&#39; is violated.
mysql> insert user values(20,&#39;2&#39;);
ERROR 3819 (HY000): Check constraint &#39;user_chk_1&#39; is violated.
mysql> insert user values(20,&#39;中国&#39;);
Query OK, 1 row affected (0.01 sec)

mysql> insert user values(20,&#39;中国1&#39;);
ERROR 3819 (HY000): Check constraint &#39;user_chk_1&#39; is violated.
mysql> insert user values(85,&#39;中国&#39;);
Query OK, 1 row affected (0.01 sec)

mysql> insert user values(9,&#39;中国&#39;);
ERROR 3819 (HY000): Check constraint &#39;user_chk_1&#39; is violated.

Anda juga boleh menentukan bahawa nilai lajur mestilah dalam set yang ditentukan, seperti jantina mestilah dalam set lelaki, perempuan, tidak diketahui dan shemale.

mysql> create table user(sex varchar(255) check (sex in (&#39;男&#39;,&#39;女&#39;,&#39;未知&#39;,&#39;人妖&#39;)));
Query OK, 0 rows affected (0.05 sec)

Sisipkan ujian.

mysql> insert user values("男");
Query OK, 1 row affected (0.02 sec)

mysql> insert user values("男男");
ERROR 3819 (HY000): Check constraint &#39;user_chk_1&#39; is violated.
mysql> insert user values("女");
Query OK, 1 row affected (0.01 sec)

mysql> insert user values("人妖");
Query OK, 1 row affected (0.00 sec)

Namakan kekangan dan padamkan kekangan.

mysql> create table user (age int(11) ,constraint CHK_AGE check(age>18));
Query OK, 0 rows affected, 1 warning (0.05 sec)

mysql> insert user values(5);
ERROR 3819 (HY000): Check constraint &#39;CHK_AGE&#39; is violated.

mysql> alter table user drop check CHK_AGE;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> insert user values(5);
Query OK, 1 row affected (0.01 sec)

Tetapi, pernahkah anda melihatnya ditulis seperti ini?

Teka apa yang berikut lakukan.

Ini sebenarnya adalah kes apabila penghakiman bersyarat, yang membenarkannya hanya memasukkan >=18, atau nombor antara 0-10.

CREATE TABLE `user` (`age` int(11) CHECK 
(((case when (`age` >=18) then 1 
else 
(case when age<10 and age >0 then 1 else 2 end) end) =1)));

3.UNIK

UNIQUE kekangan memastikan tiada nilai pendua dalam lajur kedua-dua UNIQUE dan PRIMARY KEY adalah untuk satu lajur nilai Keunikan dijamin, tetapi UNIQUE boleh muncul beberapa kali dalam setiap jadual, manakala PRIMARY KEY hanya boleh muncul sekali.

Sebagai contoh, medan nama di bawah tidak boleh diulang.

mysql> create table user (name varchar(255),unique(name));
Query OK, 0 rows affected (0.07 sec)

Sisipkan ujian.

mysql> insert user values("张三");
Query OK, 1 row affected (0.02 sec)

mysql> insert user values("张三");
ERROR 1062 (23000): Duplicate entry &#39;张三&#39; for key &#39;user.name&#39;mysql>

Namakan kekangan ini dan padamkannya.

mysql> create table user (name varchar(255),constraint name_un unique(name));
Query OK, 0 rows affected (0.07 sec)

mysql> insert user values("张三");
Query OK, 1 row affected (0.02 sec)

mysql> insert user values("张三");
ERROR 1062 (23000): Duplicate entry &#39;张三&#39; for key &#39;user.name_un&#39;
mysql> alter table user drop index name_un;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> insert user values("张三");
Query OK, 1 row affected (0.02 sec)

Selepas memasukkan, anda boleh menggunakan pernyataan berikut untuk melihat pernyataan penciptaan.

mysql> show create table user;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| user  | CREATE TABLE `user` (
  `name` varchar(255) DEFAULT NULL,
  UNIQUE KEY `name_un` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

Untuk mengalih keluar kekangan UNIQUE, anda boleh menggunakan pernyataan DROP INDEX atau ALTER TABLE:

mysql> DROP INDEX name_un ON user;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table user;
+-------+-----------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                |
+-------+-----------------------------------------------------------------------------------------------------------------------------+
| user  | CREATE TABLE `user` (
  `name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+-----------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

untuk menambah pada jadual sedia ada.

mysql> alter table user add constraint name_un unique(name);
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

4.KUNCI UTAMA

Biasanya setiap jadual mengandungi nilai yang mengenal pasti setiap baris secara unik.

mysql> create table user (id int(11) ,age int(11),primary key (id));
Query OK, 0 rows affected, 2 warnings (0.06 sec)

mysql> insert user values(1,2);
Query OK, 1 row affected (0.02 sec)

mysql> insert user values(1,2);
ERROR 1062 (23000): Duplicate entry &#39;1&#39; for key &#39;user.PRIMARY&#39;mysql>

5.KUNCI ASING

FOREIGN KEY digunakan untuk mengekang medan dalam jadual mestilah nilai yang wujud dalam medan dalam jadual lain , Tetapi dalam jadual lain, lajur ini tidak perlu menjadi kunci utama, tetapi ia mestilah indeks unik, jika tidak, penciptaan akan gagal.

Sebagai contoh, userId dalam jadual pesanan mesti merujuk kepada id dalam jadual pengguna Jika userId yang dimasukkan tidak wujud dalam jadual pengguna, ia tidak boleh dimasukkan.

mysql> create table orders (id int(11) primary key ,userId int(11) ,  FOREIGN KEY (userId) REFERENCES user(id) );
Query OK, 0 rows affected, 2 warnings (0.06 sec)

mysql> insert orders values(1,3);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`t`.`orders`, CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`))

mysql> insert orders values(1,1);
Query OK, 1 row affected (0.01 sec)

Tetapi terdapat masalah Jika rekod dalam jadual utama (pengguna) dipadamkan atau dikemas kini, apakah yang sepatutnya berlaku kepada rekod dalam pesanan? , seperti dalam contoh di bawah, anda boleh mendapati bahawa ralat dilaporkan secara langsung.

mysql> update user set id =2 where id =1;

Cannot delete or update a parent row: a foreign key constraint fails (`t`.`orders`, CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`)

MySQL menyediakan beberapa kekangan untuk membantu kami menyelesaikan masalah jenis ini Contohnya, apabila jadual pengguna dikemas kini, pesanan juga dikemas kini satu demi satu.

  1. HAD: Enggan mengemas kini atau memadam rekod dalam jadual induk jika terdapat rekod dalam jadual anak.

  2. CASCADE: Kemas kini atau padam rekod secara automatik dalam jadual anak apabila mengemas kini atau memadam rekod dalam jadual induk.

  3. SET NULL: Tetapkan nilai medan dalam jadual anak kepada batal apabila mengemas kini atau memadam rekod jadual induk.

Anda boleh mendapati bahawa RESTRICT digunakan secara lalai Mari ubah suainya supaya ia turut dikemas kini semasa mengemas kini dan null ditetapkan semasa memadam.

mysql> alter table orders add constraint orders_ibfk_1  FOREIGN KEY (`userId`) REFERENCES `user` (`id`) on update cascade on
delete set null;
Query OK, 0 rows affected (0.12 sec)
Records: 0  Duplicates: 0  Warnings: 0

Kemas kini ujian

mysql> select * from user;
+----+--------+
| id | name   |
+----+--------+
|  1 | 张三   |
+----+--------+
1 row in set (0.00 sec)

mysql> select * from orders;
Empty set (0.00 sec)

mysql> insert orders values (1,1);
Query OK, 1 row affected (0.01 sec)

mysql> update user set id =2 where id =1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from orders;
+----+--------+
| id | userId |
+----+--------+
|  1 |      2 |
+----+--------+
1 row in set (0.01 sec)

Ujian pemadaman.

mysql> delete from user where id =2;
Query OK, 1 row affected (0.02 sec)

mysql> select * from orders;
+----+--------+
| id | userId |
+----+--------+
|  1 |   NULL |
+----+--------+
1 row in set (0.00 sec)

6.DEFAULT

DEFAULT kekangan digunakan untuk menetapkan nilai lalai untuk lajur Jika medan tidak diberikan nilai, sistem akan secara automatik Medan disisipkan dengan nilai lalai Tiada tugasan bermakna medan itu tidak dinyatakan semasa memasukkan data Jika nilai nol ditentukan, nilai nol akhirnya disimpan.

mysql> create table user(age int(11) default 18);
Query OK, 0 rows affected, 1 warning (0.05 sec)

mysql> insert user values();
Query OK, 1 row affected (0.02 sec)

mysql> select * from user;
+------+
| age  |
+------+
|   18 |
+------+
1 row in set (0.00 sec)

Alamat asal: https://juejin.cn/post/7000352993572814885

Pengarang: i Tingfeng Passing Night

Lebih lanjut -pengetahuan berkaitan, sila layari: Video Pengaturcaraan! !

Atas ialah kandungan terperinci Analisis mendalam tentang 6 jenis kekangan biasa dalam MySQL. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam