MySql 基础

"learning……"

Posted by Ryan on February 17, 2025

不要抱怨,抱我。

MySql底层原理学习链接

MySql底层原理学习链接

MySql简介

MySQL 是一种开源的关系型数据库管理系统(RDBMS),它使用结构化查询语言(SQL)进行数据存储和管理。MySQL 是由 MySQL AB 开发的,后来被 Sun Microsystems(现为 Oracle Corporation)收购。由于其高效性、稳定性和广泛的社区支持,MySQL 已经成为世界上最流行的数据库之一。

1
git clone https://github.com/geekhournet/mysql-course        //一份sql文件包,可以用来实操

ps:这个玩意学起来和shell脚本似的,各种嵌套各种关键字还有正则表达式,很简单,巨容易学,也巨容易忘。

Linux安装MySQL8.0和基础命令

安装命令

1
sudo apt install mysql-server

配置安全设置

1
sudo mysql_secure_installation

检查MySQL是否正常工作

1
systemctl status mysql

连接MySQL

1
sudo mysql -u root -p

看到mysql提示符说明连接成功了。

MySQL查看自带的数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mysql> show schemas;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

退出

1
mysql>quit;

更新权限

1
mysql>flush priviledges;

MySQL地址权限

很多时候数据库服务是独立安装在远程服务器上的,为了方便,一般会使用可视化客户端工具连接到远程服务器,但常常会连接失败。为了连接成功,一般会进行一些配置。

显示端口

1
2
3
4
5
6
7
8
9
10
11
12
mysql> show variables like '%port';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| admin_port               | 33062 |
| large_files_support      | ON    |
| mysqlx_port              | 33060 |
| port                     | 3306  |
| report_port              | 3306  |
| require_secure_transport | OFF   |
+--------------------------+-------+
6 rows in set (0.02 sec)

查看和更改访问权限

1
2
3
4
5
6
7
8
9
mysql> use mysql;          //选择一个数据库,一般来说下载完MySQL会自动创建一个mysql数据库,可以直接use
select user,host from user where user='root';//查看权限,如果host字段是localhost,表示这个用户只能在本地访问
+------+-----------+
| user | host      |
+------+-----------+
| root | localhost |
+------+-----------+

update user set host='%' where user='root'; //将host字段改为%,就可以在任何地方访问了。(会带来安全风险)

MySQL的使用

image

创建和删除数据库

首先登入数据库:

1
2
sudo mysql -u root -p  //登入
mysql>show databases;  //查看已经存在的数据库

使用CREATE语句创建数据库:

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> create database game;  //创建game数据库

mysql> show databases;        //再查看一下,发现game数据库已经创建完成。
+--------------------+
| Database           |
+--------------------+
| game               |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

使用DROP语句删除数据库:

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> drop database game;    //删除game数据库
Query OK, 0 rows affected (0.01 sec)

mysql> show databases;        //再查看一下,发现game数据库已经删除完成。
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

在数据库中创建表、调整表与删除表

首先使用USE语句来进入数据库:

1
2
mysql> use game;              //选择数据库
Database changed

使用CREATE语句来建表,使用desc语句来查看表结构,使用show tables查看所有存在的表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mysql> create table player(id INT,name VARCHAR(100),level INT,exp INT,gold DECIMAL(10,2));  //  create table 表名(变量名);
Query OK, 0 rows affected (0.03 sec)

mysql> DESC player;           //使用desc语句查看表的结构
+-------+---------------+------+-----+---------+-------+
| Field | Type          | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| id    | int           | YES  |     | NULL    |       |
| name  | varchar(100)  | YES  |     | NULL    |       |
| level | int           | YES  |     | NULL    |       |
| exp   | int           | YES  |     | NULL    |       |
| gold  | decimal(10,2) | YES  |     | NULL    |       |
+-------+---------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

mysql> show tables;           //使用show语句查看当前数据库的所有的表
+----------------+
| Tables_in_game |
+----------------+
| player         |
+----------------+
1 row in set (0.00 sec)

使用alter语句来修改表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
mysql> ALTER TABLE player MODIFY COLUMN name VARCHAR(200);   //使用MODIFY修改表的参数
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE player RENAME COLUMN name to nick_name;   //使用RENAME修改参数名字
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE player ADD COLUMN last_login DATETIME;    //使用ADD增加一个新的字段
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0


