一、初识数据库
1.数据库基本概念
1.数据
数据是对客观事务进行描述并且可以鉴别的符号,这些符号是可识别的、抽象的,有多种表现形式,可以是字母、文字、文本、图形、音频等
2.数据库(Database DB)----本质是文件系统
数据库指的是以一定格式存放,能够实现多个用户共享、与程序彼此独立的数据集合
通俗一点来说,数据库就是数据的仓库,可以存放很多数据,比如说车库可以存放车一样
3.数据库管理系统(数据库系统的基础和核心)
用来定义和管理数据的软件,可以保证数据的安全性和完整性,比较流行的数据库管理系统有:MySql、Oracle、SQL server、DB2等
比如说我们写了xxx.doc,这个就是一个word文件,那么我们是不是使用word去打开里面的文件,那么word这个软件就当于这里说的DBMS
数据库管理系统(DBMS)可以管理多个数据库,一般开发人员会针对每一个应用创建一个数据库。为保存应用中实体的数据,一般会在数据库创建多个表,以保存程序中实体用户的数据。
数据库管理系统、数据库和表的关系如图所示:
4.数据库应用程序
在数据库管理系统的基础上,使用数据库管理系统的语法,开发的直接面对最终用户的应用程序,比如:学生管理系统、人事管理系统、图书管理系统
我们可以这样来理解:不是每一个人都可以接触到数据库的,而且接触到数据库也不一定会使用,举个例子:以学生管理系统来说,学生只要点击选课,就代表选到了,点击退选,就把课程给退了,底层其实还是操作数据库,不过这样子对那些不懂数据库的人来说是很方便的。
5.数据库管理员(DBA)
对数据库管理系统进行操作的人员,主要负责数据库的运营和维护
6.最终用户
指的是数据库应用程序的使用者,用户面向的是数据库应用程序,通过程序来操作数据,并不会直接面向数据库
7.数据库系统(DBS)
一般是由数据库、数据库管理系统、数据库应用程序、数据库管理员和最终用户构成
通过下面的图来总结一下:
2.数据库类型
数据库模型主要是:关系型数据库和非关系型数据库
关系型数据库
关系型数据库把复杂的数据结构用简单的二元关系(二维表)来表示
关系型数据库主要有:MySQL、Oracle、DB2、SQL server等
关系型数据库的数据是存在硬盘中的,获取数据需要通过io操作,形象效率。非关系型数据库的数据存在内存,这种数据库要求不能断电,否则数据会消失
关系型数据库对数据是有约束的,不能随意插入数据,需要遵守一定规范
关系型数据库的行代表一条记录,列代表字段
我们可以把Java的对象和关系型数据库来类比一下
非关系型数据库NOSQL
主要有:MongDB、redis、HBase
数据存在内存,访问数据很快,但是机器断电的话,数据就没了
3.常见数据库
1.Oracle:关系型数据库,世界上最流行的数据库,性能高、安全性高、风险低,管理维护和操作复杂,价格昂贵,一般用在银行、金融、保险等行业
2.DB2:用起来繁琐,时候大型的分布式应用系统
3.SQL server:Microsoft开发和推广的关系型数据库,功能全面,但只能用在Windows操作系统
4.MySQL:开源,体积小,速度快,成本低
二、MySQL数据库
1. MySQL安装以及目录信息
MySQL官方下载地址
安装过程:
1.双击MySQL安装文件mysql-installer-community-8.0.18.0.msi,出现安装类型选项。
² Developer Default:开发者默认
² Server only:只安装服务器端
² Client only:只安装客户端
² Full:安装全部选项
² Custom:自定义安装
2.选择,然后继续:
3.进入产品配置向导,配置多个安装细节,点击Next按钮即可。
4.高可靠性High Availability,采用默认选项即可。
Standalone MySQL Server/Classic MySQL Replication:独立MySQL服务器/经典MySQL复制
InnoDB Cluster:InnoDB集群
5.类型和网络 Type and Networking,采用默认选项即可。记住MySQL的监听端口默认是3306。
6.身份验证方法Authentication Method,采用默认选项即可。
7.账户和角色 Accounts and Roles。MySQL管理员账户名称是root,在此处指定root用户的密码。还可以在此处通过Add User按钮添加其他新账户,此处省略该操作。
8.Windows服务:Windows Service。
- Configure MySQL Server as a Windows Service:给MySQL服务器配置一个服务项。
Windows Service Name:服务名称,采用默认名称MySQL80即可。
- Start the MySQL at System Startup:系统启动时开启MySQL服务
9.Apply Configuration:点击Execute按钮执行开始应用这些配置项。
- Writing configuration file: 写配置文件。
- Updating Windows Firewall rules:更新Windows防火墙规则
- Adjusting Windows services:调整Windows服务
- Initializing database:初始化数据库
- Starting the server: 启动服务器
- Applying security setting:应用安全设置
- Updating the Start menu link:更新开始菜单快捷方式链接
PS:如果配置出错,查看右侧的log,查看对应错误信息。
执行完成后,如下图所示。单击Finish完成安装,进入产品配置环节。
10.产品配置Product Configuration到此结束:点击Next按钮。
11.安装完成 Installation Complete。点击Finish按钮完成安装。
2.查看MySQL应用程序
电脑->管理->服务和应用程序->服务
3.各个目录文件夹
修改my.ini可以达到重新配置的作用
有几个配置项需要注意:
port=3306 监听端口是3306
basedir="D:/Program Files/MySQL/MySQL Server 8.0/" 软件安装位置
datadir=D:/ProgramData/MySQL/MySQL Server 8.0\Data 数据文件夹安装位置
default_authentication_plugin=caching_sha2_password 默认验证插件
default-storage-engine=INNODB 默认存储引擎
允许最大连接数
max_connections=200
允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统
max_connect_errors=10
服务端使用的字符集默认为UTF8
character-set-server=utf8
创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
[mysql]
设置mysql客户端默认字符集
default-character-set=utf8
(这些内容在Linux下可能会手动更改)
4.常见命令
1. .登录
访问MySQL服务器相关命令:
注意:mysql.exe需要带参数执行,所以直接在图形界面下执行该命令会自动结束,就是说,直接点击这个命令,它会直接退出
打开控制命令台:win+r 输入cmd
控制台要重启才有效
登录的命令
出现下面这个页面就登录成功了
2.访问数据库
系统默认给的数据库
3.退出数据库
退出数据库可以使用quit或者exit命令完成,也可以用\q完成退出操作
5.数据库的卸载
6 SQL yog(MySQL图形化界面工具)
三、SQL语言入门
1.概述
数据库管理人员通过数据库管理系统可以对数据库的数据进行操作,具体的操作需要通过sql语言
SQL(结构化查询语言) SQL是一种非过程化语言,只需要指明做什么,不需要指明怎么做
2.SQL分类
DQL:数据查询语言,主要用于数据查询,基本结构使用select子句,from子句,where子句的组合来查询一条或多条数据
DML:数据操作语言,DML用于对数据库中的数据进行增加,修改,删除操作
- insert:增加数据
- update:修改数据
- delete删除数据
DDL:数据定义语言,主要针对数据库对象(数据库,表,索引,视图,存储过程,函数)进行创建,修改,删除操作
- create:创建数据库对象
- alter:修改数据库对象
- drop:删除数据库对象
DCL:数据控制语言用来授予或者回收访问数据库的权限
比如说用户的登录权限
- grant:授予用户某种权限
- revoke:回收授予的某种权限
TCL:事务控制语言 TCL用于数据库的事务管理,包括
- start transaction:开启事务
- commit:提交事务
- rollback:回滚事务
- set transaction:设置事务属性
3.创建数据库表
1.认识数据库表
2.创建数据库表t_student
新手建议使用命令,不要用图形界面
先创建数据库
mysql> create database if not exists mytestdb charset utf8mb4;
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| atguigudb |
| bjpowernode |
| dbtest1 |
| hsp_db02 |
| hsp_db03 |
| information_schema |
| mysql |
| mysqlstudy | 我们刚刚建立的数据库
| mytest1 |
| mytestdb |
| performance_schema |
| sys |
| test01_office |
| test02_market |
| test03_company |
+--------------------+
15 rows in set (0.01 sec)
mysql> use mytestdb; 用来说明我们要操作哪一个数据库
Database changed
mysql> show tables;
Empty set (0.00 sec) 目前还没有表
CREATE TABLE IF NOT EXISTS t_student(
num INT(6),
`name` VARCHAR(10),
sex CHAR(1),
age INT(3),
enterdate DATE,
classname VARCHAR(10),
email VARCHAR(15) 注意这里不要加逗号
);
创建好以后,我们来查看表的结构
DESC t_student;
查看建表语句
SHOW CREATE TABLE t_student;
把里面的内容复制出来
CREATE TABLE `t_student` (
`num` int DEFAULT NULL,
`name` varchar(10) DEFAULT NULL,
`sex` char(1) DEFAULT NULL,
`age` int DEFAULT NULL,
`enterdate` date DEFAULT NULL,
`classname` varchar(10) DEFAULT NULL,
`email` varchar(15) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
4.数据库表列类型
整数类型
MySQL支持选择在该类型关键字后面的括号内指定整数值的显示宽度(例如,INT(4))。显示宽度并不限制可以在列内保存的值的范围,也不限制超过列的指定宽度的值的显示
注意:INT(4)只是用来建议我们最好输入的值不要超过4位,比如写1234,但是我们写12345这样也是可以的,因为MySQL会自动增加宽度
主键自增:不使用序列,通过auto_increment,要求是整数类型(后面说,先有个印象)主键可以唯一定位一条记录
浮点数类型
需要注意的是与整数类型不一样的是,浮点数类型的宽度不会自动扩充。 score double(4,1)
score double(4,1)--小数部分为1位,总宽度4位,并且不会自动扩充。
字符串类型
CHAR和VARCHAR类型相似,均用于存于较短的字符串,主要的不同之处在于存储方式。CHAR类型长度固定,VARCHAR类型的长度可变。
VARCHAR类型能够根据字符串的实际长度来动态改变所占字节的大小,所以在不能明确该字段具体需要多少字符时推荐使用VARCHAR类型,这样可以大大地节约磁盘空间、提高存储效率。
CHAR和VARCHAR表示的是字符的个数,而不是字节的个数
日期和时间类型
TIMESTEMP类型的数据指定方式与DATETIME基本相同,两者的不同之处在于以下几点:
(1) 数据的取值范围不同,TIMESTEMP类型的取值范围更小。
(2) 如果我们对TIMESTAMP类型的字段没有明确赋值,或是被赋与了NULL值,MySQL会自动将该字段赋值为系统当前的日期与时间。
(3) TIMESTEMP类型还可以使用CURRENT_TIMESTAMP来获取系统当前时间。
(4) TIMESTEMP类型有一个很大的特点,那就是时间是根据时区来显示的。例如,在东八区插入的TIMESTEMP数据为2017-07-11 16:43:25,在东七区显示时,时间部分就变成了15:43:25,在东九区显示时,时间部分就变成了17:43:25。
5.DML操作数据
注意事项
int 宽度是显示宽度,如果超过,可以自动增大宽度 int底层都是4个字节
时间的方式多样 '1256-12-23' "1256/12/23" "1256.12.23"
字符串不区分单引号和双引号
如何写入当前的时间 now() , sysdate() , CURRENT_DATE()
char varchar 是字符的个数,不是字节的个数,可以使用binary,varbinary表示定长和不定长的字节个数。
如果不是全字段插入数据的话,需要加入字段的名字
-- 查看表记录:
select * from t_student;
1.插入数据
如果表名后面没有加字段名的话,就是默认插入全部数据
insert into 表名 values(值1,值2值3...)
一次性插入多条数据
insert into t_student values (1,'张三','男',18,'2022-5-8','软件1班','123@126.com'),(10010010,'张三','男',18,'2022-5-8','软件1班','123@126.com');
想想看,如果表后面没有加字段名,而且我们插入的数据也和字段数量不匹配,会出现什么后果
INSERT INTO t_student VALUES(5);
如果我们只是想要插入部分数据,怎么办呢?
insert into 表名(字段1,字段2...) values(值1,值2...)
INSERT INTO t_student (num,`name`,enterdate) VALUES (10,'李四','2023-7-5');
-- 在t_student数据库表中插入数据:
insert into t_student values (1,'张三','男',18,'2022-5-8','软件1班','123@126.com');
insert into t_student values (10010010,'张三','男',18,'2022-5-8','软件1班','123@126.com');
insert into t_student values (2,'张三','男',18,'2022.5.8','软件1班','123@126.com');
insert into t_student values (2,"张三",'男',18,'2022.5.8','软件1班','123@126.com');
insert into t_student values (7,"张三",'男',18,now(),'软件1班','123@126.com');
insert into t_student values (9,"易烊千玺",'男',18,now(),'软件1班','123@126.com');
insert into t_student (sno,sname,enterdate) values (10,'李四','2023-7-5');
没有插入的数据,就用默认值来替代
2.修改表中数据
update 表名 set 字段名=value
这种方式是不加筛选条件,那么表中所有数据的这个字段的值都会发生变化
update t_student set sex='女';
所以,我们修改数据应该要加上条件
update t_student set sex='男' where num=2;
3.删除数据
delete from 表名
这种不加筛选条件的,会删除表中所有数据,但是表的结构还在
delete from 表名 where 筛选条件
这种只会删除符合条件的数据
注意事项
1.关键字,表名,字段名不区分大小写
2.默认情况下,内容不区分大小写
3.删除操作from关键字不可缺少
4.修改,删除数据别忘记加限制条件
6.DDL操作表结构
1.修改表结构
使用alter关键字
1.1增加列
增加列add
alter table t_student add score double(5,2)
update t_student set score=123.5678 where num=2;
显示的数据是123.57,会进行四舍五入
我们增加列的时候,默认加在最后一列,那么我们可以指定这个列出现在哪一个位置吗?--- 可以
增加一列(放最前面)
alter table t_student add score double(5,2) first;
增加一列,放在sex列的后面
alter table t_student add score double(5,2) after sex;
增加一列,放在sex列的前面
alter table t_student add score double(5,2) before sex;
1.2修改列
modify修改的是列的定义,不会改变列的名字
alter table t_student modify score float(4,1);
change
alter table t_student change score score1 double(3,1);
alter table t_student change score score1 double(5,1);
2.删除表结构
删除一列
alter table t_student drop score;
删除整个表
drop table t_student;
7.DDL和DML补充
如何快速创建一张表
添加一张表:快速添加:结构和数据跟t_student 都是一致的
create table t_student2
as
select * from t_student;
快速添加,结构跟t_student一致,数据没有:
create table t_student3
as
select * from t_student where 1=2;
select * from t_student3;
快速添加:只要部分列,部分数据:
create table t_student4
as
select sno,sname,age from t_student where sno = 2;
select * from t_student4;
delete和truncate的区别:
从最终的结果来看,虽然使用TRUNCATE操作和使用DELETE操作都可以删除表中的全部记录,但是两者还是有很多区别的,其区别主要体现在以下几个方面:
(1)DELETE为数据操作语言DML;TRUNCATE为数据定义语言DDL。
(2) DELETE操作是将表中所有记录一条一条删除直到删除完;TRUNCATE操作则是保留了表的结构,重新创建了这个表,所有的状态都相当于新表。因此,TRUNCATE操作的效率更高。
(3)DELETE操作可以回滚;TRUNCATE操作会导致隐式提交,因此不能回滚(后面会讲解事务的提交和回滚)。
(4)DELETE操作执行成功后会返回已删除的行数(如删除4行记录,则会显示“Affected rows:4”);截断操作不会返回已删除的行量,结果通常是“Affected rows:0”。DELETE操作删除表中记录后,再次向表中添加新记录时,对于设置有自增约束字段的值会从删除前表中该字段的最大值加1开始自增;TRUNCATE操作则会重新从1开始自增。
四、表的完整性约束
数据库中表的数据应该要有约束的,不然什么数据都可以插入数据库中,以之前的学生表为例,里面的数据 没有任何约束,什么数据都可以放进去,但是,学生的学号,邮箱应该是唯一的,性别只有男和女,我们应该保证在插入的数据,学号,邮箱唯一,性别只能是男和女,不然就报错。
为防止不符合规范的数据存入数据库,在用户对数据进行插入、修改、删除等操作时,MySQL提供了一种机制来检查数据库中的数据是否满足规定的条件,以保证数据库中数据的准确性和一致性,这种机制就是完整性约束。
MySQL中主要支持以下几种种完整性约束,如表所示。 其中Check约束是MySQL8中提供的支持。
约束条件 | 约束描述 |
---|---|
PRIMARY KEY | 主键约束,约束字段的值可唯一地标识对应的记录 |
NOT NULL | 非空约束,约束字段的值不能为空 |
UNIQUE | 唯一约束,约束字段的值是唯一的 |
CHECK | 检查约束,限制某个字段的取值范围 |
DEFAULT | 默认值约束,约束字段的默认值 |
AUTO_INCREMENT | 自动增加约束,约束字段的值自动递增 |
FOREIGN KEY | 外键约束,约束表与表之间的关系 |
## 1. 非外键约束
代码演示主键约束
建立一张用来存储学生信息的表
字段包含学号、姓名、性别,年龄、入学日期、班级,email等信息
约束:
建立一张用来存储学生信息的表
字段包含学号、姓名、性别,年龄、入学日期、班级,email等信息
【1】学号是主键 = 不能为空 + 唯一 ,主键的作用:可以通过主键查到唯一的一条记录【2】如果主键是整数类型,那么需要自增
【3】姓名不能为空
【4】Email唯一
【5】性别默认值是男
【6】性别只能是男女
【7】年龄只能在18-50之间
-- 创建数据库表:
create table t_student(
sno int(6) primary key auto_increment,
sname varchar(5) not null,
sex char(1) default '男' check(sex='男' || sex='女'),
age int(3) check(age>=18 and age<=50),
enterdate date,
classname varchar(10),
email varchar(15) unique
);
-- 添加数据:
-- 1048 - Column 'sname' cannot be null 不能为null
-- 3819 - Check constraint 't_student_chk_1' is violated. 违反检查约束
insert into t_student values (1,'张三','男',21,'2023-9-1','java01班','zs@126.com');
-- 1062 - Duplicate entry '1' for key 't_student.PRIMARY' 主键重复
-- > 1062 - Duplicate entry 'ls@126.com' for key 't_student.email' 违反唯一约束
insert into t_student values (2,'李四','男',21,'2023-9-1','java01班','ls@126.com');
insert into t_student values (3,'露露','男',21,'2023-9-1','java01班','ls@126.com');
-- 如果主键没有设定值,或者用null.default都可以完成主键自增的效果
insert into t_student (sname,enterdate) values ('菲菲','2029-4-5');
insert into t_student values (null,'小明','男',21,'2023-9-1','java01班','xm@126.com');
insert into t_student values (default,'小刚','男',21,'2023-9-1','java01班','xg@126.com');
-- 如果sql报错,可能主键就浪费了,后续插入的主键是不连号的,我们主键也不要求连号的
insert into t_student values (null,'小明','男',21,'2023-9-1','java01班','oo@126.com');
-- 查看数据:
select * from t_student;
2.约束分为两类(从作用上来分)
(1) 表级约束:
可以约束表中任意一个或多个字段。与列定义相互独立,不包含在列定义中;与定义用‘,’分隔;必须指出要约束的列的名称;
### (2) 列级约束:
包含在列定义中,直接跟在该列的其它定义之后 ,用空格分隔;不必指定列名;自增只能是列级约束,而且自增是基于主键的情况,没有主键就没有自增
-- 删除表:
drop table t_student;
-- 创建数据库表:
create table t_student(
sno int(6) auto_increment,
sname varchar(5) not null,
sex char(1) default '男',
age int(3),
enterdate date,
classname varchar(10),
email varchar(15),
constraint pk_stu primary key (sno), -- pk_stu 主键约束的名字
constraint ck_stu_sex check (sex = '男' || sex = '女'),
constraint ck_stu_age check (age >= 18 and age <= 50),
constraint uq_stu_email unique (email)
);
-- 添加数据:
insert into t_student values (1,'张三','男',21,'2023-9-1','java01班','zs@126.com');
-- > 3819 - Check constraint 'ck_stu_sex' is violated.
-- > 3819 - Check constraint 'ck_stu_age' is violated.
-- > 1062 - Duplicate entry 'zs@126.com' for key 't_student.uq_stu_email'
insert into t_student values (3,'李四','男',21,'2023-9-1','java01班','zs@126.com');
-- 查看数据:
select * from t_student;
(3)在创建表以后添加约束:
-- 删除表:
drop table t_student;
-- 创建数据库表:
create table t_student(
sno int(6),
sname varchar(5) not null,
sex char(1) default '男',
age int(3),
enterdate date,
classname varchar(10),
email varchar(15)
);
-- > 1075 - Incorrect table definition; there can be only one auto column and it must be defined as a key
-- 错误的解决办法:就是auto_increment去掉
-- 在创建表以后添加约束:
alter table t_student add constraint pk_stu primary key (sno) ; -- 主键约束
alter table t_student modify sno int(6) auto_increment; -- 修改自增条件
alter table t_student add constraint ck_stu_sex check (sex = '男' || sex = '女');
alter table t_student add constraint ck_stu_age check (age >= 18 and age <= 50);
alter table t_student add constraint uq_stu_email unique (email);
-- 查看表结构:
desc t_student;
验证约束添加成功:查看表结构:
(4)总结:
1.主键约束
主键约束(PRIMARY KEY,缩写PK),是数据库中最重要的一种约束,其作用是约束表中的某个字段可以唯一标识一条记录。因此,使用主键约束可以快速查找表中的记录。就像人的身份证、学生的学号等等,设置为主键的字段取值不能重复(唯一),也不能为空(非空),否则无法唯一标识一条记录。
主键可以是单个字段,也可以是多个字段组合。对于单字段主键的添加可使用表级约束,也可以使用列级约束;而对于多字段主键的添加只能使用表级约束。
2.非空约束
非空约束(NOT NULL,缩写NK)规定了一张表中指定的某个字段的值不能为空(NULL)。设置了非空约束的字段,在插入的数据为NULL时,数据库会提示错误,导致数据无法插入。
无论是单个字段还是多个字段非空约束的添加只能使用列级约束(非空约束无表级约束)
为已存在表中的字段添加非空约束
alter table student8 modify stu_sex varchar(1) not null;
使用ALTER TABLE语句删除非空约束
alter table student8 modify stu_sex varchar(1) null;
- 唯一约束
唯一约束(UNIQUE,缩写UK)比较简单,它规定了一张表中指定的某个字段的值不能重复,即这一字段的每个值都是唯一的。如果想要某个字段的值不重复,那么就可以为该字段添加为唯一约束。
无论单个字段还是多个字段唯一约束的添加均可使用列级约束和表级约束
- 检查约束
检查约束(CHECK)用来限制某个字段的取值范围,可以定义为列级约束,也可以定义为表级约束。MySQL8开始支持检查约束。
- 默认值约束
默认值约束(DEFAULT)用来规定字段的默认值。如果某个被设置为DEFAULT约束的字段没插入具体值,那么该字段的值将会被默认值填充。
默认值约束的设置与非空约束一样,也只能使用列级约束。
- 字段值自动增加约束
自增约束(AUTO_INCREMENT)可以使表中某个字段的值自动增加。一张表中只能有一个自增长字段,并且该字段必须定义了约束(该约束可以是主键约束、唯一约束以及外键约束),如果自增字段没有定义约束,数据库则会提示“Incorrect table definition; there can be only one auto column and it must be defined as a key”错误。
由于自增约束会自动生成唯一的ID,所以自增约束通常会配合主键使用,并且只适用于整数类型。一般情况下,设置为自增约束字段的值会从1开始,每增加一条记录,该字段的值加1。
为已存在表中的字段添加自增约束
/创建表student11/
create table student11 (
stu_id int(10) primary key,
stu_name varchar(3),
stu_sex varchar (1)
);
为student11表中的主键字段添加自增约束
alter table student11 modify stu_id int(10) auto_increment;
使用ALTER TABLE语句删除自增约束
alter table studen11 modify stu_id int(10);
3.外键策略
-- 学生表删除:
drop table t_student;
-- 班级表删除:
drop table t_class;
-- 注意:先删除从表,再删除主表。(视频中这个位置笔误,笔记现在已经更正)
-- 先创建父表:班级表:
create table t_class(
cno int(4) primary key auto_increment,
cname varchar(10) not null,
room char(4)
)
-- 可以一次性添加多条记录:
insert into t_class values (null,'java001','r803'),(null,'java002','r416'),(null,'大数据001','r103');
-- 添加学生表,添加外键约束:
create table t_student(
sno int(6) primary key auto_increment,
sname varchar(5) not null,
classno int(4),-- 取值参考t_class表中的cno字段,不要求字段名字完全重复,但是类型长度定义 尽量要求相同。
constraint fk_stu_classno foreign key (classno) references t_class (cno)
);
-- 可以一次性添加多条记录:
insert into t_student values (null,'张三',1),(null,'李四',1),(null,'王五',2),(null,'朱六',3);
-- 查看班级表和学生表:
select * from t_class;
select * from t_student;
-- 删除班级2:如果直接删除的话肯定不行因为有外键约束:
-- 加入外键策略:
-- 策略1:no action 不允许操作
-- 通过操作sql来完成:
-- 先把班级2的学生对应的班级 改为null
update t_student set classno = null where classno = 2;
-- 然后再删除班级2:
delete from t_class where cno = 2;
-- 策略2:cascade 级联操作:操作主表的时候影响从表的外键信息:
-- 先删除之前的外键约束:
alter table t_student drop foreign key fk_stu_classno;
-- 重新添加外键约束:
alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno) on update cascade on delete cascade;
-- 试试更新:
update t_class set cno = 5 where cno = 3;
-- 试试删除:
delete from t_class where cno = 5;
-- 策略3:set null 置空操作:
-- 先删除之前的外键约束:
alter table t_student drop foreign key fk_stu_classno;
-- 重新添加外键约束:
alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno) on update set null on delete set null;
-- 试试更新:
update t_class set cno = 8 where cno = 1;
-- 注意:
-- 1. 策略2 级联操作 和 策略2 的 删除操作 可以混着使用:
alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno) on update cascade on delete set null ;
-- 2.应用场合:
-- (1)朋友圈删除,点赞。留言都删除 -- 级联操作
-- (2)解散班级,对应的学生 置为班级为null就可以了,-- set null
看完这篇以后,大家可以看我的下一篇文章。