对于MySQL数据库的基础学习

MySQL

1.数据库基本概念

1.数据库

DateBase 简写DB

2.概述

数据库是用于存储和管理数据的仓库

3.特点:

​ 1.用于持久化存储数据的,数据库其实就是一个文件系统

1.只要是持久化存储,肯定都是以文件的形式存储在硬盘上

2.数据库的文件系统和windows文件系统的虽然都可以存储数据,但是数据库不光要求 能存数据,还要求对于数据的操作更简单,管理更方便。

​ 2.方便存储和管理数据

​ 3.使用统一的操作数据语言——SOL(普通话)

4.常见的数据库

​ 1.MySQL: 最初是MySql公司的,后来被Sun公司收购,随着Sun公司,又被Oracle收购。

​ 特点:开源,免费,深受中小企业喜爱

​ 2.Oracle :甲骨文

​ 特点:安全,扩展性强,功能完备

​ 3.SQL Server

​ 特点:C# 和 .net项目中应用比较多

5.启动和关闭

​ Mysql安装好之后,需要启动服务,什么是服务?服务就是没有界面的应用程序

1.启动,关闭服务

  • ​ 方式1:(开始键+R)运行-> services.msc

  • ​ 方式2:管理员身份cmd -> net start MySqL或net stop MySqL

    • 注意:命令中的MySql 一定要与你的mysql服务的名称一致。
6.MySQL登录

​ 方式一:

mysql -u用户名 -p密码

​ 方式二:

mysql -h目标主机IP地址 -u用户名 -p密码

​ 方式三:

mysql -host=目标主机IP地址 --user=用户名 --password=密码

7.MySQL退出

quit

exit

2.SQL

2.1概述:

​ SQL:结构化查询语言(Structured Query Language)简称SQL。只要是关系型数据库,都可以用SQL语言区操作数据。不同的数据库之间的SQL操作略有不同,但是主体部分还是一样的。对于数据库之间的差异,我们称之为:“方言”.

2.2SQL语法

​ 1.SQL语句可以是单行,也可以是多行,多行以分号结尾

->show databases
->;

​ 2.使用空格 和 缩进来增强语句的可读性

​ 3.MySQL数据库的SOL语句不区分大小写,关键词建议使用大写

​ 4. 三种注释

​ 1.单行注释 :-- 注释内容 或 # 注释内容(Mysql特有)

​ 2.多行注释:/* 注释内容*/

2.3 SQL语言的分类

1.DDL(Data Definition Language):数据库定义语言

​ 用来定义数据库对象:数据库,表,列表等。关键字:create,drop,alter等

2.DML( Data Manipulation Language ):数据库操作语言

​ 用来对数据库中表的数据进行增删改操作的。关键字:insert,delete,update等

3.DQL( Data QueryLanguage ):数据库查询语言

​ 用来查询表中的数据。关键字:select,where

4.DCL(Data Control Language):数据库控制语言

​ 用来定义数据库的访问权限和安全级别,创建用户。关键字grant,revork

3.DDL -数据库定义语言

3.1操作数据库 -CRUD

1.C – Create创建

-- 创建数据库
CREATE DATABASE test;
-- 查看test数据-编码集
SHOW CREATE DATABASE test;

注意:

1.数据库已存在,再次创建就会报错

-- 如果test不存在,就创建
CREATE DATABASE IF NOT EXISTS test;

2.创建数据库时指定编码集

-- 创建数据库时指定编码集
CREATE DATABASE test2 CHAR SET utf8;
-- 将数据库test2的编码集指定为utf-8
SHOW CREATE DATABASE test2;
-- 查看test2数据库-编码集

2.R – Retrieve查询

​ 1.查询所有数据库名称 :

-- 查询所有数据库
SHOW DATABASES;

​ 2.查询指定数据库的编码集

-- 查看test数据-编码集
SHOW CREATE DATABASE test;
SHOW CREATE DATABASE 数据库名;

3.U – Upd修改

修改数据库编码集
-- 修改test的编码集为utf8
ALTER DATABASE test CHAR SET utf8;
ALTER DATABASE 数据库 CHAR SET 字符集;

4.D – Drop 删除