mysql> desc player;                                          //实现的效果,可以看到name已经变成了nick_name,type类型也发生了改变,且增加了一个字段
+------------+---------------+------+-----+---------+-------+
| Field      | Type          | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| id         | int           | YES  |     | NULL    |       |
| nick_name  | varchar(200)  | YES  |     | NULL    |       |
| level      | int           | YES  |     | NULL    |       |
| exp        | int           | YES  |     | NULL    |       |
| gold       | decimal(10,2) | YES  |     | NULL    |       |
| last_login | datetime      | YES  |     | NULL    |       |
+------------+---------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

mysql> ALTER TABLE player DROP COLUMN last_login;            //使用drop删除字段
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> DESC player;                                          //实现效果,字段last_login已经被删除
+-----------+---------------+------+-----+---------+-------+
| Field     | Type          | Null | Key | Default | Extra |
+-----------+---------------+------+-----+---------+-------+
| id        | int           | YES  |     | NULL    |       |
| nick_name | varchar(200)  | YES  |     | NULL    |       |
| level     | int           | YES  |     | NULL    |       |
| exp       | int           | YES  |     | NULL    |       |
| gold      | decimal(10,2) | YES  |     | NULL    |       |
+-----------+---------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

使用DROP TABLE删除表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mysql> create table player1(id INT);    //创建表player1
Query OK, 0 rows affected (0.03 sec)

mysql> show tables;                     //查看
+----------------+
| Tables_in_game |
+----------------+
| player         |
| player1        |
+----------------+
2 rows in set (0.00 sec)

mysql> DROP TABLE player1;              //使用DROP TABLE删除表
Query OK, 0 rows affected (0.02 sec)

mysql> show tables;                     //效果
+----------------+
| Tables_in_game |
+----------------+
| player         |
+----------------+
1 row in set (0.00 sec)

表的数据操作

使用INSERT INTO插入数据:

1
2
mysql> INSERT INTO player VALUES (1,'张三',1,1,1);      //插入数据,insert into后面跟表的名称,values后面跟数据值,前面是参数名,可以灵活变动
Query OK, 1 row affected (0.01 sec)

使用select语句来查看数据:

1
2
3
4
5
6
7
mysql> select * from player;                //*表示查询所有,from后面跟表的名称
+------+--------+-------+------+------+
| id   | name   | level | exp  | gold |
+------+--------+-------+------+------+
|    1 | 张三   |     1 |    1 | 1.00 |
+------+--------+-------+------+------+
1 row in set (0.00 sec)

使用INSERT INTO插入多条数据(数据之间用逗号隔开):

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> INSERT INTO player (id,name) VALUES (2,'李四'),(3,'王五');    //插入多条数据
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from player;                                        //查看效果
+------+--------+-------+------+------+
| id   | name   | level | exp  | gold |
+------+--------+-------+------+------+
|    1 | 张三   |     1 |    1 | 1.00 |
|    2 | 李四   |  NULL | NULL | NULL |
|    3 | 王五   |  NULL | NULL | NULL |
+------+--------+-------+------+------+
3 rows in set (0.00 sec)

添加默认值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
mysql>ALTER TABLE player MODIFY COLUMN level INT DEFAULT 1;        //默认等级为1

mysql> desc player;                                                //查看效果
+-------+---------------+------+-----+---------+-------+
| Field | Type          | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| id    | int           | YES  |     | NULL    |       |
| name  | varchar(100)  | YES  |     | NULL    |       |
| level | int           | YES  |     | 1       |       |
| exp   | int           | YES  |     | NULL    |       |
| gold  | decimal(10,2) | YES  |     | NULL    |       |
+-------+---------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

mysql> INSERT INTO player (id,name) VALUES (4,'赵六');            //此时插入新数据,会自动给出默认值
Query OK, 1 row affected (0.00 sec)

mysql> select * from player;
+------+--------+-------+------+------+
| id   | name   | level | exp  | gold |
+------+--------+-------+------+------+
|    1 | 张三   |     1 |    1 | 1.00 |
|    2 | 李四   |  NULL | NULL | NULL |
|    3 | 王五   |  NULL | NULL | NULL |
|    4 | 赵六   |     1 | NULL | NULL |
+------+--------+-------+------+------+
4 rows in set (0.00 sec)

