【數據庫】約束(主鍵、唯一鍵、外鍵、非空、默認值、自增約束)

約束


DDL 數據定義語言

DDL

1、查看某個表的約束

SELECT * FROM information_schema.table_constraints WHERE table_name = '表名稱';
或
SHOW CREATE TABLE 表名;

從information_schema架構下的系統表查看

mysql> SELECT * FROM information_schema.table_constraints WHERE table_name = 'jobs';
+--------------------+-------------------+-----------------+--------------+------------+-----------------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+
| def                | myemployees       | PRIMARY         | myemployees  | jobs       | PRIMARY KEY     |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+
1 row in set (0.00 sec)

mysql> SHOW CREATE TABLE jobs;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                           |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| jobs  | CREATE TABLE `jobs` (
  `job_id` varchar(10) NOT NULL,
  `job_title` varchar(35) DEFAULT NULL,
  `min_salary` int(6) DEFAULT NULL,
  `max_salary` int(6) DEFAULT NULL,
  PRIMARY KEY (`job_id`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

2、查看某個表的索引

SHOW INDEX FROM 表名稱;
mysql> SHOW INDEX FROM jobs;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| jobs  |          0 | PRIMARY  |            1 | job_id      | A         |          19 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)

3、主鍵約束:primary key

主鍵分爲單列主鍵和複合主鍵:

eg: 學生表 PK 學號 包含主鍵的學生表

成績表 PK 學號 課程編號 包含兩個字段組合主鍵的成績表

主鍵約束:primary key

主鍵的特點:
(1)一個表有且只能有一個主鍵約束
(2)主鍵約束意味着,唯一併且非空
(3)主鍵約束名PRIMARY primary
(4)創建主鍵會自動創建對應的索引,同樣刪除主鍵對應的索引也會刪除

(1)如何在建表時指定主鍵約束

create table 【數據名.】表名(
	字段名1 數據類型  primary key ,
	....
);
或
create table 【數據名.】表名(
	字段名1 數據類型,
	....,
    primary key(字段名1)
);
或
create table 【數據名.】表名(
    字段名1 數據類型,
    字段名2 數據類型,
	....,
    primary key(複合主鍵字段列表)#如果是複合主鍵,那麼就需要在所有字段列表後面使用這種形式指定,不能在字段後面直接加primary key
);
mysql> use test;
Database changed
mysql> show tables;
Empty set (0.00 sec)

mysql> create table test.t_stu(
    ->  sid int primary key,
    ->  sname varchar(20),
    ->  gender char
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> desc t_stu;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| sid    | int(11)     | NO   | PRI | NULL    |       |
| sname  | varchar(20) | YES  |     | NULL    |       |
| gender | char(1)     | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql>
mysql> desc t_stu;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| sid    | int(11)     | NO   | PRI | NULL    |       |
| sname  | varchar(20) | YES  |     | NULL    |       |
| gender | char(1)     | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> insert into t_stu values(1,'張三','男'),(1,'徐有容','女');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> insert into t_stu values(1,'張三','男'),(2,'徐有容','女');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql>

sid相同 違反了主鍵約束

insert into t_stu values(1,'張三','男'),(1,'李四','女');#錯誤的

mysql> insert into t_stu values(1,'張三','男'),(1,'李四','女');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'  違反了主鍵約束

insert into t_stu values(1,'張三','男'),(2,'李四','女');

(2)如何在建表後指定主鍵約束

alter table 表名稱 add primary key (主鍵字段列表);
建表後如何指定主鍵約束
alter table 【數據庫名.】表名稱 add primary key(字段列表);

create table test.t_stu(
	sid int,
	sname varchar(20),
	gender char
);
alter table test.t_stu add primary key(sid);

(3)如何刪除主鍵約束

alter table 表名稱 drop primary key;

(4)主鍵約束分爲兩種:

(1)單列主鍵約束
(2)複合主鍵約束
建表時如何指定複合主鍵約束:

create table 【數據庫名.】表名稱(
	字段名1 數據類型,
	字段名2 數據類型,
	。。。。,
	primary key(字段列表)
);
建表後如何指定複合主鍵約束:
alter table 【數據庫名.】表名稱 add primary key(字段列表);

create table t_course(
	cid int primary key,
	cname varchar(20)
);

#現在要求sid和cid的組合是主鍵,是唯一的
create table xuanke(
	sid int,
	cid int,
	score int,
	primary key(sid,cid)
);

4、唯一鍵約束:unique key

(1)唯一鍵約束特點

同一個表可以有多個唯一約束。

唯一約束可以是某一個列的值唯一,也可以多個列組合值的唯一。

MySQL會給唯一約束的列上默認創建一個唯一索引。

刪除唯一鍵只能通過刪除對應索引的方式刪除,刪除時需要指定唯一鍵索引名

(2)如何在建表時指定唯一鍵約束

create table 【數據名.】表名(
	字段名1 數據類型  primary key ,
	字段名2 數據類型 unique key,
	....
);

create table 【數據名.】表名(
    字段名1 數據類型  primary key ,
    字段名2 數據類型,
    字段名3 數據類型,
	....,
    unique key(複合唯一字段列表)#如果是複合唯一鍵,那麼就需要在所有字段列表後面使用這種形式指定,不能在字段後面直接加unique key
);
create table books(
	bid int primary key,
	bname varchar(20) unique key,
	price double
);

insert into books values
(1,'《從入門到放棄》',100),
(2,'《從入門到放棄》',88);
ERROR 1062 (23000): Duplicate entry '《從入門到放棄》' for key 'bname' 

insert into books values
(1,'《從入門到放棄》',100),
(2,'《從入門到成功》',88);

(3)如何在建表後增加唯一鍵約束

alter table 表名稱 add 【constraint 約束名】 unique 【key】 (字段名列表);
#如果沒有指定約束名,(字段名列表)中只有一個字段的,默認是該字段名,如果是多個字段的默認是字段名列表的第1個字段名。也可以通過show index from 表名;來查看
create table books(
	bid int primary key,
	bname varchar(20) ,
	price double
);
alter table books add unique key(bname);

(4)如何刪除唯一鍵約束

ALTER TABLE 表名稱 DROP INDEX 唯一性約束名;
#注意:如果忘記名稱,可以通過“show index from 表名稱;”查看
5、刪除唯一鍵約束
alter table 【數據庫名.】表名稱 drop index 索引名;

alter table books drop index bname;

6、如何查看某個表格的索引名
show index from 【數據庫名.】表名稱;

show index from books;

5、外鍵約束:foreign key

(1)外鍵特點

  • 外鍵約束是保證一個或兩個表之間的參照完整性,外鍵是構建於一個表的兩個字段或是兩個表的兩個字段之間的參照關係。
  • 在創建外鍵約束時,如果不給外鍵約束名稱,默認名不是列名,而是自動產生一個外鍵名(例如 student_ibfk_1;),也可以指定外鍵約束名。
  • 當創建外鍵約束時,系統默認會在所在的列上建立對應的普通索引。但是索引名是列名,不是外鍵的約束名。
  • 刪除外鍵時,關於外鍵列上的普通索引需要單獨刪除。

建表時,先建主表,再建從表。
刪表時,先刪從表,再刪主表。

從表、子表:參考別人的,依賴別人的
主表、父表:被參考的,被依賴的

舉例:
(1)部門表和員工表
員工表中有一個字段,表示該員工所在的部門
部門表是主表
員工表是從表,說員工選擇進入哪個部門
這樣的話,外鍵建立在員工表
部門表中表示部門編號,用did表示,int類型
員工表中表示該員工所在的部門,我用編號表示,可以使用did,也可以使用deptid int類型

(2)學生表,課程表,選課表
主表:學生表和課程表
從表:選課表,這個表有兩個外鍵,一個參考學生表,一個參考課程表

(2)要求

  • 在從表上建立外鍵,而且主表要先存在。

  • 一個表可以建立多個外鍵約束

  • 從表的外鍵列,在主表中引用的只能是鍵列(主鍵,唯一鍵,外鍵),推薦引用主表的主鍵。

  • 從表的外鍵列與主表被參照的列名字可以不相同,但是數據類型必須一樣

(3)約束關係:約束是針對雙方的

添加了外鍵約束後,主表的修改和刪除受約束

添加了外鍵約束後,從表的添加和修改受約束

(4)5個約束等級

  • Cascade方式:在父表上update/delete記錄時,同步update/delete掉子表的匹配記錄

  • Set null方式:在父表上update/delete記錄時,將子表上匹配記錄的列設爲null,但是要注意子表的外鍵列不能爲not null

  • No action方式:如果子表中有匹配的記錄,則不允許對父表對應候選鍵進行update/delete操作

  • Restrict方式:同no action, 都是立即檢查外鍵約束

  • Set default方式(在可視化工具SQLyog中可能顯示空白):父表有變更時,子表將外鍵列設置成一個默認的值,但Innodb不能識別

如果沒有指定等級,就相當於Restrict方式

(5)如何在建表時指定外鍵約束

create table 【數據名.】從表名(
	字段名1 數據類型  primary key ,
	字段名2 數據類型 【unique key】,
	....,
    【constraint 外鍵約束名】 foreign key (從表字段) references 主表名(主表字段) 【on update 外鍵約束等級】【on delete 外鍵約束等級【
    #外鍵只能在所有字段列表後面單獨指定
    #如果要自己命名外鍵約束名,建議 主表名_從表名_關聯字段名_fk
);

create table 【數據名.】表名(
    字段名1 數據類型,
    字段名2 數據類型,
	....,
    primary key(複合主鍵字段列表),#如果是複合主鍵,那麼就需要在所有字段列表後面使用這種形式指定,不能在字段後面直接加primary key
    unique key(複合唯一字段列表),#如果是複合唯一鍵,那麼就需要在所有字段列表後面使用這種形式指定,不能在字段後面直接加unique key
    foreign key (從表字段) references 主表名(主表字段) 【on update 外鍵約束等級】【on delete 外鍵約束等級【
    #外鍵只能在所有字段列表後面單獨指定
);

(6)如何在建表後指定外鍵約束

alter table表名稱 add 【constraint 外鍵約束名】 foreign key (從表字段名) references 主表名(主表被參照字段名) 【on update xx】[on delete xx];

(7)如何刪除外鍵約束

ALTER TABLE 表名稱 DROP FOREIGN KEY 外鍵約束名;
#查看約束名 SELECT * FROM information_schema.table_constraints WHERE table_name = '表名稱';
#刪除外鍵約束不會刪除對應的索引,如果需要刪除索引,需要用ALTER TABLE 表名稱 DROP INDEX 索引名;
#查看索引名 show index from 表名稱;

6、非空約束:not null

NOT NULL 非空約束,規定某個字段不能爲空

(1)如何在建表時給某個字段指定非空約束

create table 【數據名.】表名(
	字段名1 數據類型  primary key ,
	字段名2 數據類型 【unique key】 【not null】,
	....,
    foreign key (從表字段) references 主表名(主表字段) 【on update 外鍵約束等級】【on delete 外鍵約束等級【
    #外鍵只能在所有字段列表後面單獨指定
);

create table 【數據名.】表名(
    字段名1 數據類型 【not null】,
    字段名2 數據類型 【not null】,
	....,
    primary key(複合主鍵字段列表),#如果是複合主鍵,那麼就需要在所有字段列表後面使用這種形式指定,不能在字段後面直接加primary key
    unique key(複合唯一字段列表),#如果是複合唯一鍵,那麼就需要在所有字段列表後面使用這種形式指定,不能在字段後面直接加unique key
    foreign key (從表字段) references 主表名(主表字段) 【on update 外鍵約束等級】【on delete 外鍵約束等級【
    #外鍵只能在所有字段列表後面單獨指定
);

(2)如何在建表後指定某個字段非空

ALTER TABLE 表名稱 MODIFY 字段名 數據類型 NOT NULL 【default 默認值】;
#如果該字段原來設置了默認值約束,要跟着一起再寫一遍,否則默認值約束會丟失

(3)如何在建表後取消某個字段非空

ALTER TABLE 表名稱 MODIFY 字段名 數據類型 【default 默認值】;
#如果該字段原來設置了默認值約束,要跟着一起再寫一遍,否則默認值約束會丟失

7、默認值約束:default

(1)如何在建表時給某個字段指定默認約束

create table 【數據名.】表名(
	字段名1 數據類型  primary key ,
	字段名2 數據類型 【unique key】 【not null】 【default 默認值】,
	....,
    foreign key (從表字段) references 主表名(主表字段) 【on update 外鍵約束等級】【on delete 外鍵約束等級【
    #外鍵只能在所有字段列表後面單獨指定
);

create table 【數據名.】表名(
    字段名1 數據類型 【not null】 【default 默認值】,
    字段名2 數據類型 【not null】 【default 默認值】,
	....,
    primary key(複合主鍵字段列表),#如果是複合主鍵,那麼就需要在所有字段列表後面使用這種形式指定,不能在字段後面直接加primary key
    unique key(複合唯一字段列表),#如果是複合唯一鍵,那麼就需要在所有字段列表後面使用這種形式指定,不能在字段後面直接加unique key
    foreign key (從表字段) references 主表名(主表字段) 【on update 外鍵約束等級】【on delete 外鍵約束等級【
    #外鍵只能在所有字段列表後面單獨指定
);

(2)如何在建表後指定某個字段的默認值約束

ALTER TABLE 表名稱 MODIFY 字段名 數據類型  【default 默認值】 【NOT NULL】;
#如果該字段原來設置了非空約束,要跟着一起再寫一遍,否則非空約束會丟失

(3)如何在建表後取消某個字段的默認值約束

ALTER TABLE 表名稱 MODIFY 字段名 數據類型 【NOT NULL】;
#如果該字段原來設置了非空約束,要跟着一起再寫一遍,否則非空約束會丟失

8、檢查約束:check

檢查約束,mysql暫不支持

在oracle或sql server中使用

1、檢查約束:check
但是mysql暫不支持
在oracle或sql server中使用

create table t_stu(
	sid int primary key,
	sname varchar(20),
	gender char check('男' or '女')
);

insert into t_stu values(1,'張三','男');

insert into t_stu values(2,'李四','妖');

9、自增約束:auto_increment

(1)關於自增長auto_increment:

  • 一個表最多隻能有一個自增長列
  • 自增長列必須是鍵列(主鍵列,唯一鍵列,外鍵列),並且要求非空。
  • 自增列必須是整數類型
  • InnoDB表的自動增長列可以手動插入,但是插入的值如果是空或者0,則實際插入的將是自動增長後的值。

(2)如何在建表時指定自增長列

create table 【數據名.】表名(
	字段名1 數據類型  primary key auto_increment,
	字段名2 數據類型 【unique key】 【not null】 【default 默認值】,
	....
);

或
create table 【數據名.】表名(
	字段名1 數據類型  primary key ,
	字段名2 數據類型 【unique key  not null】 auto_increment,
	....
);

(3)如何在建表後指定自增長列

alter table 【數據名.】表名 modify 自增字段名 數據類型 auto_increment;

(4)如何刪除自增約束

alter table 【數據名.】表名 modify 自增字段名 數據類型;

DML

1、如果某列有自增約束,怎麼添加該字段的值

添加數據時,對於自增列

insert into 【數據庫名.]表名稱 values(值列表);#在值列表中,對應自增列可以賦值爲null和0

insert into 【數據庫名.]表名稱(部分字段列表) values(值列表);#自增列在(部分字段列表)中不寫就可以

2、如果某列有默認值約束,怎麼添加、修改該字段的值

添加數據時,對於有默認值列

insert into 【數據庫名.]表名稱 values(值列表);#在值列表中,對應默認值列,如果想用默認值,用default

insert into 【數據庫名.]表名稱(部分字段列表) values(值列表);#對應默認值列,如果想用默認值,在(部分字段列表)中不寫就可以

修改數據

update 【數據庫名.]表名稱 set 字段名1 = 值1, 字段名2 = 值2 。。。 【where 條件】; #對應默認值列,如果想用默認值,寫字段名 = default就可以
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章