-- 删除test2 和 test3 
DROP DATABASE IF EXISTS test2;
DROP DATABASE IF EXISTS test3;
DROP DATABASE IF EXISTS 数据库名;

5.使用数据库

USE 数据库名;

3.2操作表

1.Create 创建

学生表

学号姓名年龄

语法:

CREATE TABLE 表名(
	列名1 数据类型1,
    列名2 数据类型2,
    ……
    列名n 数据类型n
);

注意:

​ 1.最后一个列不需要加,

​ 2.常用数据类型

​ 1.int:整形类型

​ 例子:age INT

​ 2.float,double小数类型

​ 例子:score float(4,2) '4’代表共四位数字,”2“代表小数位为2位

​ 3.date:日期类型:只包含年月日 yyyy-MM-dde

​ 4.datetime:日期类型:包含年月日时分秒 yyyy-MM-dd HH-mm-ss

​ 5.timestamp 时间戳类型:包含年月日时分秒 yyyy-MM-dd HH-mm-ss

​ 该类型再插入数据时,不赋值或赋null,则数据库会使用当前系统时间,来自动赋值

​ 6.char,varchar 字符串

​ char(n):定长度数据类型,该类型在存储数据时,如果数据长度<n,则剩余部分用空格补齐,查询时,再去掉空格

​ varchar(n):变长度数据类型

-- 创建学生表
CREATE TABLE student(
       id INT, -- 学号
       NAME VARCHAR(20),-- 姓名
       age INT, -- 年龄
       score DOUBLE(5,2), -- 成绩
       birthday DATE, -- 生日
       insert_time TIMESTAMP -- 插入时间
);

2.R–Retrieve查询

​ 1.查询所有数据库中所有表名称 :

SHOW TABLES;

​ 2.查询指定数据库的某个表;

DESC student;
desc 表名;

3.U – Upd修改

1.修改表名

alter table 表名 rename to stu
-- 修改表名
ALTER TABLE student RENAME TO stu;
SHOW TABLES;
DESC stu;

2.修改表的字符集

-- 修改字符集
ALTER TABLE stu CHAR SET utf8;

3.添加字段

-- 添加字段
ALTER TABLE stu ADD sex CHAR(2);

4.修改列名,数据类型

方式一:alter table 表名 change 旧列名 新列名 新数据类型

方式二:alter table 表名 change 列名 新数据类型

-- 修改列名,数据类型
ALTER TABLE stu CHANGE sex gender VARCHAR(10);
-- 只修改数据类型
ALTER TABLE stu MODIFY gender VARCHAR(5);

5.删除列

-- 删除列
ALTER TABLE stu DROP gender;

4.D – Drop删除表

drop table 表名;
drop table if exists 表名;--方式2
DROP TABLE IF EXISTS stu;

4.DML-数据库操作语言

4.1添加数据

语法:

​ insert into 表名 (字段1,字段2,……) values(value 1 ,value 2,……)

注意:

​ 1.列名 和 值 需要一一对应

​ 2.如果插入语句中不加列名,则表示默认向所有字段添加数据

​ 3.除了数字类型,其他都要加 引号(单双引号)

-- 插入一条数据
INSERT INTO student(id,NAME,age,score,birthday,insert_time) VALUES (1,"赵童",18,99.00,'2000-2-18',NULL);
DESC student;

INSERT INTO student VALUES (2,"屈波",18,90.00,'2000-3-18',NULL);
-- DQL 查询表中的所有数据
SELECT*FROM student;

4.2删除数据

语法:

​ delete from 表名[where 条件]

注意:

​ 1.如果不带条件,则会把表中的所有数据删除

​ 2.如果删除表中所有记录

​ 1.delete from 表名(一条一条删除,效率低)

​ 2.truncate table 表名(直接删除表,再创建一个一样的表,效率高)

-- 删除数据
DELETE FROM student WHERE id=1;
DELETE FROM student ; -- 清空表中数据
TRUNCATE TABLE student; -- 清空表中数据,然后创建一个一模一样的新

4.3修改数据

语法:

update 表名 set 列名 1 = value 1, 列名2 = value2,……[ where 条件]

