📚前言

前面有篇文章已经简单地介绍了 Docker,却没有使用真正的案例来使用一下。

如果还没有看可以点一下这个链接 Docker笔记_hjh_cos-CSDN博客 了解一下,或许可以解决你无法使用 docker 的问题。

那么接下来我将会使用 docker 的镜像来快速安装 MySQL ,其实网上关于MySQL应不应该安装在docker 上运行部署项目持有两种态度。我个人觉得怎么方便怎么来,比如我完全为了测试用完就删,那么我就可以考虑 docker 毕竟可以不用配置环境啥的。

网上还有人说 k8s 代替 docker 你可以完全当个笑话听听,毕竟两者可以说完全是不同的服务。

📕正文

内容不是很多,毕竟官网有相关地说明和介绍,可就算如此我还是遇见问题了,流下没有技术的眼泪😭,不过后面还是解决了。

docker 官网关于MySQL教程 Mysql - Official Image | Docker Hub


💡检查是否存在 MySQL 镜像

docker images

PS F:\Space\mysql> docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
mysql        latest    3218b38490ce   2 months ago   516MB
PS F:\Space\mysql>

显然我以前已经使用 docker pull mysql 拉取过 MySQL 的镜像,不用担心为了演示我会把它删了😂。

💡删除已经安装的 MySQL 镜像

docker image rm <镜像 ID>

PS F:\Space\mysql> docker image rm 3218b38490ce
Untagged: mysql:latest
Untagged: mysql@sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709
Deleted: sha256:3218b38490cec8d31976a40b92e09d61377359eab878db49f025e5d464367f3b
Deleted: sha256:aa81ca46575069829fe1b3c654d9e8feb43b4373932159fe2cad1ac13524a2f5
Deleted: sha256:0558823b9fbe967ea6d7174999be3cc9250b3423036370dc1a6888168cbd224d
Deleted: sha256:a46013db1d31231a0e1bac7eeda5ad4786dea0b1773927b45f92ea352a6d7ff9
Deleted: sha256:af161a47bb22852e9e3caf39f1dcd590b64bb8fae54315f9c2e7dc35b025e4e3
Deleted: sha256:feff1495e6982a7e91edc59b96ea74fd80e03674d92c7ec8a502b417268822ff
Deleted: sha256:8805862fcb6ef9deb32d4218e9e6377f35fb351a8be7abafdf1da358b2b287ba
Deleted: sha256:872d2f24c4c64a6795e86958fde075a273c35c82815f0a5025cce41edfef50c7
Deleted: sha256:6fdb3143b79e1be7181d32748dd9d4a845056dfe16ee4c827410e0edef5ad3da
Deleted: sha256:b0527c827c82a8f8f37f706fcb86c420819bb7d707a8de7b664b9ca491c96838
Deleted: sha256:75147f61f29796d6528486d8b1f9fb5d122709ea35620f8ffcea0e0ad2ab0cd0
Deleted: sha256:2938c71ddf01643685879bf182b626f0a53b1356138ef73c40496182e84548aa
Deleted: sha256:ad6b69b549193f81b039a1d478bc896f6e460c77c1849a4374ab95f9a3d2cea2
PS F:\Space\mysql> 
PS F:\Space\mysql> docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
PS F:\Space\mysql>

显然我已经成功删除了 MySQL 镜像,之前镜像也没有指明版本。这次我会安装 5.7 版本的,也是为了和韩老师的 MySQL 版本对应上。如果你不指明版本,那么默认会安装 latest 最新发布的版本,毕竟版本之间到底存不存在的差异性咱也不知道,万一存在一些差异那且不是还要重新安装那太麻烦了。
在这里插入图片描述

💡拉取指定版本的镜像

docker pull <镜像:版本>

PS F:\Space\mysql> docker pull mysql:5.7.37
5.7.37: Pulling from library/mysql
6552179c3509: Pull complete
d69aa66e4482: Pull complete
3b19465b002b: Pull complete
7b0d0cfe99a1: Pull complete
9ccd5a5c8987: Pull complete
44f5f7765d10: Pull complete
7e8f1dd5efbe: Pull complete
ab45b9a309e7: Pull complete
90242da46c57: Pull complete
9a8d822d1293: Pull complete
1704bf9fa775: Pull complete
Digest: sha256:ea24ddf1116d6e5053919748d2c27c8200e39ac0dbe9540f213a2d9141b66167
Status: Downloaded newer image for mysql:5.7.37
docker.io/library/mysql:5.7.37
PS F:\Space\mysql>

