一. MySQL 介绍和安装
1. 为什么需要数据库?
- 任何的软件系统都需要存放大量的数据,这些数据通常是非常复杂和庞大的:
- 比如用户信息包括姓名、年龄、性别、地址、身份证号、出生日期等
- 比如商品信息包括商品的名称、描述、价格(原价)、分类标签、商品图片等
- 比如歌曲信息包括歌曲的名称、歌手、专辑、歌曲时长、歌词信息、封面图片等
- 那么这些信息不能直接存储到文件中吗?可以,但是文件系统有很多的缺点:
- 很难以合适的方式组织数据(多张表之间的关系合理组织)
- 并且对数据进行增删改查中的复杂操作(虽然一些简单确实可以),并且保证单操作的原子性
- 很难进行数据共享,比如一个数据库需要为多个程序服务,如何进行很好的数据共享
- 需要考虑如何进行数据的高效备份、迁移、恢复
- 等等...
- 数据库通俗来讲就是一个存储数据的仓库,数据库本质上就是一个软件、一个程序
2. 常见的数据库有哪些?
- 通常我们将数据库划分成两类:关系型数据库 和 非关系型数据库
- 关系型数据库:
MySQL
、Oracle
、DB2
、SQL Server
、Postgre SQL
等- 关系型数据库通常我们会创建很多个二维数据表
- 数据表之间相互关联起来,形成一对一、一对多、多对多等关系
- 之后可以利用
SQL
语句在多张表中查询我们所需的数据
- 非关系型数据库:
MongoDB
、Redis
、Memcached
、HBse
等- 非关系型数据库的英文其实是
Not only SQL
,也简称为NoSQL
- 相当而言非关系型数据库比较简单一些,存储数据也会更加自由(甚至我们可以直接将一个复杂的
json
对象直接塞入到数据库中) NoSQL
是基于Key-Value
的对应关系,并且查询的过程中不需要经过SQL
解析
- 非关系型数据库的英文其实是
- 如何在开发中选择他们呢?具体的选择会根据不同的项目进行综合的分析,我这里给一点点建议:
- 目前在公司进行后端开发(
Node
、Java
、Go
等),还是以关系型数据库为主 - 在爬取大量的数据进行存储时,用到非关系型数据库的会比较常见
- 目前在公司进行后端开发(
3. 认识 MySQL
- 我们后面主要是开发自己的后端项目,所以我们以关系型数据库
MySQL
作为主要内容 MySQL
的介绍:MySQL
原本是一个开源的数据库,原开发者为瑞典的MySQL AB
公司- 在 2008 年被 Sun 公司收购;在 2009 年,Sun 被 Oracle 收购
- 所以目前
MySQL
归属于 Oracle
MySQL
是一个关系型数据库,其实本质上就是一款软件、一个程序:- 这个程序中管理着多个数据库
- 每个数据库中可以有多张表
- 每个表中可以有多条数据
4. 数据组织方式

5. 下载 MySQL 软件
根据自己的操作系统下载即可
推荐大家直接下载安装版本,在安装过程中会配置一些环境变量
Windows
推荐下载MSI
的版本Mac
推荐下载DMG
的版本
这里我们安装的是
MySQL
最新的版本:8.0.32(不再使用旧的MySQL5.x
的版本)
6. Windows 安装过程
















7. 启动 MySQL
命令行方式:
打开命令提示符(按
Win + R
,输入cmd
,然后按回车)。输入以下命令以确保MySQL服务正在运行:
shellnet start mysql # 上面提示服务名无效的话,就用mysql80 net start mysql80
- 如果MySQL服务已经运行,会显示“服务已经启动”的消息。如果没有运行,则会启动MySQL服务。
任务管理器手动启动方式:
window
检查mysql
是否启动:win
+x
=> 任务管理器 => 服务 ->MySQL80
启动
mac
二. MySQL 连接和 GUI 工具 Navicat
1. MySQL 的连接操作
默认我们安装了
mysql
是没有添加到环境变量中的,所以在终端是无法使用mysql
命令的可以通过
mysql
内置的命令行工具打开输入密码(默认是之前安装时,设置的
root account password
)但如果想在
cmd
终端查看呢?首先通过刚才的命令行工具找到
mysql
可执行程序的位置当我们在终端敲
mysql
时,其实想执行的是mysql.exe
程序,但是系统在去环境变量中查找的时候,是不知道该命令所对应的程序的,所以我们需要将如下图所示的文件夹配置到环境变量中,这样当在环境变量中查找的时候,就能查找到mysql.exe
可执行程序了或者我们直接在该文件夹中打开
cmd
时,是可以找到的,因为默认会先在该文件夹下查找配置环境变量
Mac
添加环境变量export PATH=$PATH:/usr/local/mysql/bin
这时,我们就可以在
cmd
中执行mysql
可执行命令了
2. 终端连接数据库
我们如果想要操作数据,需要先和数据建立一个连接,最直接的方式就是通过终端来连接
有两种方式来连接:
两种方式的区别在于输入密码是直接输入,还是另起一行以密文的形式输入
shell# 方式一:-p+密码 mysql -uroot -platerZc0123mysql # 方式二: mysql -uroot -p Enter password: your password
-u
:指定连接 MySQL 数据库的用户名,在这个例子中是root
。-p
:指示 MySQL 命令行客户端提示你输入密码。laterZc0123mysql
:这个密码就是你要输入的密码。
3. 终端操作数据库 – 显示数据库
我们说过,一个数据库软件中,可以包含很多个数据库,如何查看数据库?
命令行结尾标志:
;
或\g
mysqlshow databases;
MySQL
默认的数据库:infomation_schema
:信息数据库,其中包括MySQL
在维护的其他数据库、表、列、访问权限等信息performance_schema
:性能数据库,记录着MySQL Server
数据库引擎在运行过程中的一些资源消耗相关的信息mysql
:用于存储数据库管理者的用户信息、权限信息以及一些日志信息等sys
:相当于是一个简易版的performance_schema
,将性能数据库中的数据汇总成更容易理解的形式sakila
:示例数据库(sample database
),提供了一个标准的方案,可用于自学,写书,教程,文章以及示例等等。 此示例数据库还展示了mysql
的一些最新特性,比如视图(Views
),存储过程(Stored Procedures
),触发器(Triggers
)等
4. 终端操作数据库 – 创建数据库-表
在终端直接创建一个属于自己的新的数据库
coderhub
(一般情况下一个新的项目会对应一个新的数据库)mysqlcreate database coderhub;
使用我们创建的数据库
coderhub
:mysqluse coderhub;
在数据中,创建一张表:
mysqlcreate table user( name varchar(20), age int, height double ); # 插入数据 insert into user (name, age, height) values ('later-zc', 18, 1.88) insert into user (name, age, height) values ('zc', 18, 1.88)
5. GUI 工具的介绍
- 我们会发现在终端操作数据库有很多不方便的地方:
- 语句写出来没有高亮,并且不会有任何的提示
- 复杂的语句分成多行,格式看起来并不美观,很容易出现错误
- 终端中查看所有的数据库或者表非常的不直观和不方便
- 等等...
- 所以在开发中,我们可以借助于一些
GUI
工具来帮助我们连接上数据库,之后直接在GUI
工具中操作就会非常方便 - 常见的
MySQL
的GUI
工具有很多,这里推荐几款:Navicat
:个人最喜欢的一款工具,但是收费的(有免费的试用时间)SQLYog
:一款免费的SQL
工具TablePlus
:常用功能都可以使用,但是会多一些限制(比如只能开两个标签页)
2. 安装 Navicat

Navicat Premium 16
下载与安装破解教程(详细教程)https://learnku.com/articles/67706Navicat Premium 12.0.24
安装及其破解方法: https://www.cnblogs.com/djwhome/p/12307693.htmlNavicat Premium 12
链接MySQL8.0.11
数据库报2059
错误: https://www.cnblogs.com/VseYoung/p/10048051.html
三. SQL 语句和数据类型
1. 认识 SQL 语句
- 我们希望操作数据库(特别是在程序中),就需要有和数据库沟通的语言,这个语言就是
SQL
:SQL
是Structured Query Language
,称之为结构化查询语言,简称SQL
- 使用
SQL
编写出来的语句,就称之为SQL
语句 SQL
语句可以用于对数据库进行操作
- 事实上,常见的关系型数据库
SQL
语句都是比较相似的,所以你学会了MySQL
中的SQL
语句,之后去操作比如Oracle
或者其他关系型数据库,也是非常方便的 SQL
语句的常用规范:- 通常关键字使用大写的,比如
CREATE
、TABLE
、SHOW
等等 - 一条语句结束后,需要以
;
结尾 - 如果遇到关键字作为表名或者字段名称,可以使用
``
包裹
- 通常关键字使用大写的,比如
2. SQL 语句的分类
- 常见的
SQL
语句我们可以分成四类: DDL
(Data Definition Language):数据定义语言- 可以通过
DDL
语句对数据库或者表进行:创建、删除、修改等操作
- 可以通过
DML
(Data Manipulation Language):数据操作语言- 可以通过
DML
语句对表进行:添加、删除、修改等操作
- 可以通过
DQL
(Data Query Language):数据查询语言- 可以通过
DQL
从数据库中查询记录
- 可以通过
DCL
(Data Control Language):数据控制语言- 对数据库、表格的权限进行相关访问控制操作
3. SQL 的数据类型 – 数字类型
我们知道不同的数据会划分为不同的数据类型,在数据库中也是一样:
MySQL
支持的数据类型有:数字类型,日期和时间类型,字符串(字符和字节)类型,空间类型和JSON
数据类型
数字类型
MySQL
的数字类型有很多:- 整数数字类型:
INTEGER
,INT
,SMALLINT
,TINYINT
,MEDIUMINT
,BIGINT
- 浮点数字类型:
FLOAT
,DOUBLE
(FLOAT
是 4 个字节,DOUBLE
是 8 个字节) - 精确数字类型:
DECIMAL
,NUMERIC
(DECIMAL
是NUMERIC
的实现形式)
- 浮点数字类型:
FLOAT
,DOUBLE
(FLOAT
是 4 个字节,DOUBLE
是 8 个字节) - 精确数字类型:
DECIMAL
,NUMERIC
(DECIMAL
是NUMERIC
的实现形式)
4. SQL 的数据类型 – 日期类型
MySQL
的日期类型也很多:YEAR
以YYYY
格式显示值- 范围 1901 到 2155,和 0000
DATE
类型用于具有日期部分但没有时间部分的值:DATE
以格式YYYY-MM-DD
显示值- 支持的范围是
1000-01-01
到9999-12-31
DATETIME
类型用于包含日期和时间部分的值:DATETIME
以格式'YYYY-MM-DD hh:mm:ss'
显示值- 支持的范围是
1000-01-01 00:00:00
到9999-12-31 23:59:59
TIMESTAMP
数据类型被用于同时包含日期和时间部分的值:TIMESTAMP
以格式'YYYY-MM-DD hh:mm:ss'
显示值- 但是它的范围是
UTC
的时间范围:'1970-01-01 00:00:01'
到'2038-01-19 03:14:07'
另外:
DATETIME
或TIMESTAMP
值可以包括在高达微秒(6 位)精度的后小数秒一部分- 比如
DATETIME
表示的范围可以是'1000-01-01 00:00:00.000000'
到'9999-12-31 23:59:59.999999'
- 比如
5. SQL 的数据类型 – 字符串类型
MySQL
的字符串类型表示方式如下:CHAR
类型在创建表时为固定长度,长度可以是 0~255 之间的任何值- 在被查询时,会删除后面的空格
VARCHAR
类型的值是可变长度的字符串,长度可以指定为 0~65535 之间的值- 在被查询时,不会删除后面的空格
BINARY
和VARBINARY
类型用于存储二进制字符串,存储的是字节字符串
https://dev.mysql.com/doc/refman/8.0/en/binary-varbinary.html
BLOB
用于存储大的二进制类型TEXT
用于存储大的字符串类型
四. SQL 语句 - DDL 语句
1. 对数据库进行操作
-- 1.查看所有数据库
SHOW DATABASES;
-- 2.使用某一个数据库
USE coderhub;
-- 3.查看当前正在使用的数据库
SELECT DATABASE();
-- 4.创建一个新的数据库(如果已存在, 会报错)
CREATE DATABASE test_demo;
-- 5.创建一个新的数据库(如果已存在, 也不会报错)
CREATE DATABASE IF NOT EXISTS test_demo;
-- 6.删除某一个数据库(如果不存在, 会报错)
DROP DATABASE IF EXISTS test_demo;
-- 7.删除某一个数据库(如果不存在, 也不会报错)
DROP DATABASE IF EXISTS test_demo;
-- 8.修改数据库的字符集和排序规则
ALTER DATABASE test_demo CHARACTER SET = utf8 COLLATE = utf8_unicode_ci;
2. 数据表的操作
-- 1.查看当前数据库中的所有数据表
SHOW TABLES;
-- 2.查看某一个表结构
DESC t_user;
-- 3.创建数据表
-- 3.1 创建基本表结构
CREATE TABLE IF NOT EXISTS `t_student`(
name VARCHAR(20),
age INT,
height DOUBLE
);
-- 3.2 创建完整表结构
CREATE TABLE IF NOT EXISTS `t_users`(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20) UNIQUE NOT NULL,
level INT DEFAULT 0,
telphone VARCHAR(20) UNIQUE
);
-- -- 4.删除表
DROP TABLE IF EXISTS `t_user`;
3. 表约束
- 主键:
PRIMARY KEY
- 一张表中,我们为了区分每一条记录的唯一性,必须有一个字段是永远不会重复,并且不会为空的,这个字段我们通常会将它设置为主键:
- 主键是表中唯一的索引
- 并且必须是
NOT NULL
的,如果没有设置NOT NULL
,那么MySQL
也会隐式的设置为NOT NULL
- 主键也可以是多列索引,
PRIMARY KEY(key_part, ...)
,我们一般称之为联合主键 - 建议:开发中主键字段应该是和业务无关的,尽量不要使用业务字段来作为主键
- 唯一:
UNIQUE
- 某些字段在开发中我们希望是唯一的,不会重复的,比如手机号码、身份证号码等,这个字段我们可以使用
UNIQUE
来约束:- 使用
UNIQUE
约束的字段在表中必须是不同的 UNIQUE
索引允许NULL
包含的列具有多个值NULL
- 使用
- 不能为空:
NOT NULL
- 某些字段我们要求用户必须插入值,不可以为空,这个时候我们可以使用
NOT NULL
来约束
- 某些字段我们要求用户必须插入值,不可以为空,这个时候我们可以使用
- 默认值:
DEFAULT
- 某些字段我们希望在没有设置值时,给予一个默认值,这个时候我们可以使用
DEFAULT
来完成
- 某些字段我们希望在没有设置值时,给予一个默认值,这个时候我们可以使用
- 自动递增:
AUTO_INCREMENT
- 某些字段我们希望不设置值时,可以进行递增,比如用户的
id
,这个时候可以使用AUTO_INCREMENT
来完成
- 某些字段我们希望不设置值时,可以进行递增,比如用户的
- 外键约束也是最常用的一种约束手段,等到讲到多表关系时,再进行讲解
4. 创建一个完整的表
CREATE TABLE IF NOT EXISTS `t_users`(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20) UNIQUE NOT NULL,
level INT DEFAULT 0,
telphone VARCHAR(20) UNIQUE
);
5. 修改表
-- 修改表名字
ALTER TABLE `t_users` RENAME TO `t_user`;
-- 添加新的字段
ALTER TABLE `t_user` ADD `createTime` TIMESTAMP;
ALTER TABLE `t_user` ADD `UPDATE` TIMESTAMP;
-- 修改字段的名称及数据类型
ALTER TABLE `t_user` CHANGE `createTime` `createAt` DATETIME;
-- 删除某一个字段(列)
ALTER TABLE `t_user` DROP `UPDATE`;
-- 修改某一个字段的数据类型
ALTER TABLE `t_user` MODIFY `id` BIGINT;
五. SQL 语句 - DML 语句
DML
:Data Manipulation Language
(数据操作语言)mysql-- 1.新建商品表 CREATE TABLE IF NOT EXISTS `t_products`( id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(20) UNIQUE NOT NULL, description VARCHAR(200) DEFAULT '', price DOUBLE DEFAULT 0, publishTime DATETIME ); -- 2.DML语句:插入数据 -- INSERT INTO `t_products` (字段的名称列表) VALUES (值的列表) INSERT INTO `t_products` (title, description, price, publishTime) VALUES ('iphone', 'hello world', 100, '2002-09-10'); -- 3.DML语句:删除数据 -- 3.1 删除表中所有的数据(慎重使用!!!) DELETE FROM `t_products`; -- 3.2 根据id删除某一条 DELETE FROM `t_products` WHERE id = 1; -- 4.DML语句:修改数据 -- 4.1 修改表中所有的数据 UPDATE `t_products` SET `price` = 888; -- 4.2 根据条件修改某一条数据 UPDATE `t_products` SET `price` = 888 WHERE id = 5; UPDATE `t_products` SET `price` = 999, `title` = 'iphone' WHERE id = 5; -- 5.扩展:当修改某一条数据时,使用最新的时间记录 ALTER TABLE `t_products` ADD `updateTime` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
六. SQL 语句 - DQL 语句
1. DQL 语句
DQL
:Data Query Language
(数据查询语言)SELECT
用于从一个或多个表中检索选中的行(Record
)
查询格式如下:
mysqlSELECT select_expr [, select_expr]... [FROM table_references] [WHERE where_condition] [ORDER BY expr [ASC | DESC]] [LIMIT {[offset,] row_count | row_count OFFSET offset}] [GROUP BY expr] [HAVING where_condition]
2. 准备数据
准备一张表
mysqlCREATE TABLE IF NOT EXISTS `products` ( id INT PRIMARY KEY AUTO_INCREMENT, brand VARCHAR(20), title VARCHAR(100) NOT NULL, price DOUBLE NOT NULL, score DECIMAL(2,1), voteCnt INT, url VARCHAR(100), pid INT );
jsconst mysql = require('mysql2') // npm i mysql2 const connection = mysql.createConnection({ host: 'localhost', port: 3306, user: 'root', password: 'laterZc0123mysql', database: 'coderhub', }) const statement = `INSERT INTO products SET ?;` const phoneJson = require('./phone.json') for (let phone of phoneJson) { connection.query(statement, phone) }
3. 基本查询
我们也可以给字段起别名:
- 别名一般在多张表或者给客户端返回对应的
key
时会使用到
mysql-- 1.基本查询 -- 1.1 查询所有的数据的所有字段 SELECT * FROM `products`; -- 1.2 查询所有的数据,并指定对应的字段 SELECT id, brand, price, title FROM `products`; -- 1.3 查到字段之后,给字段重命名(起别名,AS关键字可以省略) SELECT id AS phoneId, brand AS phoneBrand, title, price FROM `products`; SELECT id phoneId, brand phoneBrand, title, price FROM `products`;
- 别名一般在多张表或者给客户端返回对应的
4. where 条件查询
在开发中,我们希望根据条件来筛选我们的数据,这个时候我们要使用条件查询:
- 条件查询会使用
WEHRE
查询子句
- 条件查询会使用
WHERE
的比较运算符mysql-- 2.条件查询(比较运算符) -- 2.1 查询所有价格小于1000的手机 SELECT * FROM `products` WHERE price < 1000; -- 2.2 查询所有价格大于等于2000的手机 SELECT * FROM `products` WHERE price >= 2000; -- 2.3 查询所有价格等于8699的手机 SELECT * FROM `products` WHERE price = 8699; -- 2.4 查询所有华为品牌的手机 SELECT * FROM `products` WHERE brand = '华为'; -- 2.5 查询所有非苹果品牌的手机 SELECT * FROM `products` WHERE brand != '苹果';
WHERE
的逻辑运算符mysql-- 3.条件查询(逻辑运算符) -- 3.1 查询价格小于2000的华为手机 SELECT * FROM `products` WHERE brand = '华为' && price < 2000; SELECT * FROM `products` WHERE brand = '华为' AND price < 2000; -- 3.2 查询品牌为华为或价格大于5000的手机 SELECT * FROM `products` WHERE brand = '华为' || price > 5000; SELECT * FROM `products` WHERE brand = '华为' or price > 5000; -- 3.3 查询价格在1000-2000的手机 SELECT * FROM `products` WHERE price >= 1000 && price <= 2000; SELECT * FROM `products` WHERE price BETWEEN 1000 AND 2000; -- 3.4 枚举出多个结果,其中之一:小米或华为 SELECT * FROM `products` WHERE brand = '小米' OR brand = '华为'; SELECT * FROM `products` WHERE brand = '小米' || brand = '华为'; SELECT * FROM `products` WHERE brand IN ('小米', '华为');
模糊查询使用
LIKE
关键字,结合两个特殊的符号:%
表示匹配任意个的任意字符_
表示匹配一个的任意字符
mysql-- 4.条件查询(模糊查询) -- 4.1 查询所有title以v开头的数据 SELECT * FROM `products` WHERE `title` LIKE 'v%'; -- 4.2 查询所有title带v的数据 SELECT * FROM `products` WHERE `title` LIKE '%v%'; -- 4.3 查询title第五个字符为v的数据 SELECT * FROM `products` WHERE `title` LIKE '____v%';
5. 查询结果排序
当我们查询到结果的时候,我们希望将查询结果按照某种方式进行排序,这个时候使用的是
ORDER BY
ORDER BY
有两个常用的值:ASC
(ascending sort)
:升序排列DESC
(descending sort)
:降序排列
mysql-- 5.对结果进行排序(ORDER BY) -- 5.1 查询所有的价格小于1000的手机,并且按照评分的降序获取结果 SELECT * FROM `products` WHERE `price` < 1000 ORDER BY `score` DESC; -- 5.2 查询所有的价格小于1000的手机,并且按照价格的升序获取结果 SELECT * FROM `products` WHERE `price` < 1000 ORDER BY `price` ASC;
6. 分页查询
当数据库中的数据非常多时,一次性查询到所有的结果进行显示是不太现实的:
- 在真实开发中,我们都会要求用户传入
offset
、limit
或者page
等字段 - 它们的目的是让我们可以在数据库中进行分页查询
- 它的用法有
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
mysql-- 6.对表进行分页查询 -- 6.1 查询20条数据(默认从第一条开始) SELECT * FROM `products` LIMIT 20; -- 6.2 查询20条数据(偏移30条) SELECT * FROM `products` LIMIT 20 OFFSET 30; -- 6.3 另外一种写法:offset, row_count -- 查询30条数据(偏移20条) SELECT * FROM `products` LIMIT 20, 30;
- 在真实开发中,我们都会要求用户传入