注意:

​ 不加条件,修改所有的数据对应的字段

-- 修改数据
UPDATE student SET age=20;

-- 将id=2的学生的年龄修改成18
UPDATE student SET age=18 WHERE id=2;
UPDATE student SET score=100 WHERE id =1;

SELECT*FROM student;

5.DQL-数据库查询语言

语法:

select
字段列表
from
表名列表
where
条件列表
group by
分组字段
having
分组之后的条件
order by
排序
limit
分页限定

测试表:

​ 学生表(utf-8): 学号,姓名,年龄,性别,地址,java(int),c

USE test;
CREATE TABLE IF NOT EXISTS student(
id INT,#学号
NAME VARCHAR(20),#姓名
age INT,#年龄
sex VARCHAR(5),#性别
address VARCHAR(100),#地址
math INT,#数学
english INT#英语
);
DROP TABLE IF EXISTS student;
INSERT INTO student (id,NAME,age,sex,address,math,english) VALUES
(1,'马云',18,'男','杭州',80,80),
(2,'马化腾',19,'男','深圳',75,60),
(3,'埃隆马斯克',31,'男','美国',76,93),
(4,'扎克伯格',27,'男','美国',65,NULL),
(5,'郎平',16,'女','上海',90,98),
(6,'姚明',32,'男','上海',80,81);

5.1基础查询

1.SELECT*FROM 表名; – 查询该表中所有字段对应的数据

2.SELECT 字段1,字段2,……FROM 表名;查询表中指定字段对应的数据

-- 2.SELECT  字段1,字段2,……FROM 表名;查询表中指定字段对应的数据
SELECT NAME,age FROM student;

3.去重查询:SELECT DISTINCT 字段1,字段2,……FROM 表名

-- 查询学生表中的地址字段,去重
SELECT DISTINCT site FROM student;

**4.运算查询 Select 字段1,字段2,(字段1+字段2),… from 表名 **

-- 查询学生的java ,c 的成绩和总成绩
select Java,C,(Java+c) as 总成绩 from student; -- as 起别名

注意:

​ 当字段中有null值参与运算,结果也为null,这样的话不太合理,用于IFNULL

-- 查询学生的java ,c 的成绩和总成绩,如果缺考,则成绩按0处理
SELECT NAME,Java,IFNULL(c,0),(Java+IFNULL(C,0)) AS 总成绩 FROM student;

5.2条件查询
1.where子句后跟条件
2.运算符

​ 1.>,<, >= ,<=, = , <>

​ 2.BETWEEN…AND

​ 3.IN(集合)

​ 4.LINK:模糊查询

​ 占位符:

		’_:一个任意字符    周_
		%: 多个任意字符

​ 5.IS NULL

​ 6.AND或者&&

​ 7.OR或||

​ 8.NOT 或!

-- 查询年龄大于20的
SELECT*FROM student WHERE  age>20;

-- 查询年龄大于等于 20的学生
SELECT*FROM student WHERE  age>=20;

-- 查询年龄不等于32岁的学生
SELECT*FROM student WHERE age<>32;
SELECT*FROM student WHERE age!32;

-- 查询年龄在20岁 - 30岁之间的学生信息
SELECT*FROM student WHERE age<30 AND age>20;
SELECT * FROM student WHERE age>20 && age<30;
SELECT*FROM student WHERE age BETWEEN 20 AND 30;

-- 查询年龄时21和32
SELECT * FROM student WHERE age=21 OR age=32;
SELECT * FROM student WHERE age = 21 ||age = 32;
SELECT * FROM student WHERE age IN(21,32);

-- 查询C语言缺考的学生
SELECT * FROM student WHERE c IS NULL;
SELECT * FROM student WHERE c = NULL;-- 该条语句不正确,因为null不能用 = ,!= 判断

-- 查询C语言有成绩的学生
SELECT*FROM student WHERE c IS NOT NULL;

5.3 like-模糊查询

模糊查询在项目中用的比较多,因为大多数搜索框都是模糊查询

##################模糊查询###################
-- like查询
-- 查询姓赵的学生的信息
SELECT * FROM student WHERE NAME LIKE '赵%';

