约束条件与数据类型的宽度同样,都是可选参数mysql
做用:用于保证数据的完整性和一致性
主要分为:nginx
PRIMARY KEY (PK) 标识该字段为该表的主键,能够惟一的标识记录 FOREIGN KEY (FK) 标识该字段为该表的外键 NOT NULL 标识该字段不能为空 UNIQUE KEY (UK) 标识该字段的值是惟一的 AUTO_INCREMENT 标识该字段的值自动增加(整数类型,并且为主键) DEFAULT 为该字段设置默认值 UNSIGNED 无符号 ZEROFILL 使用0填充
说明:sql
1. 是否容许为空,默认NULL,可设置NOT NULL,字段不容许为空,必须赋值
session
2. 字段是否有默认值,缺省的默认值是NULL,若是插入记录时不给字段赋值,此字段使用默认值
cors
sex enum('male','female') not null default 'male'
ide
age int unsigned NOT NULL default 20 必须为正值(无符号) 不容许为空 默认是20
sqlserver
3. 是不是key
编码
主键 primary key
url
外键 foreign key
spa
索引 (index,unique...)
是否可空,null表示空,非字符串
not null - 不可空
null - 可空
默认值,建立列时能够指定默认值,当插入数据时若是未主动设置,则自动添加默认值
create table tb1(
nid int not null defalut 2,
num int not null
)
==================not null==================== mysql> create table t1(id int); #id字段默承认以插入空 mysql> desc t1; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | +-------+---------+------+-----+---------+-------+ mysql> insert into t1 values(); #能够插入空 mysql> create table t2(id int not null); #设置字段id不为空 mysql> desc t2; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | id | int(11) | NO | | NULL | | +-------+---------+------+-----+---------+-------+ mysql> insert into t2 values(); #不能插入空 ERROR 1364 (HY000): Field 'id' doesn't have a default value ==================default==================== #设置id字段有默认值后,则不管id字段是null仍是not null,均可以插入空,插入空默认填入default指定的默认值 mysql> create table t3(id int default 1); mysql> alter table t3 modify id int not null default 1;
mysql> create table t15( -> id int(11) unsigned zerofill # id为字段,必须为字段指定数据类型(int);在数据条件下添加约束条件:unsigned限制id只 能传入无符号 -> ); Query OK, 0 rows affected (0.01 sec) mysql> desc t15 -> ; +-------+---------------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------------------------+------+-----+---------+-------+ | id | int(11) unsigned zerofill | YES | | NULL | | +-------+---------------------------+------+-----+---------+-------+ 1 row in set (0.00 sec) # not null 不能为空,default设置默认值 mysql> create table t16( -> id int, -> name char(6), -> sex enum('male', 'female') not null default 'male' # 不能为空,传空就用默认值'male' -> ); Query OK, 0 rows affected (0.01 sec) mysql> desc t16; +-------+-----------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-----------------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | char(6) | YES | | NULL | | | sex | enum('male','female') | NO | | male | | +-------+-----------------------+------+-----+---------+-------+ 3 rows in set (0.01 sec) mysql> insert into t16(id,name) values(1,'egon'); Query OK, 1 row affected (0.00 sec) mysql> select * from t16; +------+--------+------+ | id | name | sex | +------+--------+------+ | 1 | egon | male | +------+--------+------+ 1 row in set (0.00 sec)
unique key指的就是限制字段传入的值是惟一的,不能重复的。
# 建立部门表,且部门名称不设置unique,所以能够建立多个同名部门名称,这明显不合理 mysql> create table department( -> id int, -> name char(10) -> ); Query OK, 0 rows affected (0.01 sec) mysql> desc department; +-------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | char(10) | YES | | NULL | | +-------+----------+------+-----+---------+-------+ 2 rows in set (0.00 sec) mysql> insert into department values -> (1,'IT'), -> (2,'IT'); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from department; +------+------------+ | id | name | +------+------------+ | 1 | IT | | 2 | IT | +------+------------+ 2 rows in set (0.00 sec) # 设置惟一约束unique # 方式一: mysql> drop table department; Query OK, 0 rows affected (0.01 sec) mysql> create table department( -> id int, -> name char(10) unique -> ); Query OK, 0 rows affected (0.01 sec) mysql> desc department; +-------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | char(10) | YES | UNI | NULL | | +-------+----------+------+-----+---------+-------+ 2 rows in set (0.00 sec) mysql> insert into department values -> (1, 'IT'), -> (2, 'IT'); ERROR 1062 (23000): Duplicate entry 'IT ' for key 'name' # 方式二: mysql> drop table department; Query OK, 0 rows affected (0.01 sec) mysql> create table department( -> id int, -> name char(10), -> unique(id), -> unique(name) -> ); Query OK, 0 rows affected (0.01 sec) mysql> desc department; +-------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+-------+ | id | int(11) | YES | UNI | NULL | | | name | char(10) | YES | UNI | NULL | | +-------+----------+------+-----+---------+-------+ 2 rows in set (0.00 sec) mysql> insert into department values -> (1,'IT'), -> (2,'IT'); ERROR 1062 (23000): Duplicate entry 'IT ' for key 'name' mysql> insert into department values (1,'IT'), (2,'Sale'); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> selcet * from department; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'selcet * from department' at line 1 mysql> select * from department; +------+------------+ | id | name | +------+------------+ | 1 | IT | | 2 | Sale | +------+------------+ 2 rows in set (0.00 sec)
mysql> create table services( -> id int, -> ip char(15), -> port int, -> unique(id), # 单列惟一 -> unique(ip,port) # 联合惟一:ip+port惟一 -> ); Query OK, 0 rows affected (0.01 sec) mysql> desc services; +-------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+-------+ | id | int(11) | YES | UNI | NULL | | | ip | char(15) | YES | MUL | NULL | | | port | int(11) | YES | | NULL | | +-------+----------+------+-----+---------+-------+ 3 rows in set (0.00 sec) mysql> insert into services values -> (1,'192.168.1.101',80), -> (2,'192.168.1.101',88), -> (3,'192.168.1.103',80); Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from services; +------+-----------------+------+ | id | ip | port | +------+-----------------+------+ | 1 | 192.168.1.101 | 80 | | 2 | 192.168.1.101 | 88 | | 3 | 192.168.1.103 | 80 | +------+-----------------+------+ 3 rows in set (0.00 sec) mysql> insert into services values (4,'192.168.1.101',80); ERROR 1062 (23000): Duplicate entry '192.168.1.101 -80' for key 'ip'
从约束角度看primary key字段的值不为空且惟一(not null unique)。
那直接使用not null+unique不就能够了吗,要primary key干什么?
主键primary key是innodb存储引擎组织数据的依据(innodb称之为索引组织表,对于innodb存储引擎一张表中必须有且只有一个主键)。
一个表中能够:单列作主键、多列作主键(复合主键)
============单列作主键=============== #方法一:not null+unique mysql> create table department( -> id int not null unique, # 主键,一般设置id为主键 -> name varchar(20) not null unique, -> comment varchar(100) -> ); Query OK, 0 rows affected (0.01 sec) mysql> desc department; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | NO | UNI | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) #方法二:在某一个字段后用primary key mysql> create table department2( -> id int primary key, # 主键 -> name varchar(20), -> comment varchar(100) -> ); Query OK, 0 rows affected (0.01 sec) mysql> desc department2; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | YES | | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) # 方法三:在全部字段后单独定义primary key mysql> create table department3( -> id int, -> name varchar(20), -> comment varchar(100), -> constraint pk_name primary key(id) #建立主键并命名为pk_name -> ); Query OK, 0 rows affected (0.02 sec) mysql> desc department3; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | YES | | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ 3 rows in set (0.01 sec)
==================多列作主键================ mysql> create table service( -> ip varchar(15), -> port char(5), -> service_name varchar(10) not null, -> primary key(ip,port) # 多列主键 -> ); Query OK, 0 rows affected (0.01 sec) mysql> desc service; +--------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------+-------------+------+-----+---------+-------+ | ip | varchar(15) | NO | PRI | NULL | | | port | char(5) | NO | PRI | NULL | | | service_name | varchar(10) | NO | | NULL | | +--------------+-------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) mysql> insert into service values -> ('172.16.45.10', '3306', 'mysqld'), -> ('172.16.45.11', '3306', 'mariadb') -> ; Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from service; +--------------+-------+--------------+ | ip | port | service_name | +--------------+-------+--------------+ | 172.16.45.10 | 3306 | mysqld | | 172.16.45.11 | 3306 | mariadb | +--------------+-------+--------------+ 2 rows in set (0.00 sec) mysql> insert into service values ('172.16.45.10', '3306', 'nginx'); ERROR 1062 (23000): Duplicate entry '172.16.45.10-3306 ' for key 'PRIMARY'
总结:只要用的表类型是innodb(最经常使用),就应该为表指定一个主键,且通常都是指定为id字段。
约束字段为自动增加,被约束的字段必须同时被key约束。
mysql> create table t19( -> id int auto_increment -> ); ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key # 自增加必须是一个key,如今学到的key分为两种:unique\primary mysql> create table t19( -> id int unique key auto_increment -> ); Query OK, 0 rows affected (0.02 sec) mysql> desc t19; +-------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | +-------+---------+------+-----+---------+----------------+ 1 row in set (0.00 sec)
#不指定id,则自动增加 mysql> create table student( -> id int primary key auto_increment, -> name varchar(20), -> sex enum('male','female') default 'male' -> ); Query OK, 0 rows affected (0.01 sec) mysql> desc student; +-------+-----------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-----------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(20) | YES | | NULL | | | sex | enum('male','female') | YES | | male | | +-------+-----------------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec) mysql> insert into student(name) values -> ('hqs') -> ,('aelx'), -> ('egon') -> ; Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from student; +----+------+------+ | id | name | sex | +----+------+------+ | 1 | hqs | male | | 2 | aelx | male | | 3 | egon | male | +----+------+------+ 3 rows in set (0.00 sec) # 指定id插入 mysql> insert into student values -> (5, 'asb', 'female'); Query OK, 1 row affected (0.01 sec) mysql> insert into student values -> (12, 'zr', 'female'); Query OK, 1 row affected (0.00 sec) mysql> select * from student; +----+------+--------+ | id | name | sex | +----+------+--------+ | 1 | hqs | male | | 2 | aelx | male | | 3 | egon | male | | 5 | asb | female | | 12 | zr | female | +----+------+--------+ 5 rows in set (0.00 sec)
注意:插入指定id的记录后,再插入不指定id记录时,新记录按照最后一条记录的id编码继续日后编排。
mysql> show variables like 'auto_inc%'; # %表明任意个数任意字符 +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | auto_increment_increment | 1 | # 查到步长,且默认为1 | auto_increment_offset | 1 | # 查到起始偏移量。且默认也为1 +--------------------------+-------+ 2 rows in set (0.02 sec)
设置步长
set session auto_increment_increment=5; # session关键词,说明这个步长修改是会话级别的,只在本次连接有效
set global auto_increment_increment=5; # 修改全局级别的步长,全部会话须要退出后从新链接才生效
#设置步长 sqlserver:自增步长 基于表级别 create table t1( id int。。。 )engine=innodb,auto_increment=2 步长=2 default charset=utf8 mysql自增的步长: show session variables like 'auto_inc%'; #基于会话级别 set session auth_increment_increment=2 #修改会话级别的步长 #基于全局级别的 set global auth_increment_increment=2 #修改全局级别的步长(全部会话都生效) #!!!注意了注意了注意了!!! If the value of auto_increment_offset is greater than that of auto_increment_increment, the value of auto_increment_offset is ignored. 翻译:若是auto_increment_offset的值大于auto_increment_increment的值,则auto_increment_offset的值会被忽略 好比:设置auto_increment_offset=3,auto_increment_increment=2
设置起始偏移量
set global auto_increment_offset=6; # 设置失效,注意:起始偏移量必须小于等于步长
#在建立完表后,修改自增字段的起始值 mysql> create table student( -> id int primary key auto_increment, -> name varchar(20), -> sex enum('male','female') default 'male' -> ); mysql> alter table student auto_increment=3; mysql> show create table student; ....... ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 mysql> insert into student(name) values('egon'); Query OK, 1 row affected (0.01 sec) mysql> select * from student; +----+------+------+ | id | name | sex | +----+------+------+ | 3 | egon | male | +----+------+------+ row in set (0.00 sec) mysql> show create table student; ....... ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 #也能够建立表时指定auto_increment的初始值,注意初始值的设置为表选项,应该放到括号外 create table student( id int primary key auto_increment, name varchar(20), sex enum('male','female') default 'male' )auto_increment=3;
mysql> show variables like 'auto_incre%'; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | auto_increment_increment | 1 | | auto_increment_offset | 1 | +--------------------------+-------+ 2 rows in set (0.01 sec) mysql> set global auto_increment_increment=5; # 修改步长 Query OK, 0 rows affected (0.00 sec) mysql> set global auto_increment_offset=3; # 修改起始便宜量 Query OK, 0 rows affected (0.00 sec) mysql> exit # 全局修改后须要退出当前会话 Bye sh-3.2# mysql -uroot -p1234 mysql> show variables like 'auto_in%'; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | auto_increment_increment | 5 | | auto_increment_offset | 3 | +--------------------------+-------+ 2 rows in set (0.00 sec) mysql> use db4 Database changed mysql> create table student1( -> id int primary key auto_increment, -> name varchar(20), -> sex enum('male', 'female') default 'male' -> ); Query OK, 0 rows affected (0.01 sec) mysql> insert into student1 -> \c mysql> insert into student1(name) values -> ('egon'), -> ('alex'), -> ('hqs'); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from student1; +----+------+------+ | id | name | sex | +----+------+------+ | 3 | egon | male | | 8 | alex | male | | 13 | hqs | male | +----+------+------+ 3 rows in set (0.00 sec)
方法一:delete from 表名; ——存在的问题:对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增加
。
delete更适用于局部记录的删除:delete from t20 where id=3;
方法二:truncate 表名; ——truncate清空表,不一样于delete一条一条删除,是直接清空表,删除大表时推荐使用。
mysql> set global auto_increment_increment=1; Query OK, 0 rows affected (0.00 sec) mysql> set global auto_increment_offset=1; Query OK, 0 rows affected (0.00 sec) mysql> exit sh-3.2# mysql -uroot -p1234 # 从新登陆,使得新的步长和起始偏移量生效 mysql> select * from student1; +----+------+------+ | id | name | sex | +----+------+------+ | 3 | egon | male | | 8 | alex | male | | 13 | hqs | male | +----+------+------+ 3 rows in set (0.00 sec) mysql> delete from student1; Query OK, 3 rows affected (0.01 sec) mysql> select * from student1; Empty set (0.00 sec) mysql> insert into student1(name) values -> ('asd'); Query OK, 1 row affected (0.00 sec) mysql> select * from student1; +----+------+------+ | id | name | sex | +----+------+------+ | 18 | asd | male | +----+------+------+ 1 row in set (0.00 sec) mysql> show create table student1; +----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | student1 | CREATE TABLE `student1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `sex` enum('male','female') DEFAULT 'male', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 | # 能够看到偏移量仍是根据以前的id顺延 +----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) # 应该用truncate清空表,比起delete一条一条地删除记录,truncate是直接清空表,在删除大表时用它 mysql> truncate student1; Query OK, 0 rows affected (0.02 sec) mysql> show create table student1; +----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | student1 | CREATE TABLE `student1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `sex` enum('male','female') DEFAULT 'male', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | +----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.01 sec) mysql> insert into student1(name) values ('egon'), ('alex'); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from student1; +----+------+------+ | id | name | sex | +----+------+------+ | 1 | egon | male | # 能够看到已经不依照创表前设置的步长和起始偏移量,按照系统当前的设置执行 | 2 | alex | male | +----+------+------+ 2 rows in set (0.00 sec)
foreign key:用来创建表之间的关系。
以一个公司的员工信息表为例,员工会有id,name,sex,department,comment等字段。可是这样存储会在部门和部门描述上有大量字段重复存储,既浪费空间又不利于后期的维护管理(部门调整或部门更名等)。所以能够把部门和部门相关信息分拆出来,做为部门表。此时部门和员工信息表分开,二者之间彻底独立。须要用外键实现两张表关联。
# 1、创建表关系 # 建立失败,由于须要先建立被关联的表 mysql> create table emp( ->id int primary key, ->name char(10), ->sex enum('male', 'female'), ->dep_id int, ->foreign key(dep_id) references dep(id) ->); ERROR 1215 (HY000): Cannot add foreign key constraint # 先建被关联的表,并保证被关联的字段惟一 mysql> create table dep( -> id int primary key, # 或者使用unique,必须保证要关联的字段是唯一的,才能建立关联表 -> name char(16), -> comment char(50) -> ); Query OK, 0 rows affected (0.01 sec) mysql> desc dep; +---------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+----------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | char(16) | YES | | NULL | | | comment | char(50) | YES | | NULL | | +---------+----------+------+-----+---------+-------+ 3 rows in set (0.00 sec) # 再建关联的表 mysql> create table emp( -> id int primary key, -> name char(10), -> sex enum('male', 'female'), -> dep_id int, -> foreign key(dep_id) references dep(id) -> ); Query OK, 0 rows affected (0.01 sec) mysql> desc emp; +--------+-----------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-----------------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | char(10) | YES | | NULL | | | sex | enum('male','female') | YES | | NULL | | | dep_id | int(11) | YES | MUL | NULL | | +--------+-----------------------+------+-----+---------+-------+ 4 rows in set (0.00 sec) # 2、插入数据 # 直接往员工表插入数据,没法插入记录,由于dep_id不能随便写入,必须是被关联内已经具有的数值 mysql> insert into emp values -> (1, 'egon', 'male', '1'); ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`db1`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`dep_id`) REFERENCES `dep` (`id`)) # 先往被关联表(dep)插入记录 mysql> insert into dep values -> (1,'IT','技术能力有限部门'), -> (2,'销售','销售能力有限部门'), -> (3,'财务','花钱特别多部门'); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from dep; +----+--------+--------------------------+ | id | name | comment | +----+--------+--------------------------+ | 1 | IT | 技术能力有限部门 | | 2 | 销售 | 销售能力有限部门 | | 3 | 财务 | 花钱特别多部门 | +----+--------+--------------------------+ 3 rows in set (0.00 sec) # 再往关联表插入记录 mysql> insert into emp values -> (1, 'egon', 'male', 1), -> (2, 'alex', 'male', 1), -> (3, 'wupeiqi', 'male', 2), -> (4, 'yuanhao', 'male', 3), -> (5, 'jinxin', 'male',2); Query OK, 5 rows affected (0.00 sec) Records: 5 Duplicates: 0 Warnings: 0 mysql> select * from emp; +----+---------+------+--------+ | id | name | sex | dep_id | +----+---------+------+--------+ | 1 | egon | male | 1 | | 2 | alex | male | 1 | | 3 | wupeiqi | male | 2 | | 4 | yuanhao | male | 3 | | 5 | jinxin | male | 2 | +----+---------+------+--------+ 5 rows in set (0.00 sec) # 3、删除数据 # 要删除某个部分,须要先删除子表对应的记录 mysql> delete from emp where dep_id=1; Query OK, 2 rows affected (0.01 sec) mysql> select * from emp; +----+---------+------+--------+ | id | name | sex | dep_id | +----+---------+------+--------+ | 3 | wupeiqi | male | 2 | | 4 | yuanhao | male | 3 | | 5 | jinxin | male | 2 | +----+---------+------+--------+ 3 rows in set (0.00 sec) mysql> delete from dep where id=1; Query OK, 1 row affected (0.00 sec) mysql> select * from dep; +----+--------+--------------------------+ | id | name | comment | +----+--------+--------------------------+ | 2 | 销售 | 销售能力有限部门 | | 3 | 财务 | 花钱特别多部门 | +----+--------+--------------------------+ 2 rows in set (0.00 sec) # 直线先删除父表直接报错 mysql> delete from dep where id=3; ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`db1`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`dep_id`) REFERENCES `dep` (`id`))
上面这种关联关系虽然创建了,可是数据的维护管理其实仍是很是繁复。要实现删除(更新)父表,子表对应记录也自动删除(更新),须要在建立关联子表的时候,设置同步删除,同步更新。
create table emp( id int primary key, name char(10), sex enum('male', 'female'), dep_id int, foreign key(dep_id) references dep(id) on delete cascade # 同步删除 on update cascade # 同步更新 );
# 删除全部表 mysql> drop table dep; ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails mysql> drop table emp; Query OK, 0 rows affected (0.01 sec) mysql> drop table dep; Query OK, 0 rows affected (0.00 sec) # 建立被关联的表,且被关联的字段惟一 mysql> create table dep( -> id int primary key, -> name char(16), -> comment char(50) -> ); Query OK, 0 rows affected (0.01 sec) # 再建立关联的表 mysql> create table emp( -> id int primary key, -> name char(10), -> sex enum('male', 'female'), -> dep_id int, -> foreign key(dep_id) references dep(id) -> on delete cascade -> on update cascade -> ); Query OK, 0 rows affected (0.01 sec) # 插入数据 mysql> insert into dep values -> (1,'IT','技术能力有限部门'), -> (2,'销售','销售能力有限部门'), -> (3,'财务','花钱特别多部门'); Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> insert into emp values -> (1,'egon','male',1), -> (2,'alex','male',1), -> (3,'wupeiqi','female',2), -> (4,'yuanhao','male',3), -> (5,'jinxin','male',2); Query OK, 5 rows affected (0.01 sec) Records: 5 Duplicates: 0 Warnings: 0 mysql> select * from dep; +----+--------+--------------------------+ | id | name | comment | +----+--------+--------------------------+ | 1 | IT | 技术能力有限部门 | | 2 | 销售 | 销售能力有限部门 | | 3 | 财务 | 花钱特别多部门 | +----+--------+--------------------------+ 3 rows in set (0.00 sec) mysql> select * from emp; +----+---------+--------+--------+ | id | name | sex | dep_id | +----+---------+--------+--------+ | 1 | egon | male | 1 | | 2 | alex | male | 1 | | 3 | wupeiqi | female | 2 | | 4 | yuanhao | male | 3 | | 5 | jinxin | male | 2 | +----+---------+--------+--------+ 5 rows in set (0.00 sec) # 删除父表,子表emp中对应记录跟着删除 mysql> delete from dep where id=2; Query OK, 1 row affected (0.00 sec) mysql> select * from dep; +----+--------+--------------------------+ | id | name | comment | +----+--------+--------------------------+ | 1 | IT | 技术能力有限部门 | | 3 | 财务 | 花钱特别多部门 | +----+--------+--------------------------+ 2 rows in set (0.00 sec) mysql> select * from emp; +----+---------+------+--------+ | id | name | sex | dep_id | +----+---------+------+--------+ | 1 | egon | male | 1 | | 2 | alex | male | 1 | | 4 | yuanhao | male | 3 | +----+---------+------+--------+ 3 rows in set (0.00 sec) # 更新父表,子表emp中的对应记录跟着修改 mysql> update dep set id=202 where id=1; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from dep; +-----+--------+--------------------------+ | id | name | comment | +-----+--------+--------------------------+ | 3 | 财务 | 花钱特别多部门 | | 202 | IT | 技术能力有限部门 | +-----+--------+--------------------------+ 2 rows in set (0.00 sec) mysql> select * from emp; +----+---------+------+--------+ | id | name | sex | dep_id | +----+---------+------+--------+ | 1 | egon | male | 202 | | 2 | alex | male | 202 | | 4 | yuanhao | male | 3 | +----+---------+------+--------+ 3 rows in set (0.00 sec)
可是在实际运用中,最好不要经过foreign key直接创建表的耦合关系,考虑程序的扩展性来讲,最好是从应用程序里,作两个表的映射关系,两个表只是有逻辑关系。
分析步骤:
(1)先站在左表的角度去找——是否左表的多条记录能够对应右表的一条记录,若是是,则证实左表的一个字段foreign key右表一个字段(一般是id)。
(2)再站在右表的角度去找——是否右表的多条记录能够对应左表的一条记录,若是是,则证实右表的一个字段foreign key左表一个字段(一般是id)。
总结:
多对一:若是只有步骤1成立,则是左表多对一右表
若是只有步骤2成立,则是右表多对一左表
多对多:若是步骤1和步骤2同时成立,证实这两张表示一个双向的多对一,即多对多。须要定义一个这两张表的关系来专门存放两者的关系。
一对一:若是1和2都不成立,而是左表的一条记录惟一对应右表的一条记录,反之亦然。这种状况很简单,就是在左表foreign key右表的基础上,将左表的外键字段设置成unique便可。
#一对多或称为多对一 三张表:出版社,做者信息,书 一对多(或多对一):一个出版社能够出版多本书 关联方式:foreign key
mysql> create table press( -> id int primary key auto_increment, -> name varchar(20) -> ); Query OK, 0 rows affected (0.01 sec) mysql> create table book( -> id int primary key auto_increment, -> name varchar(20), -> press_id int not null, -> foreign key(press_id) references press(id) -> on delete cascade -> on update cascade -> ); Query OK, 0 rows affected (0.01 sec) mysql> insert into press(name) values -> ('北京工业地雷出版社'), -> ('人民音乐很差听出版社'), -> ('知识产权没有用出版社') -> ; Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> insert into book(name,press_id) values -> ('九阳神功',1), -> ('九阴真经',2), -> ('九阴白骨爪',2), -> ('独孤九剑',3), -> ('降龙十巴掌',2), -> ('葵花宝典',3) -> ; Query OK, 6 rows affected (0.00 sec) Records: 6 Duplicates: 0 Warnings: 0 mysql> select * from press; +----+--------------------------------+ | id | name | +----+--------------------------------+ | 1 | 北京工业地雷出版社 | | 2 | 人民音乐很差听出版社 | | 3 | 知识产权没有用出版社 | +----+--------------------------------+ 3 rows in set (0.00 sec) mysql> select * from book; +----+-----------------+----------+ | id | name | press_id | +----+-----------------+----------+ | 1 | 九阳神功 | 1 | | 2 | 九阴真经 | 2 | | 3 | 九阴白骨爪 | 2 | | 4 | 独孤九剑 | 3 | | 5 | 降龙十巴掌 | 2 | | 6 | 葵花宝典 | 3 | +----+-----------------+----------+ 6 rows in set (0.00 sec)
#多对多 三张表:出版社,做者信息,书 多对多:一个做者能够写多本书,一本书也能够有多个做者,双向的一对多,即多对多 关联方式:foreign key+一张新的表
多对多的状况下,没法像多对一同样,多设置一个对应字段并设置为外键。必须创一个存放二者关系的表,一个字段关联左表id,一个字段关联右表id,这样就解决了多对多的问题。
mysql> select * from book; +----+-----------------+----------+ | id | name | press_id | +----+-----------------+----------+ | 1 | 九阳神功 | 1 | | 2 | 九阴真经 | 2 | | 3 | 九阴白骨爪 | 2 | | 4 | 独孤九剑 | 3 | | 5 | 降龙十巴掌 | 2 | | 6 | 葵花宝典 | 3 | +----+-----------------+----------+ 6 rows in set (0.00 sec) mysql> mysql> mysql> mysql> mysql> create table author( -> id int primary key auto_increment, -> name varchar(20) -> ); Query OK, 0 rows affected (0.02 sec) #这张表就存放做者表与书表的关系,即查询两者的关系查这表就能够了 mysql> create table author2book( -> id int not null unique auto_increment, -> author_id int not null, -> book_id int not null, -> constraint fk_author foreign key(author_id) references author(id) # constraint为外键取名fk_author -> on delete cascade -> on update cascade, -> constraint fk_book foreign key(book_id) references book(id) # book_id关联book表的id字段 -> on delete cascade -> on update cascade, -> primary key(author_id,book_id) -> ); Query OK, 0 rows affected (0.02 sec) #每一个做者与本身的表明做以下 1 egon: 1 九阳神功 2 九阴真经 3 九阴白骨爪 4 独孤九剑 5 降龙十巴掌 6 葵花宝典 2 alex: 1 九阳神功 6 葵花宝典 3 yuanhao: 4 独孤九剑 5 降龙十巴掌 6 葵花宝典 4 wpq: 1 九阳神功 mysql> #插入四个做者,id依次排开 mysql> insert into author(name) values('egon'),('alex'),('yuanhao'),('wpq'); Query OK, 4 rows affected (0.01 sec) Records: 4 Duplicates: 0 Warnings: 0 # 写入做者、书籍对应关系 mysql> insert into author2book(author_id,book_id) values -> (1,1), -> (1,2), -> (1,3), -> (1,4), -> (1,5), -> (1,6), -> (2,1), # alex,九阳神功 -> (2,6), -> (3,4), # yuanhao,独孤九剑 -> (3,5), -> (3,6), -> (4,1); # wpq,九阳神功 Query OK, 12 rows affected (0.01 sec) Records: 12 Duplicates: 0 Warnings: 0 mysql> select * from author2book; +----+-----------+---------+ | id | author_id | book_id | +----+-----------+---------+ | 1 | 1 | 1 | | 2 | 1 | 2 | | 3 | 1 | 3 | | 4 | 1 | 4 | | 5 | 1 | 5 | | 6 | 1 | 6 | | 7 | 2 | 1 | | 8 | 2 | 6 | | 9 | 3 | 4 | | 10 | 3 | 5 | | 11 | 3 | 6 | | 12 | 4 | 1 | +----+-----------+---------+ 12 rows in set (0.00 sec)
#一对一 两张表:学生表和客户表 一对一:一个学生是一个客户,一个客户有可能变成一个学校,即一对一的关系 关联方式:foreign key+unique
分析学生和客户的关系,学生必定是一个客户,客户不是学生,但有可能成为一个学生。所以必须用student来foreign key 表customer。
# 先创建客户表,学生来自客户 mysql> create table customer( -> id int primary key auto_increment, -> name varchar(20) not null, -> qq varchar(10) not null, -> phone char(16) not null -> ); Query OK, 0 rows affected (0.01 sec) # 创建学生表 mysql> create table student( -> id int primary key auto_increment, # 学号 -> class_name varchar(20) not null, # 班级 -> customer_id int unique, # 该字段必定要是惟一的,加了unique则学生和客户一一对应 -> foreign key(customer_id) references customer(id) # 这张表的customer_id关联客户表的id字段 -> on delete cascade -> on update cascade -> ); Query OK, 0 rows affected (0.02 sec) # 增长客户 mysql> insert into customer(name,qq,phone) values ('李飞机','31811231',13811341220), ('王大炮','123123123',15213146809), -> ('李飞机','31811231',13811341220), -> ('王大炮','123123123',15213146809), -> ('守榴弹','283818181',1867141331), ('守榴弹','283818181',1867141331), -> ('吴坦克','283818181',1851143312), -> ('赢火箭','888818181',1861243314), -> ('战地雷','112312312',18811431230) -> ; Query OK, 6 rows affected (0.01 sec) Records: 6 Duplicates: 0 Warnings: 0 #增长学生 mysql> insert into student(class_name,customer_id) values -> ('脱产3班',3), -> ('周末19期',4), -> ('周末19期',5) -> ; Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from customer; +----+-----------+-----------+-------------+ | id | name | qq | phone | +----+-----------+-----------+-------------+ | 1 | 李飞机 | 31811231 | 13811341220 | | 2 | 王大炮 | 123123123 | 15213146809 | | 3 | 守榴弹 | 283818181 | 1867141331 | | 4 | 吴坦克 | 283818181 | 1851143312 | | 5 | 赢火箭 | 888818181 | 1861243314 | | 6 | 战地雷 | 112312312 | 18811431230 | +----+-----------+-----------+-------------+ 6 rows in set (0.00 sec) mysql> select * from student; +----+-------------+-------------+ | id | class_name | customer_id | +----+-------------+-------------+ | 1 | 脱产3班 | 3 | | 2 | 周末19期 | 4 | | 3 | 周末19期 | 5 | +----+-------------+-------------+ 3 rows in set (0.00 sec)
例一:一个用户只有一个博客 用户表: id name 1 egon 2 alex 3 wupeiqi 博客表 fk+unique id url name_id 1 xxxx 1 2 yyyy 3 3 zzz 2 例二:一个管理员惟一对应一个用户 用户表: id user password 1 egon xxxx 2 alex yyyy 管理员表: fk+unique id user_id password 1 1 xxxxx 2 2 yyyyy
练习:帐号信息表,用户组,主机表,主机组。
#用户表 create table user( id int not null unique auto_increment, username varchar(20) not null, password varchar(50) not null, primary key(username,password) ); insert into user(username,password) values ('root','123'), ('egon','456'), ('alex','alex3714') ; #用户组表 create table usergroup( id int primary key auto_increment, groupname varchar(20) not null unique ); insert into usergroup(groupname) values ('IT'), ('Sale'), ('Finance'), ('boss') ; #主机表 create table host( id int primary key auto_increment, ip char(15) not null unique default '127.0.0.1' ); insert into host(ip) values ('172.16.45.2'), ('172.16.31.10'), ('172.16.45.3'), ('172.16.31.11'), ('172.10.45.3'), ('172.10.45.4'), ('172.10.45.5'), ('192.168.1.20'), ('192.168.1.21'), ('192.168.1.22'), ('192.168.2.23'), ('192.168.2.223'), ('192.168.2.24'), ('192.168.3.22'), ('192.168.3.23'), ('192.168.3.24') ; #业务线表 create table business( id int primary key auto_increment, business varchar(20) not null unique ); insert into business(business) values ('轻松贷'), ('随便花'), ('大富翁'), ('穷一辈子') ; #建关系:user与usergroup create table user2usergroup( id int not null unique auto_increment, user_id int not null, group_id int not null, primary key(user_id,group_id), foreign key(user_id) references user(id), foreign key(group_id) references usergroup(id) ); insert into user2usergroup(user_id,group_id) values (1,1), (1,2), (1,3), (1,4), (2,3), (2,4), (3,4) ; #建关系:host与business create table host2business( id int not null unique auto_increment, host_id int not null, business_id int not null, primary key(host_id,business_id), foreign key(host_id) references host(id), foreign key(business_id) references business(id) ); insert into host2business(host_id,business_id) values (1,1), (1,2), (1,3), (2,2), (2,3), (3,4) ; #建关系:user与host create table user2host( id int not null unique auto_increment, user_id int not null, host_id int not null, primary key(user_id,host_id), foreign key(user_id) references user(id), foreign key(host_id) references host(id) ); insert into user2host(user_id,host_id) values (1,1), (1,2), (1,3), (1,4), (1,5), (1,6), (1,7), (1,8), (1,9), (1,10), (1,11), (1,12), (1,13), (1,14), (1,15), (1,16), (2,2), (2,3), (2,4), (2,5), (3,10), (3,11), (3,12) ;
# 建立用户表 mysql> create table user( -> id int not null unique auto_increment, # 用户的id非空、惟一且自增 -> username varchar(20) not null, -> password varchar(50) not null, -> primary key(username,password) # 复合主键:用户名+密码 -> ); Query OK, 0 rows affected (0.03 sec) # 插入用户数据 mysql> insert into user(username,password) values -> ('root', '123'), -> ('egon', '456'), -> ('alex', 'alex3714') -> ; Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from user; +----+----------+----------+ | id | username | password | +----+----------+----------+ | 1 | root | 123 | | 2 | egon | 456 | | 3 | alex | alex3714 | +----+----------+----------+ 3 rows in set (0.00 sec) # 建立用户组 mysql> create table usergroup( -> id int primary key auto_increment, # 用户组id设为主键,且自增 -> groupname varchar(20) not null unique # 用户组名非空且惟一 -> ); Query OK, 0 rows affected (0.03 sec) # 插入用户组数据 mysql> insert into usergroup(groupname) values -> ('IT'), -> ('Sale'), -> ('Finance'), -> ('boss') -> ; Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> select * from usergroup; +----+-----------+ | id | groupname | +----+-----------+ | 4 | boss | | 3 | Finance | | 1 | IT | | 2 | Sale | +----+-----------+ 4 rows in set (0.00 sec) # 建立主机表 mysql> create table host( -> id int primary key auto_increment, # 主机表id为主键、自增 -> ip char(15) not null unique default '127.0.0.1' # ip地址非空、惟1、设置了默认值 -> ); Query OK, 0 rows affected (0.02 sec) mysql> insert into host(ip) values -> ('172.16.45.2'), -> ('172.16.31.10'), -> ('172.16.45.3'), -> ('172.16.31.11'), -> ('172.10.45.3'), -> ('172.10.45.4'), -> ('172.10.45.5'), -> ('192.168.1.20'), -> ('192.168.1.21'), -> ('192.168.1.22'), -> ('192.168.2.23'), -> ('192.168.2.223'), -> ('192.168.2.24'), -> ('192.168.3.22'), -> ('192.168.3.23'), -> ('192.168.3.24') -> ; Query OK, 16 rows affected (0.00 sec) Records: 16 Duplicates: 0 Warnings: 0 mysql> select * from host; +----+---------------+ | id | ip | +----+---------------+ | 5 | 172.10.45.3 | | 6 | 172.10.45.4 | | 7 | 172.10.45.5 | | 2 | 172.16.31.10 | | 4 | 172.16.31.11 | | 1 | 172.16.45.2 | | 3 | 172.16.45.3 | | 8 | 192.168.1.20 | | 9 | 192.168.1.21 | | 10 | 192.168.1.22 | | 12 | 192.168.2.223 | | 11 | 192.168.2.23 | | 13 | 192.168.2.24 | | 14 | 192.168.3.22 | | 15 | 192.168.3.23 | | 16 | 192.168.3.24 | +----+---------------+ 16 rows in set (0.00 sec) # 建立业务表 mysql> create table business( -> id int primary key auto_increment, # 业务id为主键、自增 -> business varchar(20) not null unique # 业务非空、惟一 -> ); Query OK, 0 rows affected (0.02 sec) mysql> insert into business(business) values -> ('轻松贷'), -> ('随便花'), -> ('大富翁'), -> ('穷一辈子') -> ; Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> select * from business; +----+-----------+ | id | business | +----+-----------+ | 3 | 大富翁 | | 4 | 穷一辈子 | | 1 | 轻松贷 | | 2 | 随便花 | +----+-----------+ 4 rows in set (0.00 sec) # 建关系:user和usergroup 多对多 mysql> create table user2usergroup( -> id int not null unique auto_increment, -> user_id int not null, -> group_id int not null, -> primary key(user_id, group_id), # 指定并建立复合主键、约束为不为空且惟一 -> foreign key(user_id) references user(id), # user_id关联用户表id字段 -> foreign key(group_id) references usergroup(id) # group_id关联用户组id字段 -> ); Query OK, 0 rows affected (0.03 sec) mysql> insert into user2usergroup(user_id,group_id) values -> (1,1), -> (1,2), -> (1,3), -> (1,4), -> (2,3), -> (2,4), -> (3,4) -> ; Query OK, 7 rows affected (0.00 sec) Records: 7 Duplicates: 0 Warnings: 0 mysql> select * from user2usergroup; +----+---------+----------+ | id | user_id | group_id | +----+---------+----------+ | 1 | 1 | 1 | | 2 | 1 | 2 | | 3 | 1 | 3 | | 4 | 1 | 4 | | 5 | 2 | 3 | | 6 | 2 | 4 | | 7 | 3 | 4 | +----+---------+----------+ 7 rows in set (0.00 sec) # 建关系:host与business 多对多 mysql> create table host2business( -> id int not null unique auto_increment, -> host_id int not null, -> business_id int not null, -> primary key(host_id,business_id), # 指定并建立复合主键、约束为不为空且惟一 -> foreign key(host_id) references host(id), # host_id关联用户id字段 -> foreign key(business_id) references business(id) # business_id关联业务id字段 -> ); Query OK, 0 rows affected (0.02 sec) mysql> insert into host2business(host_id, business_id) values -> (1,1), -> (1,2), -> (1,3), -> (2,2), -> (2,3), -> (3,4); Query OK, 6 rows affected (0.01 sec) Records: 6 Duplicates: 0 Warnings: 0 # 建关系:user与host 多对多 mysql> create table user2host( -> id int not null unique auto_increment, -> user_id int not null, -> host_id int not null, -> primary key(user_id,host_id), -> foreign key(user_id) references user(id), # user_id关联用户id字段 -> foreign key(host_id) references host(id) # host_id关联主机id字段 -> ); Query OK, 0 rows affected (0.03 sec) mysql> insert into user2host(user_id,host_id) values -> (1,1), -> (1,2), -> (1,3), -> (1,4), -> (1,5), -> (1,6), -> (1,7), -> (1,8), -> (1,9), -> (1,10), -> (1,11), -> (1,12), -> (1,13), -> (1,14), -> (1,15), -> (1,16), -> (2,2), -> (2,3), -> (2,4), -> (2,5), -> (3,10), -> (3,11), -> (3,12) -> ; Query OK, 23 rows affected (0.00 sec) Records: 23 Duplicates: 0 Warnings: 0
做业:
mysql> create database db2; Query OK, 1 row affected (0.00 sec) mysql> use db2 Database changed mysql> show tables; Empty set (0.00 sec) mysql> create table class( -> cid int primary key auto_increment, -> caption char(20) not null -> ); Query OK, 0 rows affected (0.02 sec) mysql> insert into class(caption) values -> ('三年二班'), -> ('一年三班'), -> ('三年一班'); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from class; +-----+--------------+ | cid | caption | +-----+--------------+ | 1 | 三年二班 | | 2 | 一年三班 | | 3 | 三年一班 | +-----+--------------+ 3 rows in set (0.00 sec) mysql> create table student( -> sid int primary key auto_increment, -> sname char(20) not null, -> gender enum('男','女') not null, -> class_id int not null, -> foreign key(class_id) references class(cid) -> on delete cascade -> on update cascade -> ); Query OK, 0 rows affected (0.01 sec) mysql> insert into student(sname,gender,class_id) values -> ('钢蛋','女',1), -> ('铁锤','女',1), -> ('山炮','男',2); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from student; +-----+--------+--------+----------+ | sid | sname | gender | class_id | +-----+--------+--------+----------+ | 1 | 钢蛋 | 女 | 1 | | 2 | 铁锤 | 女 | 1 | | 3 | 山炮 | 男 | 2 | +-----+--------+--------+----------+ 3 rows in set (0.00 sec) mysql> create table teacher( -> tid int primary key auto_increment, -> tname char(20) not null -> ); Query OK, 0 rows affected (0.02 sec) mysql> insert into teacher(tname) values -> ('波多'), -> ('苍空'), -> ('饭岛'); Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from teacher; +-----+--------+ | tid | tname | +-----+--------+ | 1 | 波多 | | 2 | 苍空 | | 3 | 饭岛 | +-----+--------+ 3 rows in set (0.00 sec) mysql> create table course( -> cid int primary key auto_increment, -> cname char(20) not null, -> teacher_id int not null, -> foreign key(teacher_id) references teacher(tid) -> on delete cascade -> on update cascade -> ); Query OK, 0 rows affected (0.01 sec) mysql> insert into course(cname,teacher_id) values -> ('生物',1),('体育',1),('物理',2); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from course; +-----+--------+------------+ | cid | cname | teacher_id | +-----+--------+------------+ | 1 | 生物 | 1 | | 2 | 体育 | 1 | | 3 | 物理 | 2 | +-----+--------+------------+ 3 rows in set (0.00 sec) mysql> create table score( -> sid int not null unique auto_increment, -> student_id int not null, -> corse_id int not null, -> foreign key(student_id) references student(sid) -> on delete cascade -> on update cascade, -> foreign key(corse_id) references course(cid) -> on delete cascade -> on update cascade, -> number int not null, -> primary key(student_id, corse_id) -> ); Query OK, 0 rows affected (0.01 sec) mysql> insert into score(student_id, corse_id, number) values -> (1,1,60),(1,2,59),(2,2,100); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from score; +-----+------------+----------+--------+ | sid | student_id | corse_id | number | +-----+------------+----------+--------+ | 1 | 1 | 1 | 60 | | 2 | 1 | 2 | 59 | | 3 | 2 | 2 | 100 | +-----+------------+----------+--------+ 3 rows in set (0.00 sec)