使用update更新数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
mysql> UPDATE player set level = 1 where name='李四';            //更改李四的等级为1
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from player;                                    //查看
+------+--------+-------+------+------+
| id   | name   | level | exp  | gold |
+------+--------+-------+------+------+
|    1 | 张三   |     1 |    1 | 1.00 |
|    2 | 李四   |     1 | NULL | NULL |
|    3 | 王五   |  NULL | NULL | NULL |
|    4 | 赵六   |     1 | NULL | NULL |
+------+--------+-------+------+------+
4 rows in set (0.00 sec)

mysql> UPDATE  player set exp=0,gold=0;                         //更改所有人的经验和金币都为0
Query OK, 4 rows affected (0.01 sec)
Rows matched: 4  Changed: 4  Warnings: 0

mysql> select * from player;
+------+--------+-------+------+------+
| id   | name   | level | exp  | gold |
+------+--------+-------+------+------+
|    1 | 张三   |     1 |    0 | 0.00 |
|    2 | 李四   |     1 |    0 | 0.00 |
|    3 | 王五   |  NULL |    0 | 0.00 |
|    4 | 赵六   |     1 |    0 | 0.00 |
+------+--------+-------+------+------+
4 rows in set (0.00 sec)

使用delete语句来删除数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> DELETE FROM player where name='王五';            //删除王五
Query OK, 1 row affected (0.00 sec)

mysql> select * from player;                            //效果
+------+--------+-------+------+------+
| id   | name   | level | exp  | gold |
+------+--------+-------+------+------+
|    1 | 张三   |     1 |    0 | 0.00 |
|    2 | 李四   |     1 |    0 | 0.00 |
|    4 | 赵六   |     1 |    0 | 0.00 |
+------+--------+-------+------+------+
3 rows in set (0.00 sec)

数据库导入和导出

导出文件:

1
2
3
ryan@ubuntu:~$ sudo mysqldump -u root -p game > game.sql  //导出
ls                 //查看目录
cat game.sql       //查看文件

导入文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
udo mysql -u root -p game < game.sql                       //导入

mysql> show tables;                                        //查看数据库game,发现多了很多table
+----------------+
| Tables_in_game |
+----------------+
| equip          |
| item           |
| new_player     |
| npc            |
| npc_other      |
| player         |
| ranking        |
| skill          |
| top10          |
+----------------+
9 rows in set (0.00 sec)

mysql> desc player;                                        //player表也发生了许多更改
+-------+---------------+------+-----+---------+-------+
| Field | Type          | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| id    | int           | YES  |     | NULL    |       |
| name  | varchar(100)  | YES  |     | NULL    |       |
| sex   | varchar(10)   | YES  |     | NULL    |       |
| email | varchar(100)  | YES  |     | NULL    |       |
| level | int           | YES  |     | 1       |       |
| exp   | int           | YES  |     | NULL    |       |
| gold  | decimal(10,2) | YES  |     | NULL    |       |
+-------+---------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

常用语句

有超级多的关键字,建议有什么需求先去网上查一下或者chatgpt

select语句变形

NOT>AND>OR,括号可以改变优先级:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
mysql> select * FROM player WHERE level >1;        //

mysql> select * FROM player WHERE level > 1 AND level < 5;        //
+------+-----------+------+-----------------------+-------+------+-------+
| id   | name      | sex  | email                 | level | exp  | gold  |
+------+-----------+------+-----------------------+-------+------+-------+
|    1 | 张三      | 男   | zhangsan@gmail.com    |     3 |   19 | 20.00 |
|    2 | 赵四儿    | 男   | zhaosier@geekhour.net |     4 |   22 | 26.00 |
+------+-----------+------+-----------------------+-------+------+-------+
2 rows in set (0.00 sec)

mysql> select * FROM player WHERE exp > 1 AND level < 5;        //
+------+-----------+------+-----------------------+-------+------+-------+
| id   | name      | sex  | email                 | level | exp  | gold  |
+------+-----------+------+-----------------------+-------+------+-------+
|    1 | 张三      | 男   | zhangsan@gmail.com    |     3 |   19 | 20.00 |
|    2 | 赵四儿    | 男   | zhaosier@geekhour.net |     4 |   22 | 26.00 |
|   17 | 吕秀才    | 男   | lvxiucai@gmail.com    |     1 |    2 |  3.00 |
|  131 | 弈星      | 男   | yixing@geekhour.net   |     1 |   61 | 90.00 |
+------+-----------+------+-----------------------+-------+------+-------+
4 rows in set (0.00 sec)


