最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL數(shù)據(jù)庫約束從入門到精通

 更新時間:2025年10月27日 11:22:24   作者:愛編程的小新☆  
數(shù)據(jù)庫約束時數(shù)據(jù)庫中用于強(qiáng)制數(shù)據(jù)完整性的規(guī)則,確保表中數(shù)據(jù)的準(zhǔn)確性、一致性和有效性,通過限制表中數(shù)據(jù)的輸入修改和刪除行為,防止無效和不合理數(shù)據(jù)操作,本文給大家介紹MySQL數(shù)據(jù)庫約束的相關(guān)知識,感興趣的朋友跟隨小編一起看看吧

一. 什么是數(shù)據(jù)庫約束

數(shù)據(jù)庫約束時數(shù)據(jù)庫中用于強(qiáng)制數(shù)據(jù)完整性的規(guī)則,確保表中數(shù)據(jù)的準(zhǔn)確性、一致性和有效性,通過限制表中數(shù)據(jù)的輸入修改和刪除行為,防止無效和不合理數(shù)據(jù)操作。

二. 數(shù)據(jù)庫約束類型

在數(shù)據(jù)庫中有不同的約束來約束著不同的操作,那么接下來一起看看有哪些數(shù)據(jù)庫約束。

2.1 非空約束(NOT NULL)

非空約束的作用:

指定表中的某一個列中的值不能為NULL

 創(chuàng)建一個學(xué)生表進(jìn)行示例演示:

-- 創(chuàng)建student表
create table student(
  id BIGINT comment'編號',
  name varchar(20) comment'姓名'
);
mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | bigint      | YES  |     | NULL    |       |
| name  | varchar(20) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
(此時表中結(jié)構(gòu)中的NuLL都為YES,此時表示當(dāng)前id列和name列的值是可以為NULL的)
mysql> select *from student;
+------+------+
| id   | name |
+------+------+
|    1 | NULL |
+------+------+
1 row in set (0.00 sec)
-- 此時表中name列的值是可以為空的

指定name列不能為空:

-- 重新創(chuàng)建學(xué)生表
create table student(
  id BIGINT comment'編號',
  `name` varchar(20) not null comment'姓名'
);
-- 查看表結(jié)構(gòu)
mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | bigint      | YES  |     | NULL    |       |
| name  | varchar(20) | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
(此時name列的NuLL那就變成了NO,此時就表示值不能為NULL)
-- 添加數(shù)據(jù)
mysql> insert into student (id,name) values(1,NULL);
ERROR 1048 (23000): Column 'name' cannot be null
(此時就報錯提示,不能添加NULL值)

那么添加數(shù)據(jù)之前,就可以查看一下當(dāng)前表結(jié)構(gòu),看看添加的數(shù)據(jù)能否為NULL

2.2 默認(rèn)值約束(DEFAULT)

在我們剛才創(chuàng)建的表結(jié)構(gòu)中,可以看到Default的值為NULL,這表示當(dāng)沒有指定數(shù)據(jù)時,當(dāng)前默認(rèn)值是為空的,那么我們的默認(rèn)值約束就可以將默認(rèn)值NULL定義成自己想要的默認(rèn)值

mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | bigint      | YES  |     | NULL    |       |
| name  | varchar(20) | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

示例演示:

-- 重新創(chuàng)建student表
create table student(
  id BIGINT comment'編號',
  `name` varchar(20) not null comment'姓名' ,
  age INT comment'年齡' DEFAULT(18)
);
-- 查看表結(jié)構(gòu)
mysql> desc student;
+-------+-------------+------+-----+---------+-------------------+
| Field | Type        | Null | Key | Default | Extra             |
+-------+-------------+------+-----+---------+-------------------+
| id    | bigint      | YES  |     | NULL    |                   |
| name  | varchar(20) | NO   |     | NULL    |                   |
| age   | int         | YES  |     | 18      | DEFAULT_GENERATED |
+-------+-------------+------+-----+---------+-------------------+
3 rows in set (0.00 sec)
(此時age列中的default就為18,表中默認(rèn)值為18)
-- 添加數(shù)據(jù)
mysql> insert into student(id,name) values(1,'張三');
Query OK, 1 row affected (0.01 sec)
mysql> select *from student;
+------+--------+------+
| id   | name   | age  |
+------+--------+------+
|    1 | 張三   |   18 |
+------+--------+------+
1 row in set (0.00 sec)
(此時我添加數(shù)據(jù)時并沒有指定age列的值,所以此時的默認(rèn)值為18)

