前言
环境:
- Windows11
- MySQL-8.0.35
1.服务启动和关闭
Windows系统中:
powershell
// 启动MySQL服务
net start mysql80
// 关闭MySQL服务
net stop mysql80
2.SQL基础
2.1.登录
登录本机MySQL服务,用户是root(-u指定),使用密码登录(-p表示需要输入密码)
sql
mysql -uroot -p
// windows中,进入mysql安装的bin目录下
.\mysql -uroot -p
2.2.DDL操作
数据库定义语句... ...
查看所有的数据库
sql
show databases
创建数据库
sql
create database 数据库名
进入指定的数据库
sql
use 数据库名
查看当前在哪个数据库下
sql
select database()
查看数据库中有哪些表
sql
show tables
删除数据库
sql
drop database 数据库名
创建表
sql
CREATE TABLE 表名 (列名 列类型 约束条件)
查看表的定义
sql
DESC 表名
查看创建表的SQL
sql
show create table 表名
删除表
sql
DROP TABLE 表名
修改表字段
sql
ALTER TABLE 表名 MODIFY [COLUMN] column_definition [FIRST | AFTER column_name]
增加表字段
sql
ALTER TABLE 表名 ADD [COLUMN] column_definition [FIRST | AFTER column_name]
删除表字段
sql
ALTER TABLE 表名 DROP [COLUMN] column_name
修改字段名
sql
ALTER TABLE 表名 RENAME [COLUMN] old_column_name TO new_column_name
修改字段名并修改列定义
sql
ALTER TABLE 表名 CHANGE [COLUMN] old_column_name column_definition [FIRST | AFTER col_name]
change和modify都可以修改列的定义,也就是column_definition,不同的是change后面要写两次列名,因为old列名和new列名都一样(这里是说修改列的定义,不是改名),不方便。但是change的优点是可以同时修改列名,此时old列名和new列名就不一样了,modify不可以修改列名。
如果仅仅修改列名,可以使用上面的RENAME TO的语句。
修改字段排列顺序
前面的语句中,ADD、MODIFY和CHANGE语句中,都有一个 first | alter column_name,这就是设置列的顺序的。ADD新加的列默认在最后,MODIFY和CHANGE如果不指定默认是不改变列的顺序的。
添加列并指定位置:
sql
alter table emp add birth date after ename
修改列,设置顺序第一个:
sql
alter table emp modify column age int(3) first
更改表名
sql
ALTER TABLE 表名 RENAME [TO] new_tablename
查看表的所有列信息
sql
SHOW COLUMNS FROM 表名 [FROM 数据库名] [LIKE 'pattern']
2.3.DML语句
数据库操作语句,主要是针对数据库中表数据的操作,例如insert、delete、update 和 select操作。
插入记录insert
sql
// 指定列的插入
INSERT INTO 表名(field1, field2, ..., fieldn) VALUES (value1, value2, ..., valuen)
// 不指定列的全部插入
INSERT INTO 表名 VALUES (value1, value2, ..., valuen)
// 一次性插入多条数据
INSERT INTO 表名(field1, field2, ..., fieldn)
VALUES
(value1, value2, ..., valuen),
(value1, value2, ..., valuen),
...,
(value1, value2, ..., valuen)
更新记录update
更新一个表的数据:
sql
UPDATE 表名 SET field1=value1, field2=value2, ..., fieldn=valuen [WHERE CONDITION]
同时更新多个表的数据:
sql
UPDATE 表名1 t1, 表名2 t2, ..., 表名n tn SET t1.列名=exprn, t2.列名=exprn, ..., tn.列名=exprn [WHERE CONDITION]
这种方式更多的用于根据一个表的字段动态的更新另一个表的字段。
删除记录delete
sql
DELETE FROM 表名 [WHERE CONDITION]
一次性删除多个表的数据:
sql
DELETE 表名1, 表名2, ..., 表名n from 表名1, 表名2, ..., 表名n [WHERE CONDITION]
// 例如, 同时删除emp和dept中deptno为3的数据
delete a, b from emp a, dept b where a.deptno = b.deptno and a.deptno = 3
如果from后面的表名使用别名,delete后面的也需要使用别名。
注意:不管是单表还是多表的删除,如果不加where条件,会删除表中的所有数据!!!
查询记录select
sql
SELECT * FROM 表名 [WHERE CONDITION]
// 查询不重复的记录, distinct
SELECT DISTINCT column_name1, ..., column_namen FROM 表名 [WHERE CONDITION]
// 查询条件以及排序
SELECT * FROM 表名 [WHERE CONDITION] [ORDER BY field1 [DESC | ASC], field2 [DESC | ASC], ..., fieldn [DESC | ASC]]
limit
sql
// 显示部分数据(分页), limit
SELECT ... [WHERE CONDITION] [LIMIT offset_start, row_count]
limit语句中,offset_start表示记录的起始偏移量,row_count表示显示的行数。默认情况下起始偏移量是0,只写row_count,那就展示查询数据的前n条数据,例如:
sql
// 展示查询数据的前3条数据
select * from emp limit 3
显示查询后的第二条记录开始,显示3条:
sql
// offset_start默认从0开始,所以第二条开始就从1开始
select * from emp limit 1,3
聚合
sql
SELECT [field1, field2, ..., fieldn] fun_name
FROM 表名
[WHERE CONDITION] [
GROUP BY field1, field2, ..., fieldn [WITH ROLLUP]]
[HAVING where_condition]
- fun_name:表示要做的聚合操作,也就是聚合函数,常用的有sum、count、avg、max和min。
- GROUP BY:表示要进行分类聚合的字段。
- WITH ROLLIP:可选的,表示是否对分类聚合后的结果再进行汇总。
- HAVING:表示对分类后的结果再进行条件的过滤。
注意:having和where的区别,having是对聚合后的结果进行条件的过滤,而where是在聚合前就对数据进行过滤,所有使用时尽可能先用where过滤数据,这样结果集减少,聚合的效率会提高,最后再根据having进行过滤。
聚合示例:
sql
// 要在emp表中统计公司的总人数
select count(1) from emp
// 统计各部门的人数
select deptno, count(1) from emp group by deptno
// 既要统计各部分人数, 又要统计总人数
select deptno, count(1) from emp group by deptno with rollup
// 统计人数大于1的部门
select deptno, count(1) from emp group by deptno having count(1) > 1
// 统计公司所有员工的薪水总额、最高和最低薪水
select sum(sal), max(sal), min(sal) from emp;
with rollup
在MySQL中,WITH ROLLUP是一个可选的修饰符,它可以与GROUP BY子句一起使用,以生成一个额外的汇总行,显示每个分组的总和。这在数据分析和报告生成中特别有用,因为它允许你查看每个子组的详细信息,同时还可以快速地看到整体的汇总数据。
当你使用WITH ROLLUP时,MySQL会为每个GROUP BY列生成一个额外的汇总行。这些汇总行将显示该列中所有行的汇总值,而不仅仅是特定分组的值。
表连接
大类上,分为内连接和外链接,内连接仅仅展示两张表互相匹配的数据,而外连接会选出其他不匹配的记录。
sql
// 内连接
select ename, deptno from emp, dept where emp.deptno = dept.deptno
外连接又分为 左连接 和 右连接。
- 左连接:包含所有的左表中的记录甚至是右边表中没有和它匹配的记录。
- 右连接:包含所有的右表中的记录甚至是左边表中没有和它匹配的记录。
子查询
sql
select * from emp where deptno in (select deptno from dept)
// 如果子查询记录唯一, 用 = 代替 in
select * from emp where deptno = (select deptno from dept)
// 某些情况,子查询可以转化为表连接
select emp.* from emp, dept where emp.deptno = dept.deptno
表连接很多情况下是优于子查询的
记录联合union 和 union all
union 和 union all 的区别是 union all 是把结果集直接合并在一起,而union是将union all后的结果进行一次distinct,去除重复记录后的结果。
2.3.DCL语句
数据库管理语句,主要是DBA用来管理系统中的对象权限时使用,一般开发人员很少用到。
3.帮助的使用
MySQL使用中可能遇到以下问题:
- 某个操作语法忘记了,如何快速查找?
- 如何快速知道当前版本上某个字段类型的取值范围?
- 当前版本都支持哪些函数?
- 当前版本是否支持某个功能?
3.1.按照层次看帮助
如果不知道帮助能够提供什么,可以使用 "? contents"命令显示所有可供查询的分类,例如:
shell
mysql> ? contents;
You asked for help about help category: "Contents"
For more information, type 'help <item>', where <item> is one of the following
categories:
Account Management
Administration
Components
Compound Statements
Contents
Data Definition
Data Manipulation
Data Types
Functions
Geographic Features
Help Metadata
Language Structure
Loadable Functions
Plugins
Prepared Statements
Replication Statements
Storage Engines
Table Maintenance
Transactions
Utility
如上,对于列出的分类,可以使用"? 类别名称"的方式进一步查看,例如,想查看MySQL中都支持哪些数据类型,可以执行 "? data types"命令:
shell
mysql> ? data types;
You asked for help about help category: "Data Types"
For more information, type 'help <item>', where <item> is one of the following
topics:
AUTO_INCREMENT
BIGINT
BINARY
BIT
BLOB
BLOB DATA TYPE
BOOLEAN
...
...
如上,列出了当前版本支持的所有数据类型,如果想看int类型的具体介绍,执行"? int"命令:
shell
mysql> ? int;
Name: 'INT'
Description:
INT[(M)] [UNSIGNED] [ZEROFILL]
A normal-size integer. The signed range is -2147483648 to 2147483647.
The unsigned range is 0 to 4294967295.
URL: https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
通过这种 "? 类别名称"的方式,可以一层一层的往下查找你关心的主题内容。
3.2.快速查阅帮助
实际使用中,如需要快速查阅某项语法,可以使用关键字进行快速查阅,例如想知道 show 命令都能干什么,可以执行命令 "? show":
shell
mysql> ? show;
Name: 'SHOW'
Description:
SHOW has many forms that provide information about databases, tables,
columns, or status information about the server. This section describes
those following:
SHOW {BINARY | MASTER} LOGS
SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]
SHOW {CHARACTER SET | CHARSET} [like_or_where]
SHOW COLLATION [like_or_where]
SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [like_or_where]
SHOW CREATE DATABASE db_name
SHOW CREATE EVENT event_name
SHOW CREATE FUNCTION func_name
SHOW CREATE PROCEDURE proc_name
SHOW CREATE TABLE tbl_name
...
...
同样的如果想看 CREATE TABLE 的语法,可以如下执行:
shell
mysql> ? create table;
Name: 'CREATE TABLE'
Description:
Syntax:
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
(create_definition,...)
[table_options]
[partition_options]
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
[(create_definition,...)]
[table_options]
[partition_options]
[IGNORE | REPLACE]
[AS] query_expression
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
{ LIKE old_tbl_name | (LIKE old_tbl_name) }
...
...
4.查询元数据信息
应用场景:
- 删除数据库test1下的所有前缀为tmp的表;
- 讲数据库test1下的所有存储引擎为myisam的表改为innodb;
MySQL提供了一个数据库information_schema,用来记录MySQL中的元数据信息。
元数据指的是数据的数据,比如表名、列名、列类型、所以索引名等表的各种属性名称。
这个库比较特殊,是一个虚拟的库,物理上不存在相关的目录和文件,库里show tables展示的表也不是实际存在的物理表,而全部是视图。
对于上面的两个场景,可以如下命令得到需要执行的SQL语句:
sql
select concat('drop table test1.', table_name, ';') from tables where table_schema = 'test1' and table_name like 'tmp%'
select concat('alter table test1.', table_name, ' engine=innodb;') from tables where table_schema = 'test1' and engine = 'MYISAM'
比较常见的视图:
- SCHEMATA:提供了当前MySQL实例中所有数据库的信息,show databases命令执行的结果就是来源于这个视图。
- TABLES:提供了关于数据库中的表的信息(包括视图),详细表述了某个表属于哪个schema、表类型、表引擎、创建时间等信息。show tables from schemaname命令的结果就是来源于这个视图。
- COLUMNS:提供了表中的列信息,详细表述了某张表的所有列以及每个列的信息,show columns from schemaname.tablename的结果就是来源于这个视图。
- STATISTICS:提供了表的索引信息,show index from schemaname.tablename的结果来源于这个视图。