mysql> select * FROM player WHERE level > 1 AND level < 5 OR exp > 1 AND exp < 5;    //
+------+-----------+------+-------------------------+-------+------+-------+
| id   | name      | sex  | email                   | level | exp  | gold  |
+------+-----------+------+-------------------------+-------+------+-------+
|    1 | 张三      | 男   | zhangsan@gmail.com      |     3 |   19 | 20.00 |
|    2 | 赵四儿    | 男   | zhaosier@geekhour.net   |     4 |   22 | 26.00 |
|   17 | 吕秀才    | 男   | lvxiucai@gmail.com      |     1 |    2 |  3.00 |
|   19 | 佟湘玉    | 女   | tongxiangyu@163.com     |    99 |    4 | 10.00 |
|   50 | 高启强    | 男   | gaoqiqiang@geekhour.net |    88 |    3 | 30.00 |
|  136 | 女娲      | 女   | nvwa@qq.com             |    89 |    2 | 86.00 |
+------+-----------+------+-------------------------+-------+------+-------+
6 rows in set (0.01 sec)

mysql> select * FROM player WHERE level BETWEEN 1 AND 10;                            //
+------+-----------+------+-----------------------+-------+------+-------+
| id   | name      | sex  | email                 | level | exp  | gold  |
+------+-----------+------+-----------------------+-------+------+-------+
|    1 | 张三      | 男   | zhangsan@gmail.com    |     3 |   19 | 20.00 |
|    2 | 赵四儿    | 男   | zhaosier@geekhour.net |     4 |   22 | 26.00 |
|   11 | 胡一菲    | 女   | huyifei@163.com       |     6 |   53 | 38.00 |
|   17 | 吕秀才    | 男   | lvxiucai@gmail.com    |     1 |    2 |  3.00 |
|   31 | 周伯通    | 男   | zhoubotong@163.com    |     8 |   45 | 70.00 |
|   37 | 慕容复    | 男   | murongfu@gmail.com    |     5 |   49 | 38.00 |
|   49 | 安欣      | 男   | anxin@gmail.com       |     8 |   43 | 33.00 |
|   87 | 小鱼儿    | 男   | xiaoyuer@163.com      |     6 |   55 |  4.00 |
|   91 | 余则成    | 男   | yuzecheng@163.com     |    10 |   53 | 29.00 |
|  131 | 弈星      | 男   | yixing@geekhour.net   |     1 |   61 | 90.00 |
+------+-----------+------+-----------------------+-------+------+-------+
10 rows in set (0.00 sec)

like模糊查找(正则表达式)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
mysql> select * FROM player WHERE name LIKE '王%';            //%通配所有
+------+-----------+------+---------------------------+-------+------+-------+
| id   | name      | sex  | email                     | level | exp  | gold  |
+------+-----------+------+---------------------------+-------+------+-------+
|    3 | 王五      | 女   | wangwu@163.com            |    64 |   38 | 15.00 |
|    7 | 王小二    | 男   | wangxiaoer@163.com        |    70 |   30 | 54.00 |
|   33 | 王重阳    | 男   | wangchongyang@gmail.com   |    38 |   63 | 38.00 |
|   54 | 王语嫣    | 女   | wangyuyan@geekhour.net    |    71 |   97 | 85.00 |
|   82 | 王小蒙    | 女   | wangxiaomeng@geekhour.net |    95 |   77 | 44.00 |
|  169 | 王昭君    | 女   | wangzhaojun@gmail.com     |    96 |   48 | 11.00 |
+------+-----------+------+---------------------------+-------+------+-------+
6 rows in set (0.00 sec)