-- 查询第二个字有必学生信息
SELECT * FROM student WHERE NAME LIKE "_必%";

-- 查询名字中包含唐子学生信息
SELECT * FROM student WHERE NAME LIKE "%唐%";

-- 查询名字是三个子的名字
SELECT * FROM student WHERE NAME LIKE '___';

5.4排序查询

语法:

​ order by 子句

具体写法

​ order by 排序字段1,排序方式1, 排序字段2 ,排序方式2 ……

排序方式:

1.ASC:升序(默认排序)

2.DESC: 降序

##################排序查询###################
-- 查询学生信息,按照Java创建升序排序
SELECT*FROM student ORDER BY Java;
SELECT*FROM student ORDER BY Java ASC;

-- 查询学生信息,按照Java创建降序排序
SELECT*FROM student ORDER BY Java DESC;

-- 查询学生信息,按照Java创建降序排序,如果java成绩相同,再按照c成绩进行降序排序
SELECT*FROM student ORDER BY Java DESC,C DESC;

注意:

​ 如果有多个排序条件,当前一个条件值相同时,才会按照第二个条件进行排序

5.5聚合函数
概述:

​ 将一列数据作为整体,进行纵向计算

格式:

select 聚合函数(字段名)[as 别名] from 表名

分类:

​ 1.count:統計个数

​ 2.max : 计算最大值

​ 3.min:计算最小

​ 4.sum : 求和

​ 5.avg :求平均值

注意事项:

​ 聚合函数在进行计算时,会自动排除null

##################聚合函数查询###################
-- 統計学生表中有多少条信息
SELECT COUNT(id) FROM student;
SELECT COUNT(IFNULL(C,0)) FROM student;

-- 求学生中C语言成绩最高分
SELECT MAX(IFNULL(C,0)) AS C最高分 FROM student;

-- 求学生中C语言成绩最低分
SELECT MIN(IFNULL(C,0)) AS C最低分 FROM student;

-- 求学生中Java语言成绩总和
SELECT SUM(Java) AS 成绩总和 FROM student;

-- 求学生中Java语言平均成绩
SELECT AVG(Java) AS 平均成绩 FROM student;

5.6分组查询

格式:

	group  by 分组字段

注意:

1.分组之后的查询的字段: 分组字段,聚合函数

SELECT * FROM student GROUP BY sex;-- 没有任何意义结果:查出局部数据

2.where 和 having 的区别

​ where对分组前进行限定,如果不满足,则不参与分组,having是对分组后结果进行限定,如果不满

足,就不会被查询出来。

​ where后不能跟聚合函数,having后可以跟聚合函数

-- 按照性别分组,分别查询男,女同学的数学平均分
SELECT * FROM student GROUP BY sex;-- 没有任何意义
SELECT sex,AVG(math) FROM student GROUP BY sex;

-- 按照性别分组,分别查询男,女同学的数学平均分,及相应性别对应的人数
SELECT sex,AVG(math),COUNT(id) FROM student GROUP BY sex;

-- 分组前添加一些限定条件
-- 按照性别分组,分别查询男,女同学的英语平均分,及相应性别对应的人数,分组要求:分数小于60的不参与统计
SELECT sex,AVG(IFNULL(english,0)),COUNT(id) FROM student WHERE english >60 GROUP BY sex;
SELECT sex,AVG(IFNULL(english,0)),COUNT(id) FROM student GROUP BY sex HAVING
english >60;-- 错误,因为条件是分组前的条件,having只对分组后的结果进行条件添加

-- 按照性别分组,分别查询男,女同学的英语平均分,及相应性别对应的人数,分组要求:分数小于60的不参与统计,并且只查看人数大于2的分组数据
SELECT sex,AVG(IFNULL(english,0)),COUNT(id) FROM student WHERE english >60 GROUP
BY sex HAVING COUNT(id)>2;
-- 另一种写法
SELECT sex,AVG(IFNULL(english,0)),COUNT(id) 人数 FROM student WHERE english >60
GROUP BY sex HAVING 人数>2;

5.7 分页查询

格式:

​ limit 开始的索引,每页显示的条数;

分页公式:

​ 开始的索引 = (当前页码-1)* 每页显示的条数

推导过程:

-- 每页显示2条数据
SELECT * FROM student LIMIT 0,2;-- 第1页
SELECT * FROM student LIMIT 2,2;-- 第2页
SELECT * FROM student LIMIT 4,2;-- 第3页
SELECT * FROM student LIMIT 6,2;-- 第4页

-- 后面在做网站实现分页效果的时候,我们只需要确定每页起始的索引就可以实现分页效果
-- 分页公式:开始的索引 = (当前页码-1)* 每页显示的条数


注意:

​ 分页操作limit语法是MySql的“方言”

6.约束

概述:

​ 对表中的数据进行限定,保证数据的正确性,有效性和完整性。

理解

​ 对于我们一直操作的学生表,我们可以尝试添加一些非法数据,比如名字=null,它是能被正常保存进去的,这样对于的数据是无效,不完整,且没有任何意义的。所以我们在设计表的时候可以给表中的字段加一些约束,比如名字字段对应的值不能为null,这样就可以有效的保证数据的正确性,有效性和完整性。

使用:

1.创建表时  

​ 2.修改表时

分类:

​ 1.主键约束:primary key

​ 2.非空约束:not null

​ 3.唯一约束:unique

​ 4.外键约束:foreign key(多表关系讲解后讲)

非空约束:not null

方式1:创建表时

CREATE TABLE people(
	NAME VARCHAR(20) NOT NULL,
	age INT
);
SELECT * FROM people;

INSERT INTO people (NAME,age) VALUES('马化腾',25);
INSERT INTO people (NAME,age) VALUES(NULL,25);-- 报错:Column 'name' cannot be null

方式2:修改表时,可添加,可删除

-- 修改表来添加或删除约束
ALTER TABLE people MODIFY NAME VARCHAR(20);
INSERT INTO people (NAME,age) VALUES(NULL,25);-- 不报错:我们将非空约束删除了
ALTER TABLE people MODIFY NAME VARCHAR(20) NOT NULL;
INSERT INTO people (NAME,age) VALUES(NULL,25);-- 报错:Column 'name' cannot be null

唯一约束:unique

注意:

​ 多个null值不算重复值。

方式1:创建表时

DROP TABLE IF EXISTS people;
CREATE TABLE IF NOT EXISTS people(
	NAME VARCHAR(20),
	p_id BIGINT(18) UNIQUE
);
INSERT INTO people (NAME,p_id) VALUES('马云',610503197702021125);
INSERT INTO people (NAME,p_id) VALUES('马云',610503197702021125);-- 报错:Duplicate entry '610503197702021125' for key 'p_id'
INSERT INTO people (NAME,p_id) VALUES('马化腾',NULL);-- 不报错
INSERT INTO people (NAME,p_id) VALUES('马化腾',NULL);-- 不报错
SELECT * FROM people;

方式2:修改表时,可添加,可删除

ALTER TABLE people MODIFY p_id BIGINT(18);
INSERT INTO people (NAME,p_id) VALUES('马云',610503197702021125);-- 报错,因为唯一约束的删除有特殊语法
ALTER TABLE people DROP INDEX p_id;
INSERT INTO people (NAME,p_id) VALUES('马云',610503197702021125);-- 不报错
ALTER TABLE people MODIFY p_id BIGINT(18) UNIQUE;-- 报错,因为表中有不唯一数据,删除之后就不会报错了
SELECT * FROM people;

主键约束:primary key

主键:

​ 1.主键 = 非空且唯一

​ 2.一张表中只能有一个字段为主键

​ 3.主键就是表中记录的唯一标识

DROP TABLE IF EXISTS people;
CREATE TABLE IF NOT EXISTS people(
	id INT PRIMARY KEY,-- 主键
	NAME VARCHAR(20)
);

INSERT INTO people (id,NAME) VALUES(1,'马云');
INSERT INTO people (id,NAME) VALUES(2,'刘德华');
INSERT INTO people (id,NAME) VALUES(2,'张惠妹');-- 报错:Duplicate entry '2' for key 'PRIMARY'
INSERT INTO people (id,NAME) VALUES(NULL,'张惠妹');-- 报错:Column 'id' cannot be null
-- 删除主键
ALTER TABLE people DROP PRIMARY KEY;

