約束
一、約束的概述
1.為什么需要約束
數據完整性是指數據的精確性和可靠性。它是防止數據庫 中存在不符合 語義規定的數據和防止因錯誤信息的輸入輸出造成無效操作或錯誤信息而提出的。
①實體完整性:例如,同一個表中數據庫引用完整性約束,不能存在兩條完全相同無法區分的記錄。
②域完整性:例如,年齡范圍0-120,性別范圍“男/女”
③引用完整性:例如,員工在部門數據庫引用完整性約束,在部門表中要能找到這個部門
④用戶自定義完整性:例如,用戶名唯一,密碼不能為空等,本部門經理的工資不得高于本部門職工的平均工資的5倍。
1.3約束的分類:
角度1:約束的字段的個數
單列約束 VS 多列約束
角度2:約束的作用范圍
列級約束:將此約束聲明在對應字段的后面
表級約束:在表中所有字段都聲明完,在所有字段的后面聲明的約束
角度3:約束的作用(功能)
① not null (非空約束)
② (唯一性約束)
③ key(主鍵約束)
④ KEY (外鍵約束)
⑤check (檢查約束)
⑥(默認值約束)
如何添加/刪除約束?
TABLE 時添加約束
ALTER TABLE 時增加約束,刪除約束
二、約束的分類 not null (非空約束)
特點:
#數據完整性和約束的分類
/*
什么叫約束?對表中字段的限制
約束的分類:
角度1:約束的字段的個數
單列約束 VS 多列約束
角度2:約束的作用范圍
列級約束:將此約束聲明在對應字段的后面
表級約束:在表中所有字段都聲明完,在所有字段的后面聲明的約束
角度3:約束的作用(功能)
① not null (非空約束)
②unique (唯一性約束)
③ primary key(主鍵約束)
④foreign KEY (外鍵約束)
⑤check (檢查約束)
⑥default(默認值約束)
如何添加/刪除約束?
CREATE TABLE 時添加約束
ALTER TABLE 時增加約束,刪除約束
*/
#如何查看表中的約束
SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE TABLE_NAME = 'employees';
CREATE DATABASE dbtest13;
USE dbtest13;
#not null (非空約束)
#在CREATE TABLE 時添加約束
CREATE TABLE test1(
id INT NOT NULL,
last_name VARCHAR(15) NOT NULL,
email VARCHAR(25),
salary DECIMAL(10,2)
);
DESC test1;
INSERT INTO test1(id,last_name,email,salary)
VALUES(1,'Tom','tom@126.com','3400');
#錯誤: Column 'last_name' cannot be null
INSERT INTO test1(id,last_name,email,salary)
VALUES(2,NULL,'tom@126.com','3400');
UPDATE test1
SET last_name = NULL
WHERE id = 1;
#在ALTER TABLE 時增加約束
DESC test1;
ALTER TABLE test1
MODIFY email VARCHAR(25) NOT NULL;
#Column 'last_name' cannot be null
UPDATE test1
SET last_name = NULL
WHERE id = 1;
SELECT * FROM test1;
#在ALTER TABLE 時刪除約束
ALTER TABLE test1
MODIFY email VARCHAR(25) NULL;
(唯一性約束)
#在CREATE TABLE 時添加約束
CREATE TABLE test2(
id INT UNIQUE, #列級約束
last_name VARCHAR(15),
email VARCHAR(25),
salary DECIMAL(10,2),
#表級約束
CONSTRAINT uk_test2_email UNIQUE(email)
);
DESC test2;
SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE table_name = 'test2';
#在創建唯一約束的時候,如果不給唯一約束命名,就默認和列名相同
INSERT INTO test2(id,last_name,email,salary)
VALUES (1,'Tom','tom@126.com',4500);
# Duplicate entry '1' for key 'test2.id'
INSERT INTO test2(id,last_name,email,salary)
VALUES (1,'Tom1','tom1@126.com',4600);
#可以向聲明為unique的字段上添加null值。
INSERT INTO test2(id,last_name,email,salary)
VALUES (3,'Tom1',NULL,4600);
SELECT *FROM test2;
#在ALTER TABLE 時添加約束
DESC test2;
UPDATE test2
SET salary = 5000
WHERE id=3;
ALTER TABLE test2
ADD CONSTRAINT uk_test2_sal UNIQUE(salary);
ALTER TABLE test2
MODIFY last_name VARCHAR(15)UNIQUE;
#復合的唯一性約束
CREATE TABLE USER(
id INT,
`name` VARCHAR(15),
`password` VARCHAR(15),
#表級約束
CONSTRAINT uk_user_name_pwd UNIQUE(`name`,`password`)
);
INSERT INTO USER
VALUES (1,'Tom','abc');
#可以添加成功
INSERT INTO USER
VALUES (1,'Tom1','abc');
SELECT * from USER;
#刪除唯一性約束
/*
--添加唯一性約束的列上也會主動創建唯一索引
--刪除唯一約束只能通過刪除唯一索引的方式刪除
--刪除時需要指定唯一索引名,唯一索引名就和唯一約束名一樣
--如果創建唯一約束時未指定名稱,如果是單列,就默認和列名相同;如果是組合列那么默認和列名相同,那么默認和()中排在第一個的列名相同。也可以自定義唯一性約束
*/
SELECT *FROM information_schema.TABLE_CONSTRAINTS
WHERE table_name = 'student_course';
SELECT *FROM information_schema.TABLE_CONSTRAINTS
WHERE table_name = 'test2';
DESC test2;
#如何刪除唯一性索引
ALTER TABLE test2
DROP INDEX last_name;
key(主鍵約束)
特點:主鍵約束相當于唯一約束+非空約束的組合,主鍵約束列不允許重復,也不允許出現空值。
#建表時指定主鍵約束(create table)
create TABLE test4(
id INT PRIMARY KEY,#列級約束
last_name VARCHAR(15),
salary DECIMAL(10,2),
email VARCHAR(25)
);
#MySQL的主鍵名總是PRIMARY,就算自己命名了主鍵約束也沒用
create TABLE test5(
id INT ,
last_name VARCHAR(15),
salary DECIMAL(10,2),
email VARCHAR(25),
#表級約束
CONSTRAINT pk_test5_id PRIMARY KEY(id) #沒有必要起名字
);
SELECT *FROM information_schema.TABLE_CONSTRAINTS
WHERE table_name = 'test5';
INSERT INTO test4(id,last_name,salary,email)
VALUES(1,'Tom',4500,'tom@126.com');
SELECT * FROM test4;
CREATE TABLE user1(
id INT,
`name` VARCHAR(15),
`password` VARCHAR(25),
PRIMARY KEY (name,password)
);
INSERT INTO user1
VALUES (1,'Tom','abc');
#Column 'name' cannot be null
INSERT INTO user1
VALUES (1,NULL,'abc')
SELECT * FROM user1;
#在ALTER TABLE 時添加約束
create TABLE test6(
id INT ,
last_name VARCHAR(15),
salary DECIMAL(10,2),
email VARCHAR(25)
);
DESC test6;
ALTER TABLE test6
ADD PRIMARY KEY (id);
#如何刪除主鍵約束(在實際開發中,不會主動刪除主鍵約束)
ALTER TABLE test6
DROP PRIMARY KEY;
自增列:
特點:某個字段的值自增。
KEY (外鍵約束)
KEY 約束
作用:限定某個表的某個字段的引用完整性。
#FOREIGN KEY 約束
#在create table 時添加
#主表和從表,夫表和子表
#先創建主表
USE dbtest13;
CREATE TABLE dept1(
dept_id INT,
dept_name VARCHAR(15)
);
#創建從表
CREATE TABLE emp1(
emp_id INT PRIMARY KEY auto_increment,
emp_name VARCHAR(15),
department_id INT,
#表級約束
CONSTRAINT fk_emp1_dept_id FOREIGN KEY (department_id) REFERENCES dept1 (dept_id)
);
#上述操作報錯:因為主表中的dept_id沒有主鍵約束或唯一性約束。
ALTER TABLE dept1
ADD PRIMARY KEY (dept_id);
DESC emp1;
#演示外鍵效果
INSERT INTO dept1
VALUES (10,'IT');
INSERT INTO emp1
VALUES(1001,'Tom',10);
#刪除失敗
DELETE FROM dept1
WHERE dept_id = 10;
#更新失敗
UPDATE dept1
SET dept_id = 20
WHERE dept_id = 10;
#在ALTER TABLE 時添加外鍵約束
CREATE TABLE dept2(
dept_id INT PRIMARY KEY,
dept_name VARCHAR(15)
);
CREATE TABLE emp2(
emp_id INT PRIMARY KEY auto_increment,
emp_name VARCHAR(15),
department_id INT
);
DESC emp2;
ALTER TABLE emp2
ADD CONSTRAINT fk_emp2_dept_id FOREIGN KEY (department_id) REFERENCES dept2(dept_id);
#刪除外鍵約束
#一個表中可以聲明多個外鍵約束
USE atguigudb;
SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE table_name = 'employees';
USE dbtest13;
SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE table_name = 'emp1';
ALTER TABLE emp1
DROP FOREIGN KEY fk_emp1_dept_id;
#再手動刪除外鍵約束對應的普通約束
SHOW INDEX FROM emp1;
ALTER TABLE emp1
DROP INDEX fk_emp1_dept_id;
check (檢查約束)
作用:檢查某個字段的值是否符合XX要求,一般指的是值的范圍
#MySQL5.7不支持check約束,但8.0支持
USE dbtest13;
CREATE TABLE test10(
id INT,
last_name VARCHAR(15),
salary DECIMAL(10,2) CHECK (salary > 2000)
);
INSERT INTO test10
VALUES(1,'Tom',2500);
SELECT* FROM test10;
(默認值約束)
作用:給某個字段/列指定默認值,一旦設置默認值。在插入數據時,如果此字段沒有顯示賦值,則賦值為默認值
#在 create table 時添加約束
CREATE TABLE test11(
id INT,
last_name VARCHAR(15),
salary DECIMAL (10,2) DEFAULT 2000
);
DESC test11;
INSERT INTO test11(id,last_name,salary)
VALUES(1,'Tom',3000);
INSERT INTO test11(id,last_name)
VALUES(2,'Tom1');
SELECT * FROM test11;
#在alter table 時添加約束
CREATE TABLE test12(
id INT,
last_name VARCHAR(15),
salary DECIMAL (10,2)
);
DESC test12;
ALTER TABLE test12
MODIFY salary DECIMAL(8,2) DEFAULT 2500;
#在alter table 刪除約束
ALTER TABLE test12
MODIFY salary DECIMAL(8,2);