ysql> select * FROM player WHERE name LIKE '%王%';                                //
+------+-----------+------+---------------------------+-------+------+-------+
| id   | name      | sex  | email                     | level | exp  | gold  |
+------+-----------+------+---------------------------+-------+------+-------+
|    3 | 王五      | 女   | wangwu@163.com            |    64 |   38 | 15.00 |
|    7 | 王小二    | 男   | wangxiaoer@163.com        |    70 |   30 | 54.00 |
|   33 | 王重阳    | 男   | wangchongyang@gmail.com   |    38 |   63 | 38.00 |
|   54 | 王语嫣    | 女   | wangyuyan@geekhour.net    |    71 |   97 | 85.00 |
|   82 | 王小蒙    | 女   | wangxiaomeng@geekhour.net |    95 |   77 | 44.00 |
|  160 | 牛魔王    | 男   | niumowang@qq.com          |    11 |   16 | 46.00 |
|  168 | 兰陵王    | 男   | lanlingwang@qq.com        |    64 |   22 | 12.00 |
|  169 | 王昭君    | 女   | wangzhaojun@gmail.com     |    96 |   48 | 11.00 |
+------+-----------+------+---------------------------+-------+------+-------+
8 rows in set (0.00 sec)

mysql> select * FROM player WHERE name LIKE '王_';                            //_通配单字
+------+--------+------+----------------+-------+------+-------+
| id   | name   | sex  | email          | level | exp  | gold  |
+------+--------+------+----------------+-------+------+-------+
|    3 | 王五   | 女   | wangwu@163.com |    64 |   38 | 15.00 |
+------+--------+------+----------------+-------+------+-------+
1 row in set (0.00 sec)

正则表达式REGEXP:

1
2
3
4
5
6
7
mysql> select * FROM player WHERE name REGEXP '^王.$';
+------+--------+------+----------------+-------+------+-------+
| id   | name   | sex  | email          | level | exp  | gold  |
+------+--------+------+----------------+-------+------+-------+
|    3 | 王五   | 女   | wangwu@163.com |    64 |   38 | 15.00 |
+------+--------+------+----------------+-------+------+-------+
1 row in set (0.01 sec)
查找空值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mysql> select * FROM player WHERE email is null;        //
+------+-----------+------+-------+-------+------+-------+
| id   | name      | sex  | email | level | exp  | gold  |
+------+-----------+------+-------+-------+------+-------+
|   12 | 吕子乔    | 男   | NULL  |    36 |  100 | 46.00 |
|   13 | 吕小布    | 男   | NULL  |    81 |   88 | 25.00 |
+------+-----------+------+-------+-------+------+-------+
2 rows in set (0.00 sec)

mysql> select * FROM player WHERE email is NOT null;        //

mysql> select * FROM player WHERE email is null OR email='';    //
+------+-----------+------+-------+-------+------+-------+
| id   | name      | sex  | email | level | exp  | gold  |
+------+-----------+------+-------+-------+------+-------+
|   12 | 吕子乔    | 男   | NULL  |    36 |  100 | 46.00 |
|   13 | 吕小布    | 男   | NULL  |    81 |   88 | 25.00 |
|  190 | 吕布      | 男   |       |    77 |   43 | 31.00 |
+------+-----------+------+-------+-------+------+-------+
3 rows in set (0.00 sec)
ORDER BY排序
1
2
3
mysql> select * FROM player ORDER BY level;        //升序排序
mysql> select * FROM player ORDER BY level DESC;   //降序排序
mysql> select * FROM player ORDER BY level DESC,exp ASC;    //等级降序,经验升序
聚合函数(有很多,这里只列举几个)

计数函数:

1
2
3
4
5
6
7
mysql> select COUNT(*) FROM player;        //计数
+----------+
| COUNT(*) |
+----------+
|      209 |
+----------+
1 row in set (0.01 sec)

均值函数:

1
2
3
4
5
6
7
mysql> select AVG(level) FROM player;        //所有玩家的等级均值
+------------+
| AVG(level) |
+------------+
|    55.0813 |
+------------+
1 row in set (0.00 sec)
group by分组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mysql> select sex,COUNT(*) FROM player group by sex;
+------+----------+
| sex  | COUNT(*) |
+------+----------+
| 男   |      140 |
| 女   |       65 |
| NULL |        3 |
|      |        1 |
+------+----------+
4 rows in set (0.00 sec)