2.3 唯一約束(UNIQUE)

指定了唯?約束的列,該列的值在所有記錄中不能重復(fù),在我們的生活中,每一個人的身份證號一定是唯一的,這個時候記錄數(shù)據(jù)時就要使用唯一約束避免數(shù)據(jù)重復(fù)的錯誤。

沒有唯一約束的狀態(tài):

mysql> insert into student(id,name) values(1,'李四');
Query OK, 1 row affected (0.01 sec)
mysql> select *from student;
+------+--------+------+
| id   | name   | age  |
+------+--------+------+
|    1 | 張三   |   18 |
|    1 | 李四   |   18 |
+------+--------+------+
2 rows in set (0.00 sec)
(此時張三和李四的編號是一樣的,那么就重復(fù)了)

那么默認(rèn)約束和唯一約束能不能一起使用呢?

-- 重新創(chuàng)建一個student表
create table student(
  id BIGINT comment'編號',
  `name` varchar(20) not null comment'姓名' ,
  age INT comment'年齡' DEFAULT 18 UNIQUE;
);
(這種寫法是可以通過的,但是不建議這樣使用)
mysql> desc student;
+-------+-------------+------+-----+---------+-------------------+
| Field | Type        | Null | Key | Default | Extra             |
+-------+-------------+------+-----+---------+-------------------+
| id    | bigint      | YES  |     | NULL    |                   |
| name  | varchar(20) | NO   |     | NULL    |                   |
| age   | int         | YES  | UNI | 18      | DEFAULT_GENERATED |
+-------+-------------+------+-----+---------+-------------------+
3 rows in set (0.00 sec)
mysql> insert into student(id,name) values(1,'張三');
Query OK, 1 row affected (0.01 sec)
mysql> insert into student(id,name) values(1,'李四');
ERROR 1062 (23000): Duplicate entry '18' for key 'student.age'
age 列同時使用 DEFAULT 和 UNIQUE 約束可能會引發(fā)問題。因?yàn)槟J(rèn)值是固定的(這里是 18),要是插入新記錄時沒有指定 age 值,就會都使用默認(rèn)值,這會違反唯一約束。(所以這里發(fā)生了報錯)

將id列加上唯一約束:

-- 重新創(chuàng)建student表
create table student(
  id BIGINT comment'編號' UNIQUE,
  `name` varchar(20) not null comment'姓名' ,
  age INT comment'年齡' DEFAULT(18) 
);
-- 查看表結(jié)構(gòu)
mysql> desc student;
+-------+-------------+------+-----+---------+-------------------+
| Field | Type        | Null | Key | Default | Extra             |
+-------+-------------+------+-----+---------+-------------------+
| id    | bigint      | YES  | UNI | NULL    |                   |
| name  | varchar(20) | NO   |     | NULL    |                   |
| age   | int         | YES  |     | 18      | DEFAULT_GENERATED |
+-------+-------------+------+-----+---------+-------------------+
3 rows in set (0.00 sec)
(此時id列上的key就為UNI,這個UNI就是唯一約束的標(biāo)識)
--添加數(shù)據(jù)
mysql> insert into student (id,name) values(1,'張三');
Query OK, 1 row affected (0.00 sec)
mysql> insert into student (id,name) values(1,'李四');
ERROR 1062 (23000): Duplicate entry '1' for key 'student.id'
(此時就會報錯:說明id列只能存在唯一值)
mysql> insert into student (id,name) values(2,'李四');
Query OK, 1 row affected (0.00 sec)
(此時的記錄就能添加成功)
mysql> select *from student;
+------+--------+------+
| id   | name   | age  |
+------+--------+------+
|    1 | 張三   |   18 |
|    2 | 李四   |   18 |
+------+--------+------+
2 rows in set (0.00 sec)