-- 添加主键
ALTER TABLE people MODIFY id INT PRIMARY KEY;

自动增长:AUTO_INCREMENT

概述:

​ 如果某一列是数值类型的,并且连续非空且连续的时候,我们就可以使用 auto_increment 来完 成自动增长

方式1 创建表时添加主键并将主键设置为自增

DROP TABLE IF EXISTS people;
CREATE TABLE IF NOT EXISTS people(
	id INT PRIMARY KEY AUTO_INCREMENT ,-- 主键
	NAME VARCHAR(20)
);

-- 自增序列我们可以不给值,它会自己给
INSERT INTO people (id,NAME) VALUES(NULL,'马云');
INSERT INTO people (id,NAME) VALUES(NULL,'刘德华');

-- 我们也可以手动的指定值,并且下一次添加的值只与最后一条数据有关
INSERT INTO people (id,NAME) VALUES(100,'马云');
INSERT INTO people (id,NAME) VALUES(NULL,'刘德华');--id=101
SELECT * FROM people;

方式2:修改表时,可添加,可删除

ALTER TABLE people MODIFY id INT;
INSERT INTO people (id,NAME) VALUES(NULL,'刘德华');-- 报错:Column 'id' cannot be null
ALTER TABLE people MODIFY id INT AUTO_INCREMENT;

外键约束:foreign key

首先我们先建一个测试表:emp

CREATE TABLE emp(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(20),
	age INT,
	dep_name VARCHAR(30),-- 部门名称
	dep_location VARCHAR(30)-- 部门地址
)
INSERT INTO emp (NAME,age,dep_name,dep_location) VALUES('马化腾',20,'研发部','深圳');
INSERT INTO emp (NAME,age,dep_name,dep_location) VALUES('马云',26,'研发部','深圳');
INSERT INTO emp (NAME,age,dep_name,dep_location) VALUES('周杰伦',18,'销售部','北京');
INSERT INTO emp (NAME,age,dep_name,dep_location) VALUES('蔡依林',19,'销售部','北京');
INSERT INTO emp (NAME,age,dep_name,dep_location) VALUES('求伯君',22,'研发部','深圳');
INSERT INTO emp (NAME,age,dep_name,dep_location) VALUES('詹姆斯高斯林',30,'研发部','深圳');
INSERT INTO emp (NAME,age,dep_name,dep_location) VALUES('汤姆克鲁斯',20,'销售部','北京');
INSERT INTO emp (NAME,age,dep_name,dep_location) VALUES('丁磊',27,'研发部','深圳');


	通过查询数据,我们发现 研发部对应深圳,销售部对应北京,这样相同部门的员工信息中部门地址就会

出现很多重复数据,并且在修改部门地址时非常不方便,需要每条数据单独操作。

​ 为了解决上述问题,我们可以将表进行拆分,将员工表拆分成员工表和部门信息表,让这两个表产生联。

-- 解决数据冗余问题
-- 拆分表
DROP TABLE emp;
CREATE TABLE employee( -- 员工信息表
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(20),
	age INT,
	dep_id INT
);
CREATE TABLE department(-- 部门信息表
	id INT PRIMARY KEY AUTO_INCREMENT,
	dep_name VARCHAR(30),
	dep_location VARCHAR(30)
);
-- 添加数据
-- 添加部门
INSERT INTO department (dep_name,dep_location) VALUES ('研发部','深圳');
INSERT INTO department (dep_name,dep_location) VALUES ('销售部','北京');
-- 添加员工信息
INSERT INTO employee (NAME,age,dep_id) VALUES('马化腾',20,1);
INSERT INTO employee (NAME,age,dep_id) VALUES('马云',26,1);
INSERT INTO employee (NAME,age,dep_id) VALUES('周杰伦',18,2);
INSERT INTO employee (NAME,age,dep_id) VALUES('蔡依林',19,2);
INSERT INTO employee (NAME,age,dep_id) VALUES('求伯君',22,1);
INSERT INTO employee (NAME,age,dep_id) VALUES('詹姆斯高斯林',30,1);
INSERT INTO employee (NAME,age,dep_id) VALUES('汤姆克鲁斯',20,2);
INSERT INTO employee (NAME,age,dep_id) VALUES('丁磊',27,1);