不过这个下载连接是真的有点慢,而且窗口还没有反应,像这种情况我每次都会按一下 ⬇ 键立马就好了,界面开始刷新出现下载信息,简直就是玄学😂😂。

PS F:\Space\mysql> docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
mysql        5.7.37    538ec2c8721c   3 days ago   448MB
PS F:\Space\mysql>

可以看到我已经成功下载 5.7.37 版本的 MySQL,但是这个日期是什么鬼创建时间明明是刚刚,这里却显示 3 天前,当然这些可以不用太担心,反正能用就行。

💡运行MySQL镜像并设置密码

docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

PS F:\Space\mysql> docker run --name java_mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.37
87893aae49c42597508318eea1ad48e8f64c6e3d22ed999f3fbe5bb626d8110a
PS F:\Space\mysql>

这里没啥好说的,完全是按照官网步骤。不过你如果运行你没有拉取版本的MySQL是不会成功的,docker 也会提醒你说本地没有相应 MySQL,但是如果 docker 联网找到了你输入版本的镜像,那么它会自动去下载。
如果想要实现本地软件连接docker里面的数据库,那么你可以通过 -p <本机端口:数据库端口>的方式来映射,详情请查看下面【外部连接MySQL】

PS F:\Space\mysql> docker run --name java_mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:latest
Unable to find image 'mysql:latest' locally
latest: Pulling from library/mysql
72a69066d2fe: Pull complete
93619dbc5b36: Pull complete
99da31dd6142: Pull complete
626033c43d70: Pull complete
37d5d7efb64e: Pull complete
ac563158d721: Pull complete
d2ba16033dad: Pull complete
688ba7d5c01a: Pull complete
00e060b6d11d: Pull complete
1c04857f594f: Pull complete
4d7cfa90e6ea: Pull complete
e0431212d27d: Pull complete
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709
Status: Downloaded newer image for mysql:latest
docker: Error response from daemon: Conflict. The container name "/java_mysql" is already in use by container "87893aae49c42597508318eea1ad48e8f64c6e3d22ed999f3fbe5bb626d8110a". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.
PS F:\Space\mysql>

💡查看MySQL镜像是否运行

docker ps

PS F:\Space\mysql> docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                 NAMES
87893aae49c4   mysql:5.7.37   "docker-entrypoint.s…"   8 minutes ago   Up 8 minutes   3306/tcp, 33060/tcp   java_mysql
PS F:\Space\mysql>

可以看见创建时间是 8 分钟之前,毕竟我刚刚还演示了运行拉取到本地的镜像,差不多也就花费了怎么多时间吧。

💡 进入运行的容器

docker exec -it <容器 ID> bash

PS F:\Space\mysql> docker exec -it 87893aae49c4 bash
root@87893aae49c4:/#

显然可以看出来终端的路径发生了改变,其实是因为我进入了运行的 MySQL 容器并通过参数 t 分配了一个伪终端。

💡进入 MySQL 服务

mysql -u root -p

root@87893aae49c4:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.37 MySQL Community Server (GPL)

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

💡查看数据文件位置

show variables like '%dir%';

mysql> show variables like '%dir%';
+-----------------------------------------+----------------------------+
| Variable_name                           | Value                      |
+-----------------------------------------+----------------------------+
| basedir                                 | /usr/                      |
| binlog_direct_non_transactional_updates | OFF                        |
| character_sets_dir                      | /usr/share/mysql/charsets/ |
| datadir                                 | /var/lib/mysql/            |
| ignore_db_dirs                          |                            |
| innodb_data_home_dir                    |                            |
| innodb_log_group_home_dir               | ./                         |
| innodb_max_dirty_pages_pct              | 75.000000                  |
| innodb_max_dirty_pages_pct_lwm          | 0.000000                   |
| innodb_tmpdir                           |                            |
| innodb_undo_directory                   | ./                         |
| lc_messages_dir                         | /usr/share/mysql/          |
| plugin_dir                              | /usr/lib/mysql/plugin/     |
| slave_load_tmpdir                       | /tmp                       |
| tmpdir                                  | /tmp                       |
+-----------------------------------------+----------------------------+
15 rows in set (0.01 sec)

通过变量名 datadir 可以了解到数据文件的位置。当然也可以通过变量 '%chars%' 查看当前数据库管理系统使用了什么字符集。
show variables like '%char%';

mysql> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

