MySQL 笔记
# MySQL 安装
# 下载
https://downloads.mysql.com/archives/community/ (opens new window)
找到对应的版本
我下的是 8.2.0win-zip 版
# 添加环境变量
验证是否添加成功?
如果提示Can't connect to MySQL server on 'localhost'
则证明添加成功。
# 新建配置文件
新建一个文本文件,写入一下内容
[mysql]
default-character-set=utf8
[mysqld]
character-set-server=utf8
default-storage-engine=INNODB
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
2
3
4
5
6
7
改为 my.ini
放在 MySQL 的根目录里
上面配置文本的意思是,配置数据库的默认编码集为utf-8
和默认存储引擎为INNODB
# 初始化 MySQL
在刚才的终端中敲入mysqld --initialize-insecure
回车,稍微等待一会,如果没有出现报错信息则证明data
目录初始化没有问题,此时再查看 MySQL 目录下已经有data
目录生成
# 注册 MySQL 服务
注册服务就是将 MySQL 作为计算机系统后台的一个应用程序。
在终端里敲入mysqld -install
,回车。
现在你的计算机上已经安装好了 MySQL 服务了。
# 启动 MySQL 服务
net start mysql // 启动 mysql 服务
net stop mysql // 停止 mysql 服务
2
# 修改默认账户密码
在终端里敲入mysqladmin -u root password aaaaaa
,这里的aaaaaa
就是指默认管理员(即 root 账户)的密码,可以自行修改成你所需的
至此,MySQL 5.7.24 解压版安装完毕!
# MySQL 卸载
终端(管理员)
- 敲入
net stop mysql
,回车。 - 再敲入
mysqld -remove mysql
,回车。
# MySQL 登录
终端(管理员)输入:
mysql -uroot -p123456
登录参数:
mysql -u用户名 -p密码 -h要连接的mysql服务器的ip地址(默认127.0.0.1) -P端口号(默认3306)
2
3
4
到这里你就可以开始你的 MySQL 之旅了!
# 退出 MySQL
exit 或 quit
# MySQL 文件结构
- bin:用于放置一些可执行文件,如 mysql.exe、mysqld.exe、mysqlshow.exe 等
- data:用于放置一些日志文件以及数据库,我们创建和保存的数据都存在这个目录里
- docs:用于存放一些文档
- include:由于 MySQL 是用 C 语言写的,这里放置一些头文件,如:mysql.h、mysql_ername.h 等
- lib:用于放置一系列库文件
- share:用于存放字符集、语言等信息
- my.ini:默认使用的配置文件,一般情况下,只要修改该配置文件中的内容就可以对 MySQL 进行配置
- COPYING:许可声明
- README:自述文件
# SQL 基础
# 通用语法
SQL 语句可以单行或多行书写,以分号结尾
MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写
注释:
- 单行注释:
-- 注释
或# 注释
(MySQL 特有) - 推荐使用
-- 注释
注意:使用--
添加单行注释时,--
后面一定要加空格,而#
没有要求,但推荐注释符号后都留一个空格。
- 多行注释:
/* 注释 */
-- 单行注释(推荐)
#单行注释
# 推荐留一个空格
/*
多行
注释
*/
2
3
4
5
6
7
# SQL 分类
DDL(Data Definition Language)数据定义语言,用来定义数据库对象:数据库、表、列等
DDL 简单理解就是用来操作数据库和表的。
DML(Data Manipulation Language)数据操作语言,用来对数据库中表的数据进行增删改
DML 简单理解就对表中数据进行增删改。
DQL(Data Query Language)数据查询语言,用来查询数据库中表的记录(数据)
DQL 简单理解就是对数据进行查询操作,从数据库表中查询到我们想要的数据。
DCL(Data Control Language)数据控制语言,用来定义数据库的访问权限和安全级别及创建用户
DCL 简单理解就是对数据库进行权限控制,比如我让某一个数据库表只能让某一个用户进行操作等
# DDL
# 查询
查询所有的数据库
SHOW DATABASES;
上述查询到的是的这些数据库是 mysql 安装好自带的数据库,是数据库的核心,请不要操作这些数据库
# 创建数据库
CREATE DATABASE 数据库名称;
而在创建数据库的时候,我并不知道 db01 数据库有没有创建,直接再次创建名为 db01 的数据库就会出现错误。
(Can't create database 'db01'; database exists)
为了避免上面的错误,在创建数据库的时候先做判断,如果不存在再创建
所以要先判断,如果不存在,再创建
CREATE DATABASE IF NOT EXISTS 数据库名称;
# 删除数据库
删除数据库
DROP DATABASE 数据库名称;
删除数据库(先判断,如果存在再删除)
DROP DATABASE IF EXISTS 数据库名称;
# 使用数据库
数据库创建好了,要在数据库中创建表,得先明确在哪个数据库中操作,此时就需要使用数据库
使用数据库
USE 数据库名称;
查看当前使用的数据库
SELECT DATABASE();
# 查询表
查询当前数据库下所有表名称
SHOW TABLES;
查询表结构
DESC 表名称;
# 创建表
CREATE TABLE 表名 (
字段名1 数据类型1,
字段名2 数据类型2,
…
字段名n 数据类型n
);
2
3
4
5
6
注意:最后一行末尾,不能加逗号
知道了创建表的语句,那么我们创建创建如下结构的表
CREATE TABLE tb_user (
id int,
username varchar(20),
password varchar(32)
);
2
3
4
5
MySQL 表同样是需要设置字符集的(有默认值),为了确保统一,我们推荐还是手动设置上,防止字符混乱的情况发生:
CREATE TABLE 表名 (
...,
) ENGINE = INNODB DEFAULT CHARSET = utf8;
2
3
- ENGINE = INNODB:使用 InnoDB 引擎
- DEFAULT CHARSET = utf8:数据库默认编码为 utf-8
# 数据类型
MySQL 的数据类型大概可以分为三类
数值
tinyint:小整数型,占一个字节
int:大整数类型,占四个字节,使用格式:字段名 int;
double:浮点类型,使用格式:字段名 double(总长度, 小数点后保留的位数);
2
3
日期
date:日期值,只包含年月日,eg:birthday date;
datetime:混合日期和时间值,包含年月日时分秒
2
字符串
char:定长字符串。
优点:存储性能高
缺点:浪费空间
eg:name char(10) 如果存储的数据字符个数不足10个,也会占10个的空间
varchar:变长字符串。
优点:节约空间
缺点:存储性能底
eg:name varchar(10) 如果存储的数据字符个数不足10个,那就数据字符个数是几就占几个的空间
2
3
4
5
6
7
8
# 删除表
DROP TABLE 表名;
删除表时判断表是否存在
DROP TABLE IF EXISTS 表名;
# 修改表
修改表名
ALTER TABLE 表名 RENAME TO 新的表名;
-- 将表名 student 修改为 stu
ALTER TABLE student RENAME TO stu;
2
3
4
添加一列
ALTER TABLE 表名 ADD 列名 数据类型;
-- 给 stu 表添加一列 address,该字段类型是 varchar(50)
ALTER TABLE stu ADD address varchar(50);
2
3
4
修改数据类型
ALTER TABLE 表名 MODIFY 列名 新数据类型;
-- 将 stu 表中的 address 字段的类型改为 char(50)
ALTER TABLE stu MODIFY address char(50);
2
3
4
修改列名和数据类型
ALTER TABLE 表名 CHANGE 列名 新列名 新数据类型;
-- 将 stu 表中的 address 字段名改为 addr,类型改为 varchar(50)
ALTER TABLE stu CHANGE address addr varchar(50);
2
3
4
删除列
ALTER TABLE 表名 DROP 列名;
-- 将 stu 表中的 addr 字段 删除
ALTER TABLE stu DROP addr;
2
3
4
# DML
DML 主要是对数据进行增(insert)删(delete)改(update)操作
# 添加数据
给指定列添加数据
INSERT INTO 表名(列名1, 列名2, …) VALUES(值1, 值2, …);
给全部列添加数据
INSERT INTO 表名 VALUES(值1, 值2,…);
批量添加数据
INSERT INTO 表名(列名1, 列名2, …) VALUES(值1, 值2, …), (值1, 值2, …), (值1, 值2, …), …;
INSERT INTO 表名 VALUES(值1, 值2, …), (值1, 值2, …), (值1, 值2, …), …;
2
示例:
-- 给指定列添加数据
INSERT INTO stu (id, NAME) VALUES (1, '张三');
-- 给所有列添加数据,列名列表可以省略(为了可读性,建议不要省略!)
INSERT INTO stu (id, NAME, sex, birthday, score, email, tel, STATUS) VALUES (2, '李四', '男', '1999-11-11', 88.88, 'lisi@itcast.cn', '13888888888', 1);
-- 省略列名列表(为了可读性,建议不要省略!)
INSERT INTO stu VALUES (2,'李四','男','1999-11-11',88.88,'lisi@itcast.cn','13888888888',1);
-- 批量添加数据,以给所有列添加数据为例
INSERT INTO stu VALUES
(2, '李四', '男', '1999-11-11', 88.88, 'lisi@itcast.cn', '13888888888', 1),
(2, '李四', '男', '1999-11-11', 88.88, 'lisi@itcast.cn', '13888888888', 1),
(2, '李四', '男', '1999-11-11', 88.88, 'lisi@itcast.cn', '13888888888', 1);
2
3
4
5
6
7
8
9
10
11
12
可用下列语句查询修改是否成功
# 查询 stu 中的所有数据
SELECT * FROM stu;
2
# 修改数据
UPDATE 表名 SET 列名1 = 值1, 列名2 = 值2, … [WHERE 条件];
修改语句中如果不加 WHERE 条件,则将对所有的数据都修改!
像上面的语句中的中括号,表示在写 SQL 语句中可以省略这部分
示例:
将张三的性别改成女
UPDATE stu SET sex = '女' WHERE name = '张三';
# 删除数据
删除数据
DELETE FROM 表名 [WHERE 条件];
-- 删除张三记录
DELETE FROM stu WHERE name = '张三';
-- 删除 stu 表中所有的数据
DELETE FROM stu;
2
3
4
5
# DQL
数据库查询操作是最重要的操作,所以此部分需要重点掌握。
在进行 DQL 操作时,一定要符合下列命令的先后顺序
SELECT
字段列表
FROM
表名列表
WHERE
条件列表
GROUP BY
分组字段
HAVING
分组后条件
ORDER BY
排序字段
LIMIT
分页限定
2
3
4
5
6
7
8
9
10
11
12
13
14
为了给大家演示查询的语句,我们需要先准备表及一些数据:
-- 删除 stu 表
DROP TABLE IF EXISTS stu;
-- 创建 stu 表
CREATE TABLE stu (
id int, -- 编号
name varchar(20), -- 姓名
age int, -- 年龄
sex varchar(5), -- 性别
address varchar(100), -- 地址
math double(5, 2), -- 数学成绩
english double(5, 2), -- 英语成绩
hire_date date -- 入学时间
);
-- 添加数据
INSERT INTO stu ( id, NAME, age, sex, address, math, english, hire_date )
VALUES
( 1, '马运', 55, '男', '杭州', 66, 78, '1995-09-01' ),
( 2, '马花疼', 45, '女', '深圳', 98, 87, '1998-09-01' ),
( 3, '马斯克', 55, '男', '香港', 56, 77, '1999-09-02' ),
( 4, '柳白', 20, '女', '湖南', 76, 65, '1997-09-05' ),
( 5, '柳青', 20, '男', '湖南', 86, NULL, '1998-09-01' ),
( 6, '刘德花', 57, '男', '香港', 99, 99, '1998-09-01' ),
( 7, '张学右', 22, '女', '香港', 99, 99, '1998-09-01' ),
( 8, '德玛西亚', 18, '男', '南京', 56, 65, '1994-09-02' );
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 基础查询
查询多个字段
SELECT 字段列表 FROM 表名;
SELECT * FROM 表名; -- 查询所有数据
2
去除重复记录
SELECT DISTINCT 字段列表 FROM 表名;
起别名
AS: -- AS 可以省略
# 条件查询
SELECT 字段列表 FROM 表名 WHERE 条件列表;
查询年龄大于 20 岁的学员信息
SELECT * FROM stu WHERE age > 20;
查询入学日期在 '1998-09-01' 到 '1999-09-01' 之间的学员信息
# 模糊查询
模糊查询使用 LIKE 关键字,可以使用通配符进行占位:
_
:代表单个任意字符%
:代表任意个数字符
查询姓 “马” 的学员信息
SELECT * FROM stu WHERE name LIKE '马%';
# 排序查询
SELECT 字段列表 FROM 表名 ORDER BY 排序字段名1 [排序方式1], 排序字段名2 [排序方式2] …;
排序的方法有两种
- ASC : 升序排列(默认值)
- DESC : 降序排列
查询学生信息,按照年龄升序排列
SELECT * FROM stu ORDER BY age;
SELECT * FROM stu ORDER BY age ASC;
2
# 聚合函数
将一列数据作为一个整体,进行纵向计算。
聚合函数语法
SELECT 聚合函数名(列名) FROM 表;
统计班级一共有多少个学生
SELECT COUNT(id) FROM stu;
查询数学成绩的最高分
SELECT MAX(math) FROM stu;
# 分组查询
分组查询的本质其实就是:先按照某个条件对数据进行分组,然后对每一个组进行单独的查询
SELECT 字段列表 FROM 表名 [WHERE 分组前条件限定] GROUP BY 分组字段名 [HAVING 分组后条件过滤];
注意:分组之后,查询的字段为聚合函数和分组字段,查询其他字段无任何意义。
查询男同学和女同学各自的数学平均分
SELECT sex, AVG(math) FROM stu GROUP BY sex;
查询男同学和女同学各自的数学平均分,以及各自人数,要求:分数低于 70 分的不参与分组
SELECT sex, AVG(math), COUNT(*) FROM stu WHERE math > 70 GROUP BY sex;
查询男同学和女同学各自的数学平均分,以及各自人数,要求:分数低于 70 分的不参与分组,分组之后人数大于 2 个的
SELECT sex, AVG(math), COUNT(*) FROM stu WHERE math > 70 GROUP BY sex HAVING COUNT(*) > 2
注意:如果 SQL 语句过长,那么推荐换行写。
SELECT sex, AVG( math ), COUNT(*)
FROM stu
WHERE math > 70
GROUP BY sex
HAVING COUNT(*) > 2;
2
3
4
5
WHERE 和 HAVING 区别:
执行时机不一样:WHERE 是分组之前进行限定,不满足 WHERE 条件,则不参与分组,而 HAVING 是分组之后对结果进行过滤。
可判断的条件不一样:WHERE 不能对聚合函数进行判断,HAVING 可以。
# 约束
# 约束的概念
- 约束是作用于表中列上的规则,用于限制加入表的数据
- 约束的存在保证了数据库中数据的准确性,有效性和完整性
# 约束的分类
# 案例
根据需求,为表添加合适的约束。
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT, -- id主键一般配合自增长 AUTO_INCREMENT 来约束
ename VARCHAR ( 50 ) NOT NULL UNIQUE,
joindate DATE NOT NULL,
salary DOUBLE ( 7, 2 ) NOT NULL,
bonus DOUBLE ( 7, 2 ) DEFAULT 0
);
2
3
4
5
6
7
-- 建完表后添加非空约束
ALTER TABLE 表名 MODIFY 字段名 数据类型 NOT NULL;
-- 删除约束
ALTER TABLE 表名 MODIFY 字段名 数据类型;
-- 建完表后添加唯一约束
ALTER TABLE 表名 MODIFY 字段名 数据类型 UNIQUE;
-- 删除约束
ALTER TABLE 表名 DROP INDEX 字段名;
-- 建完表后添加主键约束
ALTER TABLE 表名 ADD PRIMARY KEY(字段名);
-- 删除约束
ALTER TABLE 表名 DROP PRIMARY KEY;
-- 建完表后添加默认约束
ALTER TABLE 表名 ALTER 列名 SET DEFAULT 默认值;
-- 删除约束
ALTER TABLE 表名 ALTER 列名 DROP DEFAULT;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
注意:虽然一张表只能有一个主键,但是该主键是可以由该张表的多个字段共同构成的!
CREATE TABLE 表名 (
...,
PRIMARY KEY (字段1, 字段2)
);
-- 或是在表创建后再:ALTER TABLE 表名 ADD PRIMARY KEY(字段1, 字段2);
2
3
4
5
6
# 外键约束
概念:外键用来将两个表的数据之间建立联结,保证数据的一致性和完整性。
举例:员工表中每个员工的部门信息来源于部门表。
一致性:员工的部门信息一定来源于部门表,信息一致。
完整性:要删除某一个部门,前提是属于该部门的员工都已经删除了。
员工表为 “从表”,部门表为 “主表”。
一定是先创建主表,再创建从表!
(1)添加约束
-- 创建表时添加外键约束
CREATE TABLE 表名 (
列名 数据类型,
...
[CONSTRAINT] [外键名称] FOREIGN KEY(外键列名) REFERENCES 主表(主表列名)
);
2
3
4
5
6
-- 键完表后添加外键约束
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(外键列名) REFERENCES 主表(主表列名);
2
(2)删除约束
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
案例:
-- 一定是先创建主表,再创建从表!
-- 部门表
CREATE TABLE dept (
id INT PRIMARY KEY AUTO_INCREMENT,
dep_name VARCHAR ( 20 ),
addr VARCHAR ( 20 )
);
-- 员工表
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR ( 20 ),
age INT,
dep_id INT,
-- 添加外键 dep_id 关联 dept 表的 id 主键
-- 外键通常命名为:fk_从表_主表
CONSTRAINT fk_emp_dept FOREIGN KEY(dep_id) REFERENCES dept(id)
);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19