开篇寄语
这几天,伯衡君正在深入的学习 MySQL 相关知识,从基础到进阶,此前只是结合一些实例进行了简单了解,这次深入学习后,熟练度和理解度大大提高,按照费曼学习法,如果能给一个对 MySQL 一窍不懂的人讲明白,那就说明真正掌握了,于是就有了这一篇 MySQL 简明教程。
前情提要
- 《一文以Node.js 连接 MySQL为例操作数据库》
- 《一文以Python连接 MySQL为例操作数据库》
- 《使用 MySQL 和 Node.js 构建 API》
- 《使用 Node.js 爬虫后将数据储存到MySQL数据库并生成API调用》
- 《由兴趣使然的学习方法,帮助你触类旁通》
官方网站
内容详情
数据库市场中以 Mysql 市场占有率最高,所以学习内容自然也以按照需求来,至于其他数据库,可以参看下面这张图。
不过嘛,数据库也大同小异,学会了 MySQL,其他数据库也能驾轻就熟。
MySQL 是一个非常流行的开源关系数据库管理系统,它有什么特征呢?
- MySQL 是一个关系数据库管理系统
- MySQL 是开源免费的
- MySQL 是小型和大型应用程序的理想选择
- MySQL 非常快速、可靠、可扩展且易于使用
- MySQL 是跨平台的
- MySQL 符合 ANSI SQL 标准
- MySQL 于 1995 年首次发布
- MySQL 由 Oracle Corporation 开发、分发和支持
- MySQL 以联合创始人 Monty Widenius 的女儿命名:My
使用 MySQL 的大型和小型网站有很多,比如 Google, Youtube, Facebook 等等,特别说一下,本站也是使用 MySQL 哦。
想必大家都用过 Excel,其中的表格就和本篇文章所学的 MySQL 类似,每个数据库都由一个个表格组成,它们可以相互关联,一起组成了该数据库,参考下表:
ID | 网站 | 时间 |
1 | Forever | |
2 | Luckydesigner.space | Forever |
下载安装好 MySQLWorkbench 后打开,就可以开始本次的 MySQL 学习之旅了。
数据库及表格创建
首先是命令创建一个数据库,用以下命令:
CREATE DATABASE demoDB; /* 创建了一个名为 demoDB 的数据库 */
创建好了,觉得不满意?可以删除它,用以下命令:
DROP DATABASE demoDB;
这里要注意一下,如果不小心使用了该命令,那么该数据库下的表格都将消失不见,所以请谨慎使用。
想看是不是已经将其删除,只需要输入以下命令,显示所有数据库:
SHOW DATABASES;
创建了一个 demoDB 数据库后,如何创建第一个表格呢?请输入以下命令:
CREATE TABLE StockStatus ( ID int, StockName varchar(255) NOT NULL, PriceDay float(24), Country varchar(255), DateInput date, PRIMARY KEY (ID) );
创建了一个名为 StockStatus 的表格,包含:ID, StockName, PriceDay, Country, DateInput,其中设置 ID 为主键,PRIMARY KEY (ID) 表示其包含唯一值,并且不能包含 NULL 值。运行后,StockStatus 表格就创建好了。
如果想删除该表格,则需要输入以下命令:
DROP TABLE StockStatus;
删除表格内的所有分栏,则需要用到以下命令:
TRUNCATE TABLE StockStatus;
凡是涉及到表格的增加列名,修改列名,删减列名,统一用 “ALTER TABLE”。
增加列名
ALTER TABLE StockStatus ADD PredicPrice float(24);
修改列名
ALTER TABLE StockStatus MODIFY COLUMN PredicPrice float(48) NOT NULL;
删除列名
ALTER TABLE StockStatus DROP PredicPrice;
在创建表的时候,可以看到添加列名的时候出现了 “NOT NULL” 这一限制条件,除了它之外,还有很多很常见的,分别用实例来看一下它们都是起到什么作用。
NOT NULL
默认情况下,列可以包含 NULL 值,NOT NULL 约束强制列不接受 NULL 值。
PRIMARY KEY
PRIMARY KEY 约束唯一标识表中的每条记录,主键必须包含 UNIQUE 值,并且不能包含 NULL 值。
一张表只能有一个主键;在表中,这个主键可以由单个或多个列(字段)组成。试举一例:
CREATE TABLE StockStatus ( ID int, StockName varchar(255), PriceDay float(24), Country varchar(255), DateInput date, PRIMARY KEY (ID) );
还可以设置多个栏目共同组成一个 PRIMARY KEY,试举一例:
CREATE TABLE StockStatus ( ID int, StockName varchar(255), PriceDay float(24), Country varchar(255), DateInput date, CONSTRAINT UN_Stock PRIMARY KEY (ID,StockName) );
用 ALTER TABLE 增加,修改,删除时,分别输入的命令如下:
增加
ALTER TABLE StockStatus ADD PRIMARY KEY (ID);
增加多列共同组成一个 PRIMARI KEY:
ALTER TABLE StockStatus ADD CONSTRAINT UN_Stock UNIQUE (ID,StockName);
删除
ALTER TABLE StockStatus DROP PRIMARY KEY;
UNIQUE
UNIQUE 约束确保列中的所有值都不同。在表格中可以设置多个栏目为 UNIQUE,但是只能设置唯一一个 PRIMARY KEY。在创建表格时,这样来设置 UNIQUE:
CREATE TABLE StockStatus ( ID int, StockName varchar(255) NOT NULL, PriceDay float(24), Country varchar(255), DateInput date, CONSTRAINT UN_Stock UNIQUE (ID, StockName) );
UNIQUE 在 ALTER TABLE 中的添加,及多行添加,但是在删除时略有不同,它是这样的命令:
ALTER TABLE Persons DROP INDEX UN_Stock;
FOREIGN KEY
FOREIGN KEY 约束用于防止会破坏表之间链接的操作。
FOREIGN KEY 是一个表中的字段(或字段集合),它引用另一个表中的 PRIMARY KEY。
具有外键的表称为子表,具有主键的表称为引用表或父表。
试举一例:
姓名表
PersonID | LastName | FirstName |
1 | ZHANG | BOHENG |
2 | ZHOU | XINGCHI |
3 | DENG | LAN |
点餐表
OrderID | OrderNumber | PersonID |
1 | 256 | 3 |
2 | 156 | 3 |
3 | 254 | 1 |
4 | 118 | 2 |
请注意,点餐表中的 “PersonID” 列指向姓名表中的 “PersonID” 列。
姓名表中的 “PersonID” 列是姓名表中的 PRIMARY KEY。
点餐表中的“PersonID”列是“Orders”表中的 FOREIGN KEY。
FOREIGN KEY 约束可防止将无效数据插入 foreign key 列,因为它必须是父表中包含的值之一。撰写的命令如下:
CREATE TABLE Orders ( OrderID int NOT NULL, OrderNumber int NOT NULL, PersonID int, PRIMARY KEY (OrderID), FOREIGN KEY (PersonID) REFERENCES Persons(PersonID) );
CHECK
CHECK 约束用于限制可以放在列中的值范围。试举一例:
CREATE TABLE StockStatus ( ID int, StockName varchar(255), PriceDay float(24), Country varchar(255), DateInput date, CONSTRAINT UN_Stock CHECK (PriceDay > 120.36 AND Country = 'USA') );
DEFAULT
DEFAULT 约束用于为列设置默认值,如果未指定其他值,则默认值将添加到所有新记录中。试举一例:
CREATE TABLE StockStatus ( ID int NOT NULL, PriceDay float(24) NOT NULL, DateInput date DEFAULT CURRENT_DATE() );
用 ALTER TABLE 的命令,例子如下:
ALTER TABLE StockStatus ALTER PriceDay SET DEFAULT '127.05';
去掉默认值,例子如下:
ALTER TABLE StockStatus ALTER PriceDay DROP DEFAULT;
AUTO_INCREMENT
自动增量允许在将新记录插入表时自动生成唯一编号。试举一例:
CREATE TABLE StockStatus ( ID int AUTO_INCREMENT, StockName varchar(255) NOT NULL, PriceDay float(24), Country varchar(255), DateInput date, CONSTRAINT UN_Stock UNIQUE (ID, StockName) );
CREATE INDEX
CREATE INDEX 语句用于在表中创建索引。
索引用于比其他方式更快地从数据库中检索数据。用户看不到索引,它们只是用来加速搜索/查询。常用语法命令如下:
CREATE INDEX index_name ON table_name (column1, column2, ...);
列表中的各种神奇指令
输入以下命令,就可以看到刚刚创建的表格显示了:
SELECT * FROM StockStatus;
显示结果如下:
我们可以挑选显示的内容,比如只显示 StockName, PriceDay,只需要运行以下命令:
SELECT StockName, PriceDay FROM StockStatus;
之后,表格就只显示这两列表格了。
表格空荡荡的,让我们给它添加点内容,输入以下命令演示:
INSERT INTO StockStatus VALUES(1, 'APPLE', 143.78, 'USA', '2022-05-26');
运行后,生成的表格如下:
然后,伯衡君又创建了很多条记录,主要是用来接下来的讲解。
比如在这些列表中,如何找出 ID 为 3 的那条记录,那么只需要输入以下命令:
SELECT * FROM StockStatus WHERE ID = 3;
WHERE 在这里起到了筛选条件的作用,关于数值,数学中的运算也能起到作用,支持运算符号有下面的表格所列出的:
运算符 | 作用 |
= | 相等 |
> | A 大于 B |
< | A 小于 B |
>= | A 大于且等于 B |
<= | A 小于且等于 B |
<> | 不等于,在有些其他数据库写成 != |
+ | A + B |
- | A - B |
* | A * B |
/ | A / B |
% | 取模运算,比如 9 % 2 = 1 |
BETWEEN | 明确的数值范围间 |
LIKE | 模糊搜索 |
IN | 在明确的列表名范围搜索 |
进行筛选前六个运算符比较简单,这里就不多做演示了,只从后三个来演示。
BETWEEN
SELECT * FROM StockStatus WHERE ID BETWEEN 2 AND 4;
这样就罗列出来了 ID 从 2 到 4 的所有条目。
LIKE
模糊搜索,这个使用频率非常高,它怎么用呢?先来看一下下面的表格:
形式 | 作用 |
'a%' | 查找以“a”开头的任何值 |
'%a' | 查找以“a”结尾的任何值 |
'%or%' | 查找在任何位置具有“or”的任何值 |
'_r%' | 查找第二个位置有“r”的任何值 |
a_%' | 查找以“a”开头且长度至少为 2 个字符的任何值 |
'a__%' | 查找以“a”开头且长度至少为 3 个字符的任何值 |
'a_%_%' | 查找以“a”开头且长度至少为 3 个字符的任何值 |
'a%o' | 查找以“a”开头并以“o”结尾的任何值 |
比如想查找 StockName 中含有 'p' 字符的所有项,只需要输入以下命令:
SELECT * FROM StockStatus WHERE StockName LIKE '%p%';
运行结果如下:
IN
IN 运算符允许在 WHERE 子句中指定多个值,类似于 OR,试举例如下:
SELECT * FROM StockStatus WHERE Country IN ('USA', 'TAIWAN');
运行效果如下:
还能通过 LIMIT 命令限制显示的结果条数,试举例如下:
SELECT * FROM StockStatus WHERE Country = 'USA' LIMIT 2;
那么结果就只显示符合条件的两条结果。
显示结果的顺序并不是一成不变的,可以通过 ORDER BY 语法进行更改显示,通过以 “ASC” 和 “DESC” 分别显示正序和倒序,试举一例:
SELECT * FROM StockStatus ORDER BY Country;
运行结果如下:
另一种写法则是如下,显示结果一样:
SELECT * FROM StockStatus ORDER BY Country ASC;
如果想倒序查看,则输入以下命令:
SELECT * FROM StockStatus ORDER BY Country DESC;
NULL 值在 Mysql 中也很常见,如果说在当初设计表格的时候,设置了列中允许 NULL 值,这个时候,就可以利用 NULL 值来进行筛选。
SELECT * FROM StockStatus WHERE Country IS NULL;
SELECT * FROM StockStatus WHERE Country IS NOT NULL;
之后是来了解一下更新列表中的值,试举一例,统一更改日期为“2022-05-27”,那么语法如下:
UPDATE StockStatus SET DateInput = '2022-05-27';
可以同时修改 N 项,根据需求来定。
删除列表中的某一条记录,则用到的语法用 “DELETE”,试举例如下,想删除 ID 为 3 的内容,则命令如下:
DELETE FROM StockStatus WHERE ID = 3;
那些进阶内容
代指
别名用于为表或表中的列提供临时名称,作用主要是用来易于解读,仅在查询时期使用。试举一例:
SELECT PriceDay AS pd FROM StockStatus;
注释
MySQL 中有两种注释方法,一个是单行用 ‘--’,另一个是多行用 ‘/* SOME TEXT */’。
--这是单行注释不执行 /* 这是多行注释也不执行 */
CASE 条件
在 MySQL 中有一种类似编程语言的条件控制语法,试举一例:
SELECT ID, PriceDay, CASE WHEN PriceDay > 124.85 THEN 'High' WHEN PriceDay = 21.02 THEN 'Middle' ELSE 'Low' END AS Remarks FROM StockStatus;
表的连接
JOIN 子句用于根据两个或多个表之间的相关列组合来自两个或多个表的行。连接形式有如下几种:
- INNER JOIN:返回两个表中具有匹配值的记录
- LEFT JOIN:从左表返回所有记录,从右表返回匹配的记录
- RIGHT JOIN:从右表返回所有记录,从左表返回匹配的记录
- CROSS JOIN:返回两个表中的所有记录
INNER JOIN
试举一例:
姓名表
PersonID | LastName | FirstName |
1 | ZHANG | BOHENG |
2 | ZHOU | XINGCHI |
3 | DENG | LAN |
点餐表
OrderID | OrderNumber | PersonID |
1 | 256 | 3 |
2 | 156 | 3 |
3 | 254 | 1 |
4 | 118 | 2 |
那么用 INNER JOIN 命令可以这样用:
SELECT NameTable.PersonID, OrderTable.OrderNumber FROM NameTable INNER JOIN OrderTable ON NameTable.PersonID = OrderTable.OrderID;
只要列之间存在匹配项,INNER JOIN 关键字就会从两个表中选择所有行。如果点餐表中有记录与姓名表中不匹配,这些订单将不会显示!
LEFT JOIN
用法与 INNER JOIN 差不多,所以就不演示了,LEFT JOIN 关键字返回左表中的所有记录,即使右表中没有匹配项。
RIGHT JOIN
用法与 INNER JOIN 差不多,所以就不演示了,RIGHT JOIN 关键字返回右表中的所有记录,即使左表中没有匹配项。
CROSS JOIN
用法与 INNER JOIN 差不多,所以就不演示了,CROSS JOIN 关键字返回两个表中的所有匹配记录,无论另一个表是否匹配。
UNION
UNION 运算符用于组合两个或多个 SELECT 语句的结果集。
SELECT City FROM NameTable UNION //无重复值 SELECT City FROM OrderTable;
SELECT City FROM NameTable UNION ALL //有重复值 SELECT City FROM OrderTable;
GROUP BY
GROUP BY 语句将具有相同值的行分组到汇总行中,常常伴随着使用 MySQL 的内构函数,比如 COUNT(), MAX(), MIN(), SUM(), AVG() 等等。
试举一例:
SELECT COUNT(ID), Country FROM StockStatus GROUP BY Country ORDER BY COUNT(ID) DESC;
运行结果如下所示:
有一些比较奇特的筛选条件 HAVING, EXISTS, ANY, ALL 等等。
HAVING
WHERE 关键字不能与聚合函数一起使用,所以 HAVING 就出现在了这里。
SELECT COUNT(ID), Country FROM StockStatus GROUP BY Country HAVING COUNT(ID) > 2;
EXISTS
如果子查询返回一条或多条记录,则 EXISTS 运算符返回 TRUE。试举一例:
SELECT OrderNumber FROM OrderTable WHERE EXISTS (SELECT OrderNumber FROM NameTable WHERE OrderTable.OrderID = NameTable.PersonID);
ANY
- 结果返回一个布尔值
- 如果任何子查询值满足条件,则返回 TRUE
SELECT Country FROM StockStatus WHERE ID = ANY (SELECT OrderID FROM OrderTable WHERE OrderNumber > 200);
ALL
- 结果返回一个布尔值,如果所有子查询值都满足条件,则返回 TRUE
- 与 SELECT、WHERE 和 HAVING 语句一起使用
INSERT INTO SELECT
INSERT INTO SELECT 语句从一个表中复制数据并将其插入到另一个表中。
INSERT INTO SELECT 语句要求源表和目标表中的数据类型匹配。
语法大致如下:
INSERT INTO table2 SELECT * FROM table1 WHERE condition;
日期格式
MySQL 带有以下数据类型,用于在数据库中存储日期或日期/时间值:
- DATE - 格式: YYYY-MM-DD
- DATETIME - 格式: YYYY-MM-DD HH:MI:SS
- TIMESTAMP - 格式: YYYY-MM-DD HH:MI:SS
- YEAR - 格式: YYYY or YY
温馨提示
MySQL 基础篇先告一段落,后续发布进阶篇内容,请参看这篇文章:
- 我的微信
- 微信扫一扫加好友
- 我的微信公众号
- 扫描关注公众号