身为前端掌握些简单的数据库知识是有益的,本文就来介绍下如何安装数据库 MySQL,以及如何对数据库进行些增删改查的操作。
简介
当需要存储大量数据时,为了方便增删改查等操作,我们会把数据存储在数据库中。MySQL 就是常用的关系型数据库,与之对应的如 MongoDB 则为非关系型数据库(更准确的说法应该是不仅仅是关系型数据库,即 Not only SQL)。使用 MySQL 可以创建多个关系型数据库,然后在每个数据库中我们又可以创建一个个二维数据表,不同数据表之间可以互相关联,然后利用 SQL 语句查询我们需要的数据。
下载安装
我们可以前往 MySQL 的官网下载 MySQL 的安装程序:
安装时只需按提示一步步进行安装就可以了。安装成功后,就可以在 windows 系统的服务窗口查看到 MySQL 正在运行:
配置环境变量
为了方便在任意目录下操作 MySQL 的可执行命令,可以将 mysql.exe 的路径添加到环境变量中:
之后即可直接打开命令行,输入 mysql --version
查看 MySQL 的版本,为最新的 8.4 版本:
连接 MySQL
安装好了 mysql 就可以进行连接了,下面介绍 2 种链接方式:
通过命令行
输入 mysql -uroot -p
,-u
的 u
就是 user,在安装时 MySQL 默认给我们提供的用户名为 root,-p
的 p
就是安装时设置的密码:
按下回车输入密码即可进行连接操作 :
我们也可以搜索打开 MySQL 8.4 Command Line Client,直接输入密码:
之后就连接上了 MySQL,可以输入 sql 语句开始操作了,比如查看所有的数据库,SHOW DATABASES;
也可以是小写,但这些关键字最好使用大写,注意要以 ;
结尾表示语句结束:
可以看到默认就存在 4 个数据库:
- information_schema:信息数据库,存储 MySQL 所维护的其它数据库、表,访问权限等信息;
- mysql:存储数据库管理者的用户和权限信息,还有一些日志信息等;
- performance_schema:性能数据库,存储 MySQL Server 数据库引擎运行时资源消耗的信息;
- sys:可以看成 information_schema 和 performance_schema 结合的简易版,里面的数据更容易理解。
通过图形化工具 navicat
如果不想直接在命令行对数据库进行操作,可以下载使用 navicat(我下载的是最新的 Navicat Premium 17) 来连接 MySQL:
输入密码即可建立连接:
SQL 语句
虽然有了图形化操作工具,我们可以直接对某个数据库的某张表里的数据进行操作,但在项目里我们一般还是需要通过 SQL(Structured Query Language,结构化查询语言) 语句来操作数据库的。我们可以直接在 navicat 点击"新建查询",然后在新打开的标签内输入 sql 语句,之后选中语句运行:
分类
SQL 语句非常的多,不过常见的关系型数据库使用的 SQL 语句都类似,所以我们主要是学习 MySQL 的 SQL 语句,它们可以分为 4 类:
DDL(Data definition language)
数据定义语言,用于对数据库或表本身进行增(CREATE)、改(ALTER)、删(DROP)等操作。
操作数据库
增(CREATE DATABASE)
比如创建名为 juejin 的数据库:
sql
CREATE DATABASE IF NOT EXISTS juejin;
IF NOT EXISTS
是为了防止重复添加同名数据库导致报错。执行后右击连接名,点击"刷新",即可看到新增了名为 juejin 的数据库:
也可以通过
sql
SHOW DATABASES;
查看所有的数据库,可以看到新增了 juejin:
然后可以使用 juejin 数据库:
sql
USE juejin;
并查看当前哪个数据库正在使用:
sql
SELECT DATABASE();
结果如下:
注意,如果数据库(或是表、字段)的名字恰巧同关键字一样,可以使用```` 包裹:
sql
CREATE DATABASE `DATABASE`;
删(DROP DATABASE)
如果想删库跑路,可以使用 DROP DATABASE 数据库名;
,为了防止删除不存在的数据库导致报错,一般会添加判断 IF EXISTS
:
sql
DROP DATABASE IF EXISTS juejin;
看到摘要消息为 'OK',说明删除成功:
操作表
增(CREATE TABLE)
先选择使用 juejin 数据库,然后添加名为 users 的表:
sql
CREATE TABLE IF NOT EXISTS users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(10) UNIQUE NOT NULL,
level INT DEFAULT 1
)
其中有 3 个字段, id、name 和 level。INT
表示需要是整数类型,VARCHAR(10)
表明存入的值的类型需为字符串类型,并且最多 10 个字符(characters,也就是说,如果是中文最多输入 10 个汉字,如果是英文也最多输入 10 个字母)。PRIMARY KEY
、AUTO_INCREMENT
、UNIQUE
、NOT NULL
和 DEFAULT
则是表约束。关于 MySQL 的数据类型和表约束,下文会有单独介绍。 然后可以使用:
sql
SHOW TABLES;
查看当前数据库中的所有表:
可以通过:
sql
DESC users;
查看表的描述(Describe ):
小提示:新增完表如果想在后续书写语句时得到关于新表的表名或字段提示,可以重启一下 navicat。
改(ALTER TABLE)
注意下是 alter(更改) 不是 alert(警报)。
对于表
- RENAME
如果想将原来的表名 users 更改为 members:
sql
ALTER TABLE users RENAME TO members;
对于字段
- ADD
如果想添加某个字段,比如想添加电话信息 phone,并且希望它具有唯一性:
sql
ALTER TABLE members ADD phone VARCHAR(11) UNIQUE;
如果想记录每次数据发生修改(包括新增)时的时间戳,可以这样:
sql
ALTER TABLE members ADD updateTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
也就是给 members 表添加了 updateTime 字段,格式为 TIMESTAMP
,默认值为 CURRENT_TIMESTAMP
即当前时间,并在记录发生更新时(ON UPDATE
),将值更新。
- CHANGE
如果你又想改改字段名,把 phone 改为 telephone:
sql
ALTER TABLE members CHANGE phone telephone VARCHAR(11) UNIQUE;
- MODIFY
如果你想更改某个字段的类型,比如你觉得 telephone 应该用 CHAR(11)
:
sql
ALTER TABLE members MODIFY telephone CHAR(11) UNIQUE;
更改完可以通过右击 members 打开 "设计表" 查看带有类型信息的表结构:
- DROP
最后你又想让自己显得更像是善于改需求的领导,决定删除电话字段 telephone:
sql
ALTER TABLE members DROP telephone;
删(DROP TABLE)
删除表和删除数据库的语句类似,比如我们想删除表 members:
sql
DROP TABLE IF EXISTS members;
DML(Data manipulation language)
数据操作语言,用于对表内的数据执行增(INSERT)、改(UPDATE)、删(DELETE)等操作。
增(INSERT INTO)
比如我们想往之前创建的表 members 里添加一条数据,可以直接通过 navicat 操作,输入完信息点击下图箭头所指的对勾符号生成数据:
如果想使用 SQL 语句插入新数据,则为:
sql
INSERT INTO members (`name`, `level`, telephone) VALUES ('Eson', 1, '15912341234');
查看表 members,可以看到添加了数据,由于 id 字段我们前面添加了 AUTO_INCREMENT
约束,所以会自动赋值:
改(UPDATE)
如果想修改某条数据,使用的是 UPDATE
关键字,在需要修改的字段前使用 SET
,并使用 WHERE
说明要修改的是哪一条数据:
sql
UPDATE members SET `level` = 2 WHERE id = 1;
注意,如果不写 WHERE id = 1
则会将整张表所有数据的 level 都改成 2。 也可以一次性修改多个字段的值,用 ,
分割即可:
sql
UPDATE members SET `level` = 3, telephone = '1871234134' WHERE id = 1;
删(DELETE FROM)
如果想删除 id 为 2 的这条数据:
sql
DELETE FROM members WHERE id = 2;
同样的,如果不使用 WHERE
,将会把整张表的所有数据删除。 注意,如果删除后再次执行添加数据操作,id 的值默认是继续自增的:
DQL(Data query language)
数据查询语言,主要是使用 SELECT
语句,配合 FROM
、WHERE
等对数据库进行查询操作。有时候 SELECT
也会被认为属于 DML 语句,我个人认为某条语句到底属于哪种分类并不是重点,分类是为了更好地掌握语句本身而已。
基本查询
比如想查询 members 表的所有记录:
sql
SELECT * FROM members;
*
就代表要查询所有字段,FROM
指明要从哪张表查询。 如果只需要查看某些字段,比如 name 和 level:
sql
SELECT `name`, `level` FROM members;
字段之间使用 ,
分割。结果如下:
如果字段之间不用 ,
号分割,就是给 name 字段起了个别名为 level,相当于:
sql
-- AS 可以省略
SELECT `name` AS `level` FROM members;
结果就变成:
条件查询
使用 WHERE
子句可以对查询对象进行筛选。比如想知道 level 大于等于 3 的数据都有哪些:
sql
SELECT * FROM members WHERE `level` >= 3;
比较运算符除了 >=
,也可以是 >
、<
、 =
、!=
等。 WHERE
之后还可以用逻辑与跟上多个判断,比如既要 level 大于等于 3,又要满足 name 为 'Jay':
sql
SELECT * FROM members WHERE `level` >= 3 && `name` = 'Jay';
&&
也可以使用 AND
替换。如果是逻辑或就使用 ||
或 OR
。 如果想查看 level 位于某个范围内的数据:
sql
SELECT * FROM members WHERE `level` >= 1 && `level` <= 3;
因为是包含 1 和 3 的,所以可以使用 BETWEEN AND
替换:
sql
SELECT * FROM members WHERE `level` BETWEEN 1 AND 3;
注意这里 AND
就不能使用 &&
替换了。 如果想查询某个字段的值是否符合多个结果中的一个:
sql
SELECT * FROM members WHERE `name` IN ('Jay', 'Eson', 'Jolin');
结果如下:
模糊查询
使用 LIKE
关键字,配合 %
与 _
使用,可以进行模糊查询。其中 %
表示任意个数的任意字符,比如要查询 name 的值是以 J 开头的记录:
sql
SELECT * FROM members WHERE `name` LIKE 'J%';
结果如下:
_
表示匹配 1 个任意字符,比如查询 name 为总共 3 个字符,前 2 个为 Ja 的记录:
sql
SELECT * FROM members WHERE `name` LIKE 'Ja_';
对查询结果排序
如果对结果的排序不满意,想让其按照 id 的升序排列,可以使用 ORDER BY
:
sql
SELECT * FROM members WHERE `name` IN ('Jay', 'Eson', 'Jolin') ORDER BY id ASC;
ASC
就是 ascending,意为升序,这里其实可以省略不写。
相对应的就是降序(descending)排列:
sql
SELECT * FROM members WHERE `name` IN ('Jay', 'Eson', 'Jolin') ORDER BY id DESC;
分页查询
使用 LIMIT
关键字表示要查询几条数据,OFFSET
表示要偏移几条数据开始查询:
javascript
SELECT * FROM members LIMIT 1 OFFSET 1;
也可以写成下面这样,第一个 1 代表 OFFSET
的值,第二个 1 为 LIMIT
的值:
javascript
SELECT * FROM members LIMIT 1, 1;
执行结果如下:
聚合函数(Aggregate Function)
如果我们想知道 members 表内所有人的平均 level,可以通过 MySQL 提供的聚合函数 ------ 对值集进行操作的函数 ------来帮助我们处理。值集就是一些值的集合,比如执行下列语句:
sql
SELECT `level` FROM members;
得到的就是所有记录的 level:
欲得到 level 的平均值,可以通过聚合函数 AVG()
:
sql
SELECT AVG(`level`) FROM members;
结果如下:
除了获取平均值,还有很多聚合函数,比如获取最大值的 MAX()
等,详见截取自官方文档的下表:
GROUP BY
聚合函数一般情况会配合 GROUP BY
子句使用,也就是对数据进行分组后再使用聚合函数计算。为了方便演示,我将 members 表的数据改成了如下所示,添加了代表地区的 region 字段,并增加了几条数据,修改了下 id:
现在,我们就可以根据地区来分组,并统计各个地区的平局 level:
sql
SELECT region, ROUND(AVG(`level`), 2) FROM members GROUP BY region;
这里使用了 ROUND()
将 AVG()
的计算结果处理成统一保留 2 位小数,结果如下:
如果想对经过 GROUP BY
得到的数据再次筛选,就不能使用 WHERE
了,要使用 HAVING
:
sql
SELECT region, AVG(`level`) FROM members GROUP BY region HAVING AVG(`level`) > 1;
小结
综合上述对于 SELECT 与其它子句的配合使用,可以小结如下:
sql
SELECT
select_expr [, select_expr] ...
[FROM table_references]
[WHERE where_condition]
[GROUP BY expr]
[HAVING where_condition]
[ORDER BY expr [ASC | DESC]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
另外,SELECT 语句内还可以包含子查询,即再次使用 SELECT 语句。
DCL(Data control language)
数据控制语言,主要是对数据库或表格的访问权限进行些控制的操作。篇幅有限,本文就不再多做介绍。
相关知识点补充
数据类型
之前在增加表的时候,我们会给表中的字段定义好类型,MySQL 中所支持的数据类型很多,包括数字类型、日期和时间类型、字符串类型,空间类型和 json 数据类型。
数字类型
光是数字类型,就可以分为整数类型和浮点数类型还有定点数类型,不过一般使用 INT 或 DOUBLE 类型即可。
- 整数类型( Integer Types)
整数类型又可以细分为以下几种:INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT,它们之间的区别可见下表:
其中 TINYINT 只有 1 字节,如果不带符号,只能表示 0 ~ 255 之间的数,可以用来表示布尔值,比如 true 为 1,false 为 0。
- 浮点数类型(Floating-Point Types)
浮点类型可以是 FLOAT(4 字节) 或 DOUBLE(8 字节),它们是用来表示近似值(Approximate Value)的,如果想精确地表示数字可以使用定点数类型。
- 定点数类型 (Fixed-Point Types)
分为 DECIMAL 与 NUMERIC,其中 DECIMAL 是 NUMERIC 的实现形式。
日期类型
日期类型也分为几种:
- YEAR 类型
以 'YYYY' 格式显示值,范围从 1901 到 2155,另外还有个 0000。
- DATE 类型
表示的值只有日期部分,没有时间部分,以 'YYYY-MM-DD' 格式显示值,范围从 '1000-01-01' 到 '9999-12-31'。
- DATETIME 类型
表示的值包含日期和时间,以 'YYYY-MM-DD hh:mm:ss' 格式显示值,范围从 '1000-01-01 00:00:00' 到 '9999-12-31 23:59:59'。
- TIMESTAMP 类型
同 DATETIME 类型一样,也是以 'YYYY-MM-DD hh:mm:ss' 格式来表示包含日期和时间的值,但支持的范围是 '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC。一般存储日期时间使用的就是 TIMESTAMP 类型。 注:DATETIME 与 TIMESTAMP 的值的 'ss' 部分可以有 6 位小数,比如 '1000-01-01 00:00:00.123456'。
字符串类型
- CHAR 类型
前面我们创建字符串字段时,赋予的类型都是 VARCHAR 类型的,其中的 VAR 代表的意思是 variable-length,即长度可变的,去掉 VAR 的 CHAR 类型,其的值是固定长度的,长度可以是 0 到 255 之间的值。当被检索时,如果输入时由于值没有达到指定长度而在其后面添加的空格,一般情况下会被去除。
- VARCHAR 类型
值为可变长度的字符串,长度可在 0 到 65535 之间指定。并且如果值的后面带有空格,在被检索时不会被删除。
- BINARY 和 VARBINARY 类型
它们和 CHAR、VARCHAR很相似,但它们是用来存储二进制字符串的,也就是说存储的是字节字符串而不是字符串。
- BLOB 和 TEXT 类型
分别用于存储非常大的二进制类型和字符串类型数据。
表约束
在创建表的某个字段时,我们可以在该字段的类型之后设置一些约束:
- 主键(PRIMARY KEY )
在一张表中,我们可以设置一个字段(最好是和业务无关的)为主键,来区分每一条记录的唯一性。作为主键的字段应该是唯一索引,并且不会为空(即 NOT NULL),如果没有设置 NOT NULL,则 MySQL 会隐式地设置为 NOT NULL。 主键也可以是多列索引(联合主键),比如在处理多对多关系中,我们会建立一张专门记录关系的表,此时主键就可以使用联合主键,诸如 PRIMARY KEY(member_id, course_id)
。
- 唯一(UNIQUE)
如果希望某个字段的值都具有唯一性,可以添加 UNIQUE 约束,使用 UNIQUE 约束的值可以为空(NULL)。
- 不可为空(NOT NULL)
NOT NULL 也是一个表约束,见名知意,表示字段不可为空。
- 默认值(DEFAULT)
让某个字段在没有赋值的时候能有个默认值。
- 自动递增(AUTO_INCREMENT)
让某个字段,比如 id 值,可以自动递增。
- 外键约束
之后会写篇文章谈及多表操作时再介绍。