从这里可以看出客户端与服务端都没有使用 utf8 字符集,后续存储还需要配置中文字符集,因此需要将字符集设置成 uft8,虽然 utf8 支持的字符编码没有 utf8mb4 多,但不影响后续中文的显示问题。

📕外部连接MySQL

其实如果你希望容器里面的MySQL,可以通过外部的图像界面管理的话,只需要将端口映射一下就行了。
docker run -p <本机端口:数据库端口> --name <容器名称> -e MYSQL_ROOT_PASSWORD=<数据库密码> -d mysql:<版本号>

PS C:\Users\19095> docker run -p 8888:3306 --name java -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.37
ffbc1f2270f2fe9265884c0c95bfbbe2ae53e971a2aee6c80ebaa94b79d7b5c2
PS C:\Users\19095> docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                               NAMES
ffbc1f2270f2   mysql:5.7.37   "docker-entrypoint.s…"   12 seconds ago   Up 11 seconds   33060/tcp, 0.0.0.0:8888->3306/tcp   java
PS C:\Users\19095>

在这里插入图片描述
在这里插入图片描述
可以观察到在本地我通过 localhost 主机的8888端口成功连接上容器里面的数据库管理系统。

看来我完全成功了,又可以开始新的历程。

后续遇到什么问题也会更新在博客里面。

❌问题

❌中文字符存储错误

说什么来什么,我以为系统字符集为 utf8 ,那么我创建表的时候应该默认是 utf8 字符格式,终究还是太年轻了,技术不到家经验不足一起的毛病。
在这里插入图片描述
先看一下报错,本来就是想测试一下是什么影响表的默认字符集😌。这不是失误,而是故意为之,没错就是这样的😂。
show variables like '%char%';

mysql> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

其实上面也有介绍如何查看MySQL数据库客户端与服务端的字符集设置,不过还是介绍一下,避免大伙还去前面看命令。

这短短几行可以看的出来,客户端与服务端都是采用 latin1 编码方式,根据百度百科的描述这是一种 ISO-8859-1 的别名,反正这个是不支持汉字显示。

那么如何让中文数据直接存储到表里面去并且查询可以正确展示中文?

  • 数据库管理系统的配置文件

  • 指定数据库默认字符集

  • 指定表默认字符集

  • 指定字段默认字符集

在上面四种方法种对于目前我这种情况来说,当然是选择通过修改字段默认字符集来解决问题。

毕竟表已经形成了,再去通过修改数据库默认字符集和配置文件已经无济于事了。当然我也推荐大家使用第一种方式直接一步到位,省得以后还要来回改太麻烦了。

alter table <表名> convert to character set utf8;

mysql> alter table person convert to character set utf8;
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> show full columns from person;
+-------+-------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type        | Collation       | Null | Key | Default | Extra | Privileges                      | Comment |
+-------+-------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
| name  | varchar(25) | utf8_general_ci | YES  |     | NULL    |       | select,insert,update,references |         |
| age   | int(3)      | NULL            | YES  |     | NULL    |       | select,insert,update,references |         |
| sex   | varchar(1)  | utf8_general_ci | YES  |     | NULL    |       | select,insert,update,references |         |
+-------+-------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
3 rows in set (0.00 sec)

mysql>

在这里插入图片描述
显然我可以插入中文字符了,但是你以为这样就结束了。其实还并没有,因为终端还是无法显示中文。

mysql> select * from person;
+--------+------+------+
| name   | age  | sex  |
+--------+------+------+
| hjhcos |   13 | ?    |
+--------+------+------+
1 row in set (0.00 sec)

通过命令查看数据,sex 字符的数据直接打问号,这非常不方便我查询。

mysql> set character_set_results = utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

mysql> select * from java.person;
+--------+------+------+
| name   | age  | sex  |
+--------+------+------+
| hjhcos |   13 ||
+--------+------+------+
1 row in set (0.00 sec)

我通过设置 character_set_results 来解决这个问题。

❌重新进入容器终端字符集被重置

mysql> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)

因为这个问题并不会影响 Java 对数据查询,似乎只是客户端存在这种显示问题,其真实数据并没有改变,所以问题保留。

像我的话,并没有那种必须要依赖 docker 容器的终端去查看数据,完全可以利用 Java SQL查询命令查看或者使用本地连接容器数据库管理系统的软件查看都是非常方便的。


如果你是无意刷到这篇文章并看到这里,希望你给我的文章来一个赞赞👍👍。如果你不同意其中的内容或有什么问题都可以在下方评论区留下你的想法或疑惑,谢谢你的支持!!😀😀

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