2.4 主鍵約束(PRIMARY KEY)

  • 主鍵約束的特點(diǎn)必須包含唯一的值并且不能包含NULL值(可以理解為unique和not null的特點(diǎn)的結(jié)合)
  • 每個表中只能有一個主鍵,可以由單個列或者多個列組成
  • 建議為每張表都指定一個主鍵,主鍵列建議使用Bigint類型(防止數(shù)據(jù)過大發(fā)生錯誤)

 主鍵包含了unique和not null的特點(diǎn),但是不能使用這兩個約束代替主鍵約束:

注意:有些博客中會用unique和not null來代替主鍵約束,雖然MySQL中是支持這樣的語法,但是嚴(yán)格意義上來說這是不對的。

unique和not null是業(yè)務(wù)規(guī)則,對數(shù)據(jù)本身就有這樣的要求,但是主鍵約束時數(shù)據(jù)庫表中的一個特性,決定了數(shù)據(jù)如何組織依賴主鍵(這個在下文的外鍵就會說到),主鍵通常是搭配外鍵使用的。

由于存在上述區(qū)別,在實(shí)際應(yīng)用中建議使用PRIMARY KEY來定義表的主鍵。

 示例演示:

-- 創(chuàng)建student表,使用primary key主鍵
create table student(
  id BIGINT comment'編號'PRIMARY KEY,
  `name` varchar(20) not null comment'姓名' 
);
-- 查看表結(jié)構(gòu)
mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | bigint      | NO   | PRI | NULL    |       |
| name  | varchar(20) | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
(此時的Key那里就顯示主鍵約束的標(biāo)識了)
-- 重新創(chuàng)建student表,使用not null+unique代替主鍵
create table student(
  id BIGINT comment'編號' not null UNIQUE,
  `name` varchar(20) not null comment'姓名' 
);
-- 查看表結(jié)構(gòu)
mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | bigint      | NO   | PRI | NULL    |       |
| name  | varchar(20) | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec
(此時Key這里顯示的也是PRI主鍵標(biāo)識,但是還是不建議這么使用)

 添加數(shù)據(jù)測試:

-- 添加數(shù)據(jù)
mysql> insert into student values(1,'張三');
Query OK, 1 row affected (0.00 sec)
(這是使用null not+unique代替主鍵的方式報的錯誤)
mysql> insert into student values(1,'李四');
ERROR 1062 (23000): Duplicate entry '1' for key 'student.id'
(這是使用主鍵方式報的錯誤)
mysql> insert into student values(1,'李四');
ERROR 1062 (23000): Duplicate entry '1' for key 'student.PRIMARY'
(所以還是會有些許差別,再次強(qiáng)調(diào)能用主鍵的地方用主鍵,不要使用null not+unique)
(此時添加成功)
mysql> insert into student values(2,'李四');
Query OK, 1 row affected (0.00 sec)
-- 查看數(shù)據(jù)
mysql> select *from student;
+----+--------+
| id | name   |
+----+--------+
|  1 | 張三   |
|  2 | 李四   |
+----+--------+
2 rows in set (0.00 sec)

注意:表中是不能有多個主鍵的:

-- 創(chuàng)建student表
mysql> create table student(
    ->   id BIGINT comment'編號' PRIMARY KEY,
    ->   `name` varchar(20) comment'姓名' PRIMARY KEY
    -> );
ERROR 1068 (42000): Multiple primary key defined
(一個表是不能創(chuàng)建多個主鍵的)

 但是可以由多個列共同組成一個主鍵(復(fù)合主鍵),主鍵是否沖突以多個列的組成進(jìn)行判斷:

-- 創(chuàng)建student表(使用復(fù)合主鍵)
create table student(
  id BIGINT comment'編號',
  `name` varchar(20) comment'姓名',
  PRIMARY KEY (id, name)
);
-- 查看表結(jié)構(gòu)
mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | bigint      | NO   | PRI | NULL    |       |
| name  | varchar(20) | NO   | PRI | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
(此時id列和name列中的key都帶有PRI主鍵標(biāo)識)
-- 添加數(shù)據(jù)
mysql> insert into student values(1,'張三');
Query OK, 1 row affected (0.01 sec)
mysql> insert into student values(1,'李四');
Query OK, 1 row affected (0.00 sec)
mysql> select *from student;
+----+--------+
| id | name   |
+----+--------+
|  1 | 張三   |
|  1 | 李四   |
+----+--------+
2 rows in set (0.00 sec)
(此時id列是可以重復(fù)的,因?yàn)楝F(xiàn)在是根據(jù)id和name的值一起判斷的)
-- id和name一起重復(fù)
mysql> insert into student values(1,'張三');
ERROR 1062 (23000): Duplicate entry '1-張三' for key 'student.PRIMARY'
(此時就會報錯)

AUTO_INCREMENT(自動增長)

在之前創(chuàng)建的student表中,id列通常需要我們手動進(jìn)行輸入數(shù)據(jù),每次添加前都需要查看一下當(dāng)前id數(shù)到哪里了,這就很影響我們的效率,所以引入的 AUTO_INCREMENT(自動增長)

-- 創(chuàng)建學(xué)生表
create table student(
  id BIGINT comment'編號' PRIMARY KEY auto_increment,
  `name` varchar(20) comment'姓名'
);
-- 查看表結(jié)構(gòu)
mysql> desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | bigint      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(20) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)mysql> desc student;
(此時extra那里就多了一個auto_increment(自動增長))
-- 添加數(shù)據(jù)
mysql> insert into student (name) values('張三');
Query OK, 1 row affected (0.03 sec)
mysql> insert into student (name) values('李四');
Query OK, 1 row affected (0.00 sec)
mysql> select *from student;
+----+--------+
| id | name   |
+----+--------+
|  1 | 張三   |
|  2 | 李四   |
+----+--------+
2 rows in set (0.00 sec)
(通過查看表中的數(shù)據(jù)就可以發(fā)現(xiàn),id列的編號自己進(jìn)行增加和添加了)
-- 在有自動增加的情況下,null值為一個占用符
mysql> insert into student (id,name) values(null,'李四');
Query OK, 1 row affected (0.00 sec)
mysql> select *from student;
+----+--------+
| id | name   |
+----+--------+
|  1 | 張三   |
|  2 | 李四   |
|  3 | 李四   |
+----+--------+
3 rows in set (0.00 sec)
-- 手動輸入id列的值
mysql> select *from student;
+-----+--------+
| id  | name   |
+-----+--------+
|   1 | 張三   |
|   2 | 李四   |
|   3 | 李四   |
| 100 | 王五   |
+-----+--------+
4 rows in set (0.00 sec)
(此時id列的值就是我們手動添加的值,但是現(xiàn)在自增的值又會是多少呢)
-- 查看自增的值
mysql> show create table student;
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                                                                                                                                                    |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| student | CREATE TABLE `student` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '編號',
  `name` varchar(20) DEFAULT NULL COMMENT '姓名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci     |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
(此時AUTO_INCREMENT=101,所以下一次再進(jìn)行添加的時候,自增的值就會變成101)
-- 添加數(shù)據(jù)
mysql> insert into student (name) values('趙六');
Query OK, 1 row affected (0.01 sec)
mysql> select *from student;
+-----+--------+
| id  | name   |
+-----+--------+
|   1 | 張三   |
|   2 | 李四   |
|   3 | 李四   |
| 100 | 王五   |
| 101 | 趙六   |
+-----+--------+
5 rows in set (0.00 sec)