​ 这样做看似解决了之前所说的数据冗余,操作不方便等问题,但是又有了新问题,比如我现在直接 将部门表中一个部门删掉,并且是可以删除成功的,但是我员工表中还有几个员工在被删除的这个部 门,这样的话就会出现逻辑问题,所以应该有一个约束:只有当前部门中没有员工时,才能删除该部 门。

方式1:创建表时添加

语法:

create table 表名(
	……
	外键列
	constraint 外键名称 foreign key (外键列名称) references 关联表名称(主表列名称)
);

案例:

-- 添加外键
DROP TABLE employee;
DROP TABLE department;
CREATE TABLE department(-- 部门信息表
	id INT PRIMARY KEY AUTO_INCREMENT,
	dep_name VARCHAR(30),
	dep_location VARCHAR(30)
);
CREATE TABLE employee( -- 员工信息表
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(20),
	age INT,
	dep_id INT ,-- 外键列
	CONSTRAINT emp_dep_fk FOREIGN KEY (dep_id) REFERENCES department(id)
);
-- 添加数据
-- 添加部门
INSERT INTO department (dep_name,dep_location) VALUES ('研发部','深圳');
INSERT INTO department (dep_name,dep_location) VALUES ('销售部','北京');
-- 添加员工信息
INSERT INTO employee (NAME,age,dep_id) VALUES('马化腾',20,1);
INSERT INTO employee (NAME,age,dep_id) VALUES('马云',26,1);
INSERT INTO employee (NAME,age,dep_id) VALUES('周杰伦',18,2);
INSERT INTO employee (NAME,age,dep_id) VALUES('蔡依林',19,2);
INSERT INTO employee (NAME,age,dep_id) VALUES('求伯君',22,1);
INSERT INTO employee (NAME,age,dep_id) VALUES('詹姆斯高斯林',30,1);
INSERT INTO employee (NAME,age,dep_id) VALUES('汤姆克鲁斯',20,2);
INSERT INTO employee (NAME,age,dep_id) VALUES('丁磊',27,1);
INSERT INTO employee (NAME,age,dep_id) VALUES('丁磊',27,3);-- 报错:Cannot add or update a child row
DELETE FROM department WHERE id = 1;-- 报错:annot delete or update a parent row:

方式2:修改表时,可添加,可删除

-- 删除外键
ALTER TABLE employee DROP FOREIGN KEY emp_dep_fk;
-- 添加外键
ALTER TABLE employee ADD CONSTRAINT emp_dep_fk FOREIGN KEY (dep_id) REFERENCES department(id);

级联操作(慎用)

当我们设置了外键之后,我想修改我的部门id,可以操作,但是比较麻烦

-- 1. 将员工表中关联的数据设置为null
UPDATE employee SET dep_id = NULL WHERE dep_id = 1;
-- 2. 修改部门id
UPDATE department SET id = 10 WHERE id=1;
-- 3. 将外键为null的值再设置成10
UPDATE employee SET dep_id=10 WHERE dep_id IS NULL;

设置级联更新:ON UPDATE CASCADE

-- 设置级联更新
ALTER TABLE employee DROP FOREIGN KEY emp_dep_fk;-- 先删除外键
ALTER TABLE employee ADD CONSTRAINT emp_dep_fk FOREIGN KEY (dep_id) REFERENCES department(id) ON UPDATE CASCADE;
UPDATE department SET id = 1 WHERE id=10;

设置级联删除:ON DELETE CASCADE

-- 设置级联删除
ALTER TABLE employee DROP FOREIGN KEY emp_dep_fk;-- 先删除外键
ALTER TABLE employee ADD CONSTRAINT emp_dep_fk FOREIGN KEY (dep_id) REFERENCES
department(id) ON UPDATE CASCADE ON DELETE CASCADE;--可以同时设置更新和删除,也可以分开设置
DELETE FROM department WHERE id=1;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值