Skip to content

一. MySQL 介绍和安装


1. 为什么需要数据库?

  • 任何的软件系统都需要存放大量的数据,这些数据通常是非常复杂和庞大的:
    • 比如用户信息包括姓名、年龄、性别、地址、身份证号、出生日期等
    • 比如商品信息包括商品的名称、描述、价格(原价)、分类标签、商品图片等
    • 比如歌曲信息包括歌曲的名称、歌手、专辑、歌曲时长、歌词信息、封面图片等
  • 那么这些信息不能直接存储到文件中吗?可以,但是文件系统有很多的缺点
    • 很难以合适的方式组织数据(多张表之间的关系合理组织)
    • 并且对数据进行增删改查中的复杂操作(虽然一些简单确实可以),并且保证单操作的原子性
    • 很难进行数据共享,比如一个数据库需要为多个程序服务,如何进行很好的数据共享
    • 需要考虑如何进行数据的高效备份、迁移、恢复
    • 等等...
  • 数据库通俗来讲就是一个存储数据的仓库,数据库本质上就是一个软件、一个程序

2. 常见的数据库有哪些?

  • 通常我们将数据库划分成两类:关系型数据库 和 非关系型数据库
  • 关系型数据库MySQLOracleDB2SQL ServerPostgre SQL
    • 关系型数据库通常我们会创建很多个二维数据表
    • 数据表之间相互关联起来,形成一对一、一对多、多对多等关系
    • 之后可以利用 SQL 语句在多张表中查询我们所需的数据
  • 非关系型数据库MongoDBRedisMemcachedHBse
    • 非关系型数据库的英文其实是 Not only SQL,也简称为 NoSQL
    • 相当而言非关系型数据库比较简单一些,存储数据也会更加自由(甚至我们可以直接将一个复杂的 json 对象直接塞入到数据库中)
    • NoSQL 是基于 Key-Value 的对应关系,并且查询的过程中不需要经过 SQL 解析
  • 如何在开发中选择他们呢?具体的选择会根据不同的项目进行综合的分析,我这里给一点点建议:
    • 目前在公司进行后端开发(NodeJavaGo 等),还是以关系型数据库为主
    • 在爬取大量的数据进行存储时,用到非关系型数据库的会比较常见

3. 认识 MySQL

  • 我们后面主要是开发自己的后端项目,所以我们以关系型数据库 MySQL 作为主要内容
  • MySQL 的介绍:
    • MySQL 原本是一个开源的数据库,原开发者为瑞典的 MySQL AB 公司
    • 在 2008 年被 Sun 公司收购;在 2009 年,Sun 被 Oracle 收购
    • 所以目前 MySQL 归属于 Oracle
  • MySQL 是一个关系型数据库,其实本质上就是一款软件、一个程序:
    • 这个程序中管理着多个数据库
    • 每个数据库中可以有多张表
    • 每个表中可以有多条数据

4. 数据组织方式

image-20230217154118235

5. 下载 MySQL 软件

  • 下载地址:https://dev.mysql.com/downloads/mysql/

  • 根据自己的操作系统下载即可

    image-20230217160808357
  • 推荐大家直接下载安装版本,在安装过程中会配置一些环境变量

    • Windows 推荐下载 MSI 的版本
    • Mac 推荐下载 DMG 的版本
  • 这里我们安装的是 MySQL 最新的版本:8.0.32(不再使用旧的 MySQL5.x 的版本)

    image-20230217160905443

6. Windows 安装过程

image-20230217161911414image-20230217161828996image-20230217162016156image-20230217162042406image-20230217162311063image-20230217162330744image-20230217162450133image-20230217162631701image-20230217163111142image-20230217163810971image-20230217163945427image-20230217164102043image-20230217164211677image-20230217164323808image-20230217164358709image-20230217164521067

7. 启动 MySQL

  • 命令行方式:

    • 打开命令提示符(按 Win + R,输入 cmd,然后按回车)。

    • 输入以下命令以确保MySQL服务正在运行:

      shell
      net start mysql 
      # 上面提示服务名无效的话,就用mysql80
      net start mysql80
      • 如果MySQL服务已经运行,会显示“服务已经启动”的消息。如果没有运行,则会启动MySQL服务。
  • 任务管理器手动启动方式:

    • window 检查 mysql 是否启动:win + x => 任务管理器 => 服务 -> MySQL80 启动
    image-20230217165152788
  • mac

    image-20230217165231415