主鍵或唯?鍵沖突時的更新操作

當(dāng)我們提前預(yù)測到當(dāng)前添加的數(shù)據(jù)可能會出現(xiàn)主鍵沖突的情況下,我們可以對之前插入的數(shù)據(jù)進(jìn)行修改,這樣就避免了主鍵沖突的現(xiàn)象:

更新數(shù)據(jù)的方式一:

-- 創(chuàng)建student表
create table student(
  id BIGINT comment'編號' PRIMARY KEY,
  `name` varchar(20) comment'姓名',
  sno varchar(20) comment'學(xué)號'
);
-- 添加數(shù)據(jù)
mysql> insert into student(id,name,sno) values(1,'張三','10001');
Query OK, 1 row affected (0.01 sec)
mysql> insert into student(id,name,sno) values(1,'張三',10002);
ERROR 1062 (23000): Duplicate entry '1' for key 'student.PRIMARY'
(此時直接添加就會發(fā)生報錯,但是此時兩條數(shù)據(jù)的差別就在于學(xué)號,那么我就可以進(jìn)行更新)
-- 更新數(shù)據(jù)
mysql> insert into student(id,name,sno) values(1,'張三',10002) on duplicate key update sno='10002';
Query OK, 2 rows affected (0.00 sec)
(此時為什么有2條數(shù)據(jù)進(jìn)行了改變呢,這是因?yàn)楫?dāng)前更新數(shù)據(jù)的操作的本質(zhì)其實(shí)是:先將原來的數(shù)據(jù)進(jìn)行了刪除,再將更新的數(shù)據(jù)進(jìn)行添加,所以這里是2次操作)
-- 查看
mysql> select *from student;
+----+--------+-------+
| id | name   | sno   |
+----+--------+-------+
|  1 | 張三   | 10002 |
+----+--------+-------+
1 row in set (0.00 sec)

 更新數(shù)據(jù)的方式二:

-- 更新數(shù)據(jù)
mysql> replace into student(id,name,sno) values(1,'李四','10003');
Query OK, 2 rows affected (0.01 sec)
(此時修改的記錄也是兩條,原理和方式一是一樣的)
-- 查看
mysql> select *from student;
+----+--------+-------+
| id | name   | sno   |
+----+--------+-------+
|  1 | 李四   | 10003 |
+----+--------+-------+
1 row in set (0.00 sec)

這里需要注意的是,當(dāng)沒有發(fā)生主鍵沖突的時候,更新操作就會變成添加操作:

-- 更新數(shù)據(jù)
mysql> replace into student(id,name,sno) values(2,'王五','10004');
Query OK, 1 row affected (0.01 sec)
(可以發(fā)現(xiàn)此時對數(shù)據(jù)就只進(jìn)行了1次操作)
-- 查看
mysql> select *from student;
+----+--------+-------+
| id | name   | sno   |
+----+--------+-------+
|  1 | 李四   | 10003 |
|  2 | 王五   | 10004 |
+----+--------+-------+
2 rows in set (0.00 sec)

雖然MySQL是支持這樣的更新操作的,但是不建議這樣進(jìn)行更新數(shù)據(jù),因?yàn)椴还鼙碇杏袥]有主鍵沖突的數(shù)據(jù),此時都會掃描一遍表中是否存在主鍵沖突,如果存在主鍵沖突的情況,那么就會進(jìn)行更新操作(先刪除再添加),如果沒有則進(jìn)行添加操作,這個效率是非常低的

那么在工作中我們應(yīng)該怎么去更新數(shù)據(jù)呢:

1. 先按條件去查詢一下數(shù)據(jù),看看有沒有相應(yīng)的記錄

2. 沒有的話就insert一條新紀(jì)錄

