一.制作docker镜像
在当前目录新建子目录script, 将数据库初始化脚本拷贝进去,后缀名为 *.sql,脚本执行顺序是按字母大小排序,建议可以按 1_xxx.sql, 2_xxx.sql这样命令。
Dockerfile如下
FROM mysql:5.7 AS base
WORKDIR /docker-entrypoint-initdb.d
COPY script/ ./
运行构建命令: docker build -t mysql:test .
二. 制作docker-compose.yml文件
version: "3.8"
services:
db_test:
image: mysql:test
volumes:
- /etc/localtime:/etc/localtime:ro
- /mydata:/var/lib/mysql
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --log-timestamps=SYSTEM
environment:
- MYSQL_ROOT_PASSWORD=111111
- MYSQL_USER=test
- MYSQL_PASSWORD=123456
container_name: mysql_test
~
运行docker-compose up -d 启动容器,当/mydata目录为空时,会执行数据库初始化脚本。
坑一:因文件格式导致的 sql 语法错误
我在本地写sql脚本时保存的是UTF8 BOM格式的文件,如果使用linux shell的脚本合并到别的文件时,会把BOM前缀也写进去,这会导致初始化提示SQL syntax错误,这个问题当时一直没弄明白,后来用vi编辑器一看才发现。
重现步骤如下
echo '#hello' > test.sql
cat init.sql >> test.sql
然后用vi编辑一看,就发现一些奇怪的字符(蓝色标记的)
解决办法如下:用sed去掉特殊字符
sed $'1s/^\xEF\xBB\xBF//' < ./init.sql >> test.sql
坑二: 初始化后中文数据在数据表里变成了乱码
在每个数据库脚本文件的第一行加上:
SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';
注意:笔者是使用的utf8mb4_unicode_ci, 如果你使用的是别的编码,可以换成你的。
可用如下命令查询编码:
附加到mysql容器上
docker exec -it mysql_test sh
登录mysql命令行交互模式
mysql -u root -p
查询编码
show variables like '%char%';
show variables like '%collation%';
如果要在mysql命令行交互模式下查看中文数据,需要加参数,如下
mysql -u root --default-character-set=utf8mb4 -p
坑三: 脚本里的存储过程创建报错,提示语法错误
默认delimiter是分号, 存储过程内容里肯定包含了分号,所以在创建存储过程时,需要先切换delimiter, 创建完了之后再还原,示例如下:
delimiter $$
DROP PROCEDURE IF EXISTS TestProc;
CREATE PROCEDURE TestProc()
Begin
...
...
End; $$
delimiter ;