二. MySQL 连接和 GUI 工具 Navicat


1. MySQL 的连接操作

  • 默认我们安装了 mysql 是没有添加到环境变量中的,所以在终端是无法使用 mysql 命令的

    image-20230217170200189
  • 可以通过 mysql 内置的命令行工具打开

    image-20230217170011533
  • 输入密码(默认是之前安装时,设置的 root account password

    image-20230217165742309

  • 但如果想在 cmd 终端查看呢?

  • 首先通过刚才的命令行工具找到 mysql 可执行程序的位置

    image-20230217170538488image-20230217170746941image-20230217171009034
  • 当我们在终端敲 mysql 时,其实想执行的是 mysql.exe 程序,但是系统在去环境变量中查找的时候,是不知道该命令所对应的程序的,所以我们需要将如下图所示的文件夹配置到环境变量中,这样当在环境变量中查找的时候,就能查找到 mysql.exe 可执行程序了

    image-20230217171247657
  • 或者我们直接在该文件夹中打开 cmd 时,是可以找到的,因为默认会先在该文件夹下查找

    image-20230217171609260image-20230217171640257
  • 配置环境变量

    image-20230217172058368image-20230217172344950
  • Mac 添加环境变量

    export PATH=$PATH:/usr/local/mysql/bin
  • 这时,我们就可以在 cmd 中执行 mysql 可执行命令了

    image-20230217172441194

2. 终端连接数据库

  • 我们如果想要操作数据,需要先和数据建立一个连接,最直接的方式就是通过终端来连接

  • 有两种方式来连接:

    • 两种方式的区别在于输入密码是直接输入,还是另起一行以密文的形式输入

      shell
      # 方式一:-p+密码
      mysql -uroot -platerZc0123mysql
      
      # 方式二:
      mysql -uroot -p
      Enter password: your password

      -u:指定连接 MySQL 数据库的用户名,在这个例子中是 root

      -p:指示 MySQL 命令行客户端提示你输入密码。

      laterZc0123mysql:这个密码就是你要输入的密码。

    image-20230217173130827

3. 终端操作数据库 – 显示数据库

  • 我们说过,一个数据库软件中,可以包含很多个数据库,如何查看数据库?

  • 命令行结尾标志:;\g

    mysql
    show databases;
    image-20230217174019880
  • MySQL 默认的数据库:

    • infomation_schema:信息数据库,其中包括 MySQL 在维护的其他数据库、表、列、访问权限等信息
    • performance_schema:性能数据库,记录着 MySQL Server 数据库引擎在运行过程中的一些资源消耗相关的信息
    • mysql:用于存储数据库管理者的用户信息、权限信息以及一些日志信息等
    • sys:相当于是一个简易版的 performance_schema,将性能数据库中的数据汇总成更容易理解的形式
    • sakila:示例数据库(sample database),提供了一个标准的方案,可用于自学,写书,教程,文章以及示例等等。 此示例数据库还展示了 mysql 的一些最新特性,比如视图(Views),存储过程(Stored Procedures),触发器(Triggers)等

4. 终端操作数据库 – 创建数据库-表

  • 在终端直接创建一个属于自己的新的数据库 coderhub(一般情况下一个新的项目会对应一个新的数据库)

    mysql
    create database coderhub;
    image-20230217175035178
  • 使用我们创建的数据库 coderhub

    mysql
    use coderhub;
    image-20230217175100096
  • 在数据中,创建一张表:

    mysql
    create 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)
    image-20230217182057035

5. GUI 工具的介绍

  • 我们会发现在终端操作数据库有很多不方便的地方:
    • 语句写出来没有高亮,并且不会有任何的提示
    • 复杂的语句分成多行,格式看起来并不美观,很容易出现错误
    • 终端中查看所有的数据库或者表非常的不直观和不方便
    • 等等...
  • 所以在开发中,我们可以借助于一些 GUI 工具来帮助我们连接上数据库,之后直接在 GUI 工具中操作就会非常方便
  • 常见的 MySQLGUI 工具有很多,这里推荐几款:
    • Navicat:个人最喜欢的一款工具,但是收费的(有免费的试用时间)
    • SQLYog:一款免费的 SQL 工具
    • TablePlus:常用功能都可以使用,但是会多一些限制(比如只能开两个标签页)