//分组后having过滤,然后降序
mysql> select level,COUNT(*) FROM player group by level having count(level)>4 order by COUNT(level) DESC;
+-------+----------+
| level | COUNT(*) |
+-------+----------+
|    13 |        9 |
|    96 |        7 |
|    95 |        5 |
|    88 |        5 |
|    54 |        5 |
+-------+----------+
5 rows in set (0.00 sec)

子查询

有的时候,我们需要使用一个查询结果作为另一个查询的条件。

1
mysql> select * from player where level > (select AVG(level) from player);  //把一个查询套上括号

查询结果创建新表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mysql> create table new_table (select * from player where level < 5);
Query OK, 4 rows affected (0.03 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> show tables;
+----------------+
| Tables_in_game |
+----------------+
| equip          |
| item           |
| new_player     |
| new_table      |
| npc            |
| npc_other      |
| player         |
| ranking        |
| skill          |
| top10          |
+----------------+
10 rows in set (0.00 sec)

表关联

表关联用来查询多个表中的数据,关联的表必须要有相同字段。
在关系型数据库中,表关联(Join)是一种将两个或多个表的数据结合在一起的操作,通常用于根据某些条件从多个表中获取相关的数据。表关联可以基于共同的列(通常是主键与外键关系)将数据链接在一起。

内连接(INNER JOIN)
  • 返回两个表中匹配的行。如果在某个表中没有匹配行,则这些行不会出现在结果中。
  • 适用于你只关心两个表中存在共同数据的场景。

以装备表equip和玩家player表为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> select * from player 
    -> inner join equip 
    -> on player.id=equip.player_id;
+------+-----------+------+---------------------+-------+------+-------+------+-----------------+-----------+
| id   | name      | sex  | email               | level | exp  | gold  | id   | name            | player_id |
+------+-----------+------+---------------------+-------+------+-------+------+-----------------+-----------+
|   76 | 林克      | 男   | linke@qq.com        |    48 |   12 | 11.00 |    6 | 大师之剑        |        76 |
|  157 | 张飞      | 男   | zhangfei@gmail.com  |    76 |   36 | 80.00 |    2 | 丈八蛇矛        |       157 |
|  161 | 孙悟空    | 男   | sunwukong@gmail.com |    74 |   32 | 23.00 |    7 | 金箍棒          |       161 |
|  177 | 关羽      | 男   | guanyu@gmail.com    |    19 |   60 | 36.00 |    1 | 青龙偃月刀      |       177 |
|  186 | 曹操      | 男   | caocao@geekhour.net |    70 |   15 | 27.00 |    3 | 七星宝刀        |       186 |
|  190 | 吕布      | 男   |                     |    77 |   43 | 31.00 |    9 | 赤兔马          |       190 |
|  190 | 吕布      | 男   |                     |    77 |   43 | 31.00 |    8 | 方天画戟        |       190 |
+------+-----------+------+---------------------+-------+------+-------+------+-----------------+-----------+
7 rows in set (0.01 sec)
左连接(LEFT JOIN 或 LEFT OUTER JOIN)
  • 返回左表(第一个表)中的所有行以及右表(第二个表)中匹配的行。如果右表没有匹配的行,则右表的结果为空(NULL)。
  • 适用于你想保留左表所有记录,无论是否在右表中找到匹配项的场景。

左连接把左表所有数据全部输出(太多了只截取一部分),右表匹配上的匹配,匹配不上的全是NULL:

1
2
3
4
5
6
7
8
9
10
mysql> select * from player  left join equip  on player.id=equip.player_id;
+------+--------------+------+----------------------------+-------+------+--------+------+-----------------+-----------+
| id   | name         | sex  | email                      | level | exp  | gold   | id   | name            | player_id |
+------+--------------+------+----------------------------+-------+------+--------+------+-----------------+-----------+
|    1 | 张三         | 男   | zhangsan@gmail.com         |     3 |   19 |  20.00 | NULL | NULL            |      NULL |
|    2 | 赵四儿       | 男   | zhaosier@geekhour.net      |     4 |   22 |  26.00 | NULL | NULL            |      NULL |
|    3 | 王五         | 女   | wangwu@163.com             |    64 |   38 |  15.00 | NULL | NULL            |      NULL |
|    4 | 刘能         | 男   | liuneng@qq.com             |    30 |   95 |   1.00 | NULL | NULL            |      NULL |
|    5 | 范德彪       | 男   | fandebiao@gmail.com        |    95 |   89 |  44.00 | NULL | NULL            |      NULL |

右连接(RIGHT JOIN 或 RIGHT OUTER JOIN)
  • 返回右表(第二个表)中的所有行,以及左表(第一个表)中匹配的行。如果左表没有匹配的行,则左表的结果为空(NULL)。
  • 适用于你想保留右表所有记录,无论是否在左表中找到匹配项的场景。

右连接把右表所有数据全部输出,左表匹配上的匹配,匹配不上的全是NULL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> select * from player  right join equip  on player.id=equip.player_id;
+------+-----------+------+---------------------+-------+------+-------+------+-----------------+-----------+
| id   | name      | sex  | email               | level | exp  | gold  | id   | name            | player_id |
+------+-----------+------+---------------------+-------+------+-------+------+-----------------+-----------+
|  177 | 关羽      | 男   | guanyu@gmail.com    |    19 |   60 | 36.00 |    1 | 青龙偃月刀      |       177 |
|  157 | 张飞      | 男   | zhangfei@gmail.com  |    76 |   36 | 80.00 |    2 | 丈八蛇矛        |       157 |
|  186 | 曹操      | 男   | caocao@geekhour.net |    70 |   15 | 27.00 |    3 | 七星宝刀        |       186 |
| NULL | NULL      | NULL | NULL                |  NULL | NULL |  NULL |    4 | 长剑            |      NULL |
| NULL | NULL      | NULL | NULL                |  NULL | NULL |  NULL |    5 | 铁盾            |      NULL |
|   76 | 林克      | 男   | linke@qq.com        |    48 |   12 | 11.00 |    6 | 大师之剑        |        76 |
|  161 | 孙悟空    | 男   | sunwukong@gmail.com |    74 |   32 | 23.00 |    7 | 金箍棒          |       161 |
|  190 | 吕布      | 男   |                     |    77 |   43 | 31.00 |    8 | 方天画戟        |       190 |
|  190 | 吕布      | 男   |                     |    77 |   43 | 31.00 |    9 | 赤兔马          |       190 |
+------+-----------+------+---------------------+-------+------+-------+------+-----------------+-----------+
9 rows in set (0.00 sec)

索引

在数据库管理系统中,索引(Index)是一种数据结构,用于提高数据检索速度。它通过创建一个数据项的“指针”来快速定位到数据表中的数据行,避免了对整个数据表进行全表扫描,从而显著提高查询效率。索引类似于书本的目录,帮助你快速找到某个章节或内容。
创建索引后正常查询即可。

创建普通索引:

1
CREATE INDEX index_name ON table_name (column_name);

建表时直接定义索引:

1
2
3
4
5
CREATE TABLE table_name (
    id INT,
    name VARCHAR(100),
    INDEX (name)
);

删除索引:

1
DROP INDEX index_name ON table_name;

视图索引

在关系型数据库中,视图(View)是一个虚拟表,它是由一个或多个表的查询结果所组成的。视图本身不存储数据,而是通过查询定义来动态地生成数据(有点像shell脚本)。可以将视图视为一个“虚拟表”,你可以像操作普通表一样对视图进行查询、插入、更新和删除等操作,但视图背后存储的是查询结果而不是物理数据。

创建视图:

1
2
3
mysql> CREATE VIEW top10
    -> AS
    -> select * from player order by level desc limit 10;

使用视图:

1
2
3
4
5
6
7
8
9
10
11
mysql> select * from top10;
+------+-----------+------+-----------------------+-------+------+-------+
| id   | name      | sex  | email                 | level | exp  | gold  |
+------+-----------+------+-----------------------+-------+------+-------+
|   17 | 吕秀才    | 男   | lvxiucai@gmail.com    |     1 |    2 |  3.00 |
|  131 | 弈星      | 男   | yixing@geekhour.net   |     1 |   61 | 90.00 |
|    1 | 张三      | 男   | zhangsan@gmail.com    |     3 |   19 | 20.00 |
|    2 | 赵四儿    | 男   | zhaosier@geekhour.net |     4 |   22 | 26.00 |
|   37 | 慕容复    | 男   | murongfu@gmail.com    |     5 |   49 | 38.00 |
+------+-----------+------+-----------------------+-------+------+-------+
5 rows in set (0.01 sec)