3. 有的話,要么進(jìn)行update操作(手動更新),要么將原數(shù)據(jù)的刪除標(biāo)識置為已刪除,再寫一條新數(shù)據(jù)

(在工作中是不建議直接替換老數(shù)據(jù)的,所以自己進(jìn)行手動更新并存一檔備份更加保險)

2.5 外鍵約束(FOREIGN KEY)

外鍵約束用于定義主表(存在主鍵)和從表(存在外鍵)之間的關(guān)系

外鍵約束定義在從表的列上,主表關(guān)聯(lián)的列必須是主鍵或者唯一約束

當(dāng)定義外鍵后,要求從表中的外鍵列數(shù)據(jù)必須在主表的主鍵或唯一列存在或?yàn)镹ULL

 那么為什么要將兩張表之間建立這樣的關(guān)系呢?直接將兩張表寫成一張表不是更方便嗎?

外鍵約束也是對數(shù)據(jù)的一種校驗(yàn),從表中使用了主表中的某個值,這個值必須要存在于主表中

 創(chuàng)建外鍵的語法格式:

foreign key 字段名(哪個列)references 主表 (哪個列)

創(chuàng)建一個學(xué)生表(從表)和班級表(主表)------學(xué)生表依賴班級表:

-- 創(chuàng)建class表(主表)
create table class(
  id BIGINT PRIMARY KEY auto_increment,
  class_name varchar(20) comment'班級名稱'
);
-- 添加數(shù)據(jù)
insert into class(class_name)values('軟件工程1班');
insert into class(class_name)values('軟件工程2班');
insert into class(class_name)values('軟件工程3班');
insert into class(class_name)values('軟件工程4班');
insert into class(class_name)values('軟件工程5班');
-- 查看
mysql> select* from class;
+----+------------------+
| id | class_name       |
+----+------------------+
|  1 | 軟件工程1班      |
|  2 | 軟件工程2班      |
|  3 | 軟件工程3班      |
|  4 | 軟件工程4班      |
|  5 | 軟件工程5班      |
+----+------------------+
5 rows in set (0.00 sec)
--創(chuàng)建student表(從表)
create table student(
  id BIGINT PRIMARY KEY auto_increment,
  `name` varchar(20) not null,
  class_id BIGINT,
  FOREIGN KEY (class_id) references class(id)
);
-- 添加數(shù)據(jù)
insert into student(name,class_id) values('張三',1);
insert into student(name,class_id) values('李四',1);
insert into student(name,class_id) values('王五',2);
insert into student(name,class_id) values('趙六',3);
insert into student(name,class_id) values('錢七',4);
-- 查看
mysql> select* from student;
+----+--------+----------+
| id | name   | class_id |
+----+--------+----------+
|  1 | 張三   |        1 |
|  2 | 李四   |        1 |
|  3 | 王五   |        2 |
|  4 | 趙六   |        3 |
|  5 | 錢七   |        4 |
+----+--------+----------+
5 rows in set (0.00 sec)

 此時如果學(xué)生表中的添加一個class_id這個列的數(shù)據(jù)不在班級表中的id中會發(fā)生什么呢?

mysql> insert into student(name,class_id) values('小明',6);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`))
(此時就會發(fā)生報錯)

主表中數(shù)據(jù)和從表中數(shù)據(jù)的關(guān)系:

主表和從表的刪除:

-- 刪除主表中的軟件工程1班這條數(shù)據(jù)
mysql> delete from class where class_name='軟件工程1班';
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`))
(此時是刪除不了的,因?yàn)樵趶谋碇羞€有數(shù)據(jù)和主表中的軟件工程1班這條數(shù)據(jù)建立著關(guān)系)
-- 刪除主表中的軟件工程5班這條數(shù)據(jù)
mysql> delete from class where class_name='軟件工程5班';
Query OK, 1 row affected (0.01 sec)
(此時是可以刪除的 ,因?yàn)橹爸鞅碇械臄?shù)據(jù)和從表中的數(shù)據(jù)中,軟件工程5班這條數(shù)據(jù)是沒有和從表的數(shù)據(jù)有建立關(guān)系的,所以此時是可以刪除的)

那么此時我應(yīng)該怎么刪除有關(guān)聯(lián)關(guān)系的數(shù)據(jù)呢?

先刪除從表中的數(shù)據(jù),讓從表中數(shù)據(jù)和主表中的數(shù)據(jù)斷開關(guān)聯(lián)關(guān)系
mysql> delete from student where name='錢七';
Query OK, 1 row affected (0.01 sec)
mysql> delete from class where class_name='軟件工程4班';
Query OK, 1 row affected (0.01 sec)
(此時先刪除student表中的錢7這條數(shù)據(jù),那么從表中就沒有數(shù)據(jù)和主表中的軟件工程4班這條數(shù)據(jù)有關(guān)系了,所以此時就可以刪除這條數(shù)據(jù)了)

 那么假設(shè)我將從表的數(shù)據(jù)全部刪除后,能不能將主表進(jìn)行刪除呢?

-- 刪除從表數(shù)據(jù)
mysql> delete from student;
Query OK, 4 rows affected (0.01 sec)
-- 刪除主表
mysql> drop table class;
ERROR 3730 (HY000): Cannot drop table 'class' referenced by a foreign key constraint 'student_ibfk_1' on table 'student'.
(其實(shí)現(xiàn)在還是不能直接刪除主表,因?yàn)閺谋砗椭鞅碇g還是存在聯(lián)系,只有將從表和主表這層關(guān)系斷開才能夠刪除主表)
方法1: 刪除從表,再刪除主表
mysql> drop table student;
Query OK, 0 rows affected (0.01 sec)
mysql> drop table class;
Query OK, 0 rows affected (0.01 sec)
方法2:刪除從表中的外鍵
mysql> drop table class;
ERROR 3730 (HY000): Cannot drop table 'class' referenced by a foreign key constraint 'student_ibfk_1' on table 'student'.
mysql> alter table student drop foreign key student_ibfk_1;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
(這里的刪除外鍵的名稱就是上面報錯系統(tǒng)自己生成的名稱)

工作中數(shù)據(jù)庫層面其實(shí)是不創(chuàng)建外鍵的(數(shù)據(jù)量大的情況下),我們一般是在java這種層面處理關(guān)聯(lián)關(guān)系,保證數(shù)據(jù)正確,校驗(yàn)好之后才進(jìn)行入庫的

2.6 check約束

check約束其實(shí)就是對我們插入的數(shù)據(jù)進(jìn)行判斷的最直接的約束

check約束可以應(yīng)用于一個或者多個列,限制可以接受的數(shù)據(jù)值,保證數(shù)據(jù)的準(zhǔn)確性,但是check約束在8.0.16版本才開始支持,之前的版本會忽略check的定義,為了保證版本兼容問題,我們幾乎不用check約束

 示例演示:

-- 創(chuàng)建student類
mysql> create table student(
    -> id bigint primary key auto_increment,
    -> name varchar(20)not null,
    -> age int default 18,
    -> check(age>=16),
    -> gender char(1),
    -> check(gender ='男' or gender ='女')
    -> );
Query OK, 0 rows affected (0.02 sec)
-- 添加數(shù)據(jù)
mysql> insert into student values(null,'張三',15,'男');
ERROR 3819 (HY000): Check constraint 'student_chk_1' is violated.
(當(dāng)我們添加的數(shù)據(jù)中年齡<16就會觸發(fā)第一個check約束)
mysql> insert into student values(null,'張三',19,'x');
ERROR 3819 (HY000): Check constraint 'student_chk_2' is violated.
(當(dāng)我們添加的數(shù)據(jù)中性別不是男或者女其中一個就會觸發(fā)第二個check約束)
-- 正確添加
mysql> insert into student values(null,'張三',19,'男');
Query OK, 1 row affected (0.01 sec)
-- 查看
mysql> select *from student;
+----+--------+------+--------+
| id | name   | age  | gender |
+----+--------+------+--------+
|  1 | 張三   |   19 | 男     |
+----+--------+------+--------+
1 row in set (0.00 sec)

到此這篇關(guān)于MySQL數(shù)據(jù)庫約束的文章就介紹到這了,更多相關(guān)mysql數(shù)據(jù)庫約束內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mysql時區(qū)查看與設(shè)置方法

    mysql時區(qū)查看與設(shè)置方法

    這篇文章主要介紹了mysql時區(qū)查看與設(shè)置方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • MySQL中一條SQL查詢語句是如何執(zhí)行的

    MySQL中一條SQL查詢語句是如何執(zhí)行的

    在寫SQL查詢語句的時候,通常要考慮SQL語句的查詢效率,了解SQL查詢語句的執(zhí)行順序,可以讓我們寫出更好的SQL語句,下面這篇文章主要給大家介紹了關(guān)于MySQL中一條SQL查詢語句是如何執(zhí)行的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • mysql的InnoDB使用行鎖的限制

    mysql的InnoDB使用行鎖的限制

    本文主要介紹了mysql的InnoDB使用行鎖的限制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-03-03
  • MySQL為什么要避免大事務(wù)以及大事務(wù)解決的方法

    MySQL為什么要避免大事務(wù)以及大事務(wù)解決的方法

    這篇文章主要介紹了MySQL為什么要避免大事務(wù)以及大事務(wù)解決的方法,幫助大家更好的理解和學(xué)習(xí)MySQL,感興趣的朋友可以了解下
    2020-08-08
  • mysql?窗口函數(shù)?ROW_NUMBER、NTILE詳解

    mysql?窗口函數(shù)?ROW_NUMBER、NTILE詳解

    這篇文章主要介紹了mysql?窗口函數(shù)?ROW_NUMBER、NTILE,本文通過sql語句給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • Mysql5.7定時備份的實(shí)現(xiàn)

    Mysql5.7定時備份的實(shí)現(xiàn)

    這篇文章主要介紹了Mysql5.7定時備份的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • mysql密碼中有特殊字符&在命令行下登錄的操作

    mysql密碼中有特殊字符&在命令行下登錄的操作

    這篇文章主要介紹了mysql密碼中有特殊字符&在命令行下登錄的操作,具有很好的參考價值希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Linux中使用mysqladmin extended-status配合Linux命令查看MySQL運(yùn)行狀態(tài)

    Linux中使用mysqladmin extended-status配合Linux命令查看MySQL運(yùn)行狀態(tài)

    這篇文章主要介紹了Linux中使用mysqladmin extended-status配合Linux命令查看MySQL運(yùn)行狀態(tài),需要的朋友可以參考下
    2014-08-08
  • MySql 5.6.14 Win32位免安裝解壓縮版配置教程

    MySql 5.6.14 Win32位免安裝解壓縮版配置教程

    本文給大家介紹mysql 5.6.14 win32 位免安裝解壓縮版配置方法,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,對mysql5.6.14 免安裝解壓縮版配置方法感興趣的朋友一起看看吧
    2016-11-11
  • MySQL 各個索引的使用詳解

    MySQL 各個索引的使用詳解

    這篇文章主要介紹了MySQL 各個索引的使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11

最新評論

盘山县| 高州市| 德昌县| 岱山县| 颍上县| 敖汉旗| 布尔津县| 灌阳县| 陇西县| 五华县| 古蔺县| 定州市| 兴国县| 昭觉县| 法库县| 巧家县| 乳源| 抚远县| 济宁市| 洱源县| 乐山市| 绥德县| 西宁市| 江都市| 德阳市| 宜春市| 徐水县| 滦南县| 泗阳县| 辽中县| 天祝| 潞西市| 双鸭山市| 承德县| 什邡市| 阿拉善盟| 徐水县| 尼木县| 沈阳市| 思南县| 家居|