2. 安装 Navicat

image-20230217192411409

三. SQL 语句和数据类型


1. 认识 SQL 语句

  • 我们希望操作数据库(特别是在程序中),就需要有和数据库沟通的语言,这个语言就是 SQL
    • SQLStructured Query Language,称之为结构化查询语言,简称 SQL
    • 使用 SQL 编写出来的语句,就称之为 SQL 语句
    • SQL 语句可以用于对数据库进行操作
  • 事实上,常见的关系型数据库 SQL 语句都是比较相似的,所以你学会了 MySQL 中的 SQL 语句,之后去操作比如 Oracle 或者其他关系型数据库,也是非常方便的
  • SQL 语句的常用规范:
    • 通常关键字使用大写的,比如 CREATETABLESHOW 等等
    • 一条语句结束后,需要以;结尾
    • 如果遇到关键字作为表名或者字段名称,可以使用 `` 包裹

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 的数字类型有很多:
    • 整数数字类型:INTEGERINTSMALLINTTINYINTMEDIUMINTBIGINT
    • 浮点数字类型:FLOATDOUBLEFLOAT 是 4 个字节,DOUBLE是 8 个字节)
    • 精确数字类型:DECIMALNUMERICDECIMALNUMERIC 的实现形式)
    image-20230222213153641
    • 浮点数字类型:FLOATDOUBLEFLOAT 是 4 个字节,DOUBLE 是 8 个字节)
    • 精确数字类型:DECIMALNUMERICDECIMALNUMERIC 的实现形式)

4. SQL 的数据类型 – 日期类型

  • MySQL 的日期类型也很多:

  • YEARYYYY 格式显示值

    • 范围 1901 到 2155,和 0000
  • DATE 类型用于具有日期部分但没有时间部分的值:

    • DATE 以格式 YYYY-MM-DD 显示值
    • 支持的范围是 1000-01-019999-12-31
  • DATETIME 类型用于包含日期和时间部分的值:

    • DATETIME 以格式 'YYYY-MM-DD hh:mm:ss' 显示值
    • 支持的范围是 1000-01-01 00:00:009999-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'
  • 另外:DATETIMETIMESTAMP 值可以包括在高达微秒(6 位)精度的后小数秒一部分

    • 比如 DATETIME 表示的范围可以是 '1000-01-01 00:00:00.000000' '9999-12-31 23:59:59.999999'
    image-20230222213756586

5. SQL 的数据类型 – 字符串类型

  • MySQL 的字符串类型表示方式如下:

  • CHAR 类型在创建表时为固定长度,长度可以是 0~255 之间的任何值

    • 在被查询时,会删除后面的空格
  • VARCHAR 类型的值是可变长度的字符串,长度可以指定为 0~65535 之间的值

    • 在被查询时,不会删除后面的空格
    • BINARYVARBINARY 类型用于存储二进制字符串,存储的是字节字符串
  • https://dev.mysql.com/doc/refman/8.0/en/binary-varbinary.html

  • BLOB 用于存储大的二进制类型

  • TEXT 用于存储大的字符串类型

    image-20230222233943945

四. SQL 语句 - DDL 语句


1. 对数据库进行操作

mysql
-- 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. 数据表的操作

mysql
-- 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. 创建一个完整的表

mysql
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. 修改表

mysql
-- 修改表名字
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 语句


  • DMLData 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 语句

  • DQLData Query Language(数据查询语言)

    • SELECT 用于从一个或多个表中检索选中的行Record
  • 查询格式如下:

    mysql
    SELECT 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. 准备数据

  • 准备一张表

    mysql
    CREATE 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
    );
    js
    const 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. 分页查询

  • 当数据库中的数据非常多时,一次性查询到所有的结果进行显示是不太现实的:

    • 在真实开发中,我们都会要求用户传入 offsetlimit 或者 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;

Released under the MIT License.