docker安装mysql8, 字符集,SQL大小写规范,sql_mode
一、Docker安装MySQL
使用Docker安装MySQL,命令如下
docker run -d \-p 3306:3306 \-v mysql_conf:/etc/mysql/conf.d \-v mysql_data:/var/lib/mysql \--name mysql \--restart=always \--privileged \-e MYSQL_ROOT_PASSWORD=1234 \mysql:8.0.30
- 参数解释
🐳 docker run -d
• docker run:创建并运行一个新的容器。
• -d:以 后台模式(detached) 运行容器,终端不会显示容器的日志。
⸻
🔌 -p 3306:3306
• 将 容器内部的 3306 端口(MySQL 默认端口)映射到 主机的 3306 端口。
• 格式是 -p 主机端口:容器端口,这样主机就能访问数据库服务。
⸻
📁 -v mysql8_conf:/etc/mysql/conf.d
• 把一个名为 mysql_conf 的 Docker 卷(volume)挂载到容器的 /etc/mysql/conf.d 目录。
• 作用:你可以把自定义的 MySQL 配置文件(如 my.cnf)放到这个卷中,MySQL 会自动加载。
⸻
📦 -v mysql8_data:/var/lib/mysql
• 把名为 mysql_data 的卷挂载到 MySQL 的 数据目录。
• 保证数据库数据持久化,即使容器重启或删除,数据不会丢失。
⸻
🔑 -e MYSQL_ROOT_PASSWORD=1234
• 设置 MySQL 的 root 用户密码为 1234。
• 这是 mysql:8.0.30 镜像要求的初始化密码环境变量,否则容器会启动失败。
⸻
🧾 --name mysql
• 给容器取一个名字叫 mysql。
• 这样你可以通过名字来操作容器,例如:docker stop mysql,而不需要记住容器 ID。
⸻
♻️ --restart=always
• 设置容器的自动重启策略为 always:
• Docker 启动时自动重启容器。
• 如果容器意外退出,也会自动重启。
⸻
🔐 --privileged
• 让容器拥有更高权限,类似于“超级用户模式”。
• 通常用于容器需要访问主机硬件或修改内核设置等特殊场景。
• 注意:不建议在非必要场合使用,存在安全风险。
⸻
🐬 mysql:8.0.30
• 使用的镜像是 mysql,版本为 8.0.30。
• 如果本地没有这个镜像,Docker 会从 Docker Hub 拉取。
- 等待安装完成
测试远程连接
1、先从最简单的终端开始
mysql -h yourLinuxIp -P 3306 -u root -p
# 如果用的是默认端口 -P 3306 可以省略 ,大P指定端口, 小p指定密码
回车输入密码
2、使用Navicat连接
测试连接:MySQL8版本,图形连接时还会出现如下问题
配置新连接报错:错误号码 2058,出现这个原因是MySQL 8 之前的版本中加密规则是mysql_native_password,而在MySQL 8之后,加密规则是caching_sha2_password。
解决方案:
方案一(推荐):升级SQLyog和Navicat(因此,新版SQLyog和Navicat不会出现此问题)
方案二:把MySQL用户登录密码加密规则还原成mysql_native_password。
解决方案: 登录你的 MySQL 数据库 登录你的 MySQL 数据库
# 用方法1先连接到mysql#修改默认密码校验方式
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '1111';
#ALTER USER: 修改用户信息。
#'root'@'%': 代表用户名是 root,% 是通配符,表示允许从任意主机连接(远程连接)。
#IDENTIFIED WITH mysql_native_password: 指定使用 mysql_native_password 插件进行身份验证(这是 MySQL 较早期版本使用的认证方式)。
#BY '1234': 设置新密码为 1111。
# 执行刷新权限在重新连接即可
FLUSH PRIVILEGES;
---- 到这里安装就已经结束了,下面是一些常见配置, 是一些了解的内容
二、mysql字符集
1、默认字符集
MySQL 8版本之前,默认字符集为 latin1(ISO-8859-1) ,不支持中文,使用前必须设置字符集为utf8(utf8mb3)或utf8mb4。从MySQL 8开始,数据库的默认字符集为 utf8mb4 ,从而避免中文乱码的问题。
-- 查看MySQL使用的字符集
SHOW VARIABLES LIKE '%char%';
2、 更改字符集
具体步骤:
1、编辑MySQL配置文件:打开MySQL的配置文件,通常是my.cnf(Linux)或my.ini(Windows)。可以使用文本编辑器打开该文件。
忘记挂载配置文件的目录可以通过查看
docker inspect 容器名
2.切换到此目录,创建my.cnf配置文件
cd /var/lib/docker/volumes/mysql_conf/_data
cd conf.d/
vim my.cnf
#i进入插入模式复制一下配置, 按ESC输入wq保存退出
3、添加字符集设置:在 [mysqld] 部分添加以下两行配置,用于设置默认字符集为UTF-8:
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
这将设置MySQL服务器的默认字符集为UTF-8,并使用utf8_general_ci作为默认的排序规则。
4、保存并关闭配置文件:保存对配置文件的修改,并关闭文本编辑器。
5、重启MySQL服务:重启MySQL服
务,以使配置更改生效。
docker restart mysql
# docker restart 容器名
查看是否生效
3、 utf8与utf8mb4
utf8 字符集表示一个字符需要使用1~4个字节,但是我们常用的一些字符使用1~3个字节就可以表示了。而字符集表示一个字符所用的最大字节长度,在某些方面会影响系统的存储和性能,所以,设计MySQL的设计者偷偷的定义了两个概念:
utf8mb3 :utf8mb3 阉割过的 utf8 字符集,只使用1~3个字节表示字符(无法存储emoji表情)。
utf8mb4:utf8mb4正宗的 utf8 字符集,使用1~4个字节表示字符。
注意:MySQL5.7中的utf8是utf8mb3字符集 , MySQL8.0中的utf8是utf8mb4字符集
三、 SQL大小写规范
1、 Windows和Linux的区别
**Windows环境:**全部不区分大小写
Linux环境:
1、数据库名、表名、表的别名、变量名严格【区分大小写】;
2、列名与列的别名【不区分大小写】;
3、关键字、函数名称【不区分大小写】;
2、 Linux下大小写规则设置
在MySQL 8中设置的具体步骤为:
show variables like 'lower_case_table_names'
1、停止MySQL服务
2、删除数据目录,即删除 /var/lib/mysql 目录
3、在MySQL配置文件(/etc/my.cnf )的 [mysqld] 中添加 lower_case_table_names=1
- 注意:不建议在开发过程中修改此参数,将会丢失所有数据。
四、 sql_mode
1、sql_mode简介
sql_mode是MySQL中的一个系统变量,用于控制MySQL服务器在执行SQL语句时的行为和规则。它定义了MySQL对于SQL语句的语法、数据校验和处理方式的严格程度。
sql_mode可以通过设置来改变MySQL的默认行为,常见的sql_mode值包括:
1、STRICT_TRANS_TABLES:启用严格模式,要求插入或更新操作中的数据类型必须与表定义的数据类型完全匹配,否则会抛出错误。
2、NO_ZERO_IN_DATE:禁止在日期中使用零值,例如’0000-00-00’,否则会抛出错误。
3、NO_ZERO_DATE:禁止在日期或日期时间字段中使用零值,例如’0000-00-00’或’0000-00-00 00:00:00’,否则会抛出错误。
4、ERROR_FOR_DIVISION_BY_ZERO:当除数为零时,执行除法运算会抛出错误。
5、ONLY_FULL_GROUP_BY(重点了解面试):要求GROUP BY子句中的列必须出现在SELECT列表中,或者是聚合函数的参数,否则会抛出错误。
6、ANSI_QUOTES:启用ANSI_QUOTES模式,要求使用双引号来引用字符串,而不是单引号。
除了上述常见的sql_mode值,还有其他一些选项可以根据需要进行配置。
可以通过以下方式查看当前的sql_mode设置:
SHOW VARIABLES LIKE 'sql_mode';
2、 更改sql_mode
临时设置
-- 全局针对所有的客户端连接有效,要重新启动客户端生效,重启MySQL服务后失效
SET GLOBAL sql_mode = 'mode1,model2,...';
-- 当前会话生效,关闭当前会话就不生效了。可以省略SESSION关键字
SET SESSION sql_mode = 'mode1,model2,...';
永久设置
在mysql配置文件中配置,永久生效:在mysql配置文件中配置,永久生效:在宿主机上执行以下命令,创建配置文件:
cd /var/lib/docker/volumes/mysql_conf/_data
cd conf.d/
vim my.cnf
编辑配置文件
[mysqld]
sql-mode = "mode1,model2,..."
重启mysql容器
docker restart mysql
案例演示(ONLY_FULL_GROUP_BY)
建表并插入数据:
CREATE DATABASE test;
USE test;
CREATE TABLE employee(
id INT,
`name` VARCHAR(16),
age INT,
dept INT);
INSERT INTO employee VALUES(1,'zhang3',33,101);
INSERT INTO employee VALUES(2,'li4',34,101);
INSERT INTO employee VALUES(3,'wang5',34,102);
INSERT INTO employee VALUES(4,'zhao6',34,102);
INSERT INTO employee VALUES(5,'tian7',36,102);
- 需求:查询每个部门年龄最大的人
-- 错误演示
-- 在SQL_MODE 约束 ONLY_FULL_GROUP_BY的情况下,分组时,select 后必须跟聚合函数(max min avg sum count),或者分组字段,name不满足上述情况所以报错
SELECT `name`, dept, MAX(age) FROM employee GROUP BY dept;
1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘testdb.employee.name’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
- 非 “ONLY_FULL_GROUP_BY” 模式下可以正常执行,但是得到的是错误的结果:
-- 不推荐设置,这里只是演示, 临时设置关闭此次连接就会失效
-- 把所有的模式全部清空
SET SESSION sql_mode = '';
正确的查询方式:查询应该分两个步骤:
1、查询每个部门最大的年龄
2、查询人
正确的语句:
SELECT name, e.dept,max_age from employee einner join (SELECT dept,max(age) max_age from employeegroup by dept) as group_max_age on e.dept=group_max_age.dept and e.age=group_max_age.max_age
如果修改了配置文件,测试完成后再将sql_mode设置回来:
SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
如果只是设置了,当前回话有效,直接关闭连接就可以.