开源的 MySQL、PostgreSQL 几乎已经成为新项目的默认选择,但存量企业系统——金融、电信、政府——仍然跑在 Oracle 和 SQL Server 上。这些数据库在 Docker 化时遇到的问题和 MySQL 不一样:Oracle 需要改字符集和表空间,SQL Server 对 SA 密码有强校验、还需要 ODBC 驱动。这篇文章把两个"老牌商业数据库"在 Docker 里的安装、字符集、备份、客户端连接一次性说清楚。
阅读对象:维护 Oracle 11g/12c 遗留系统、需要在容器里跑 SQL Server 给 .NET 应用、或者为演示环境准备"商业数据库"镜像的工程师。
覆盖范围:Oracle 11g(helowin 镜像)安装、字符集改 ZHS16GBK、创建表空间与用户、expdp/impdp 数据泵;SQL Server 2019/2022 容器启动、密码策略、ODBC 驱动连接。
一、为什么要在 Docker 里跑商业数据库
| 场景 | 价值 |
|---|
| 演示 / 培训环境 | 一行 docker run 拉起一个完整 Oracle/SQL Server,不用装 Windows 虚拟机 |
| CI/CD 集成测试 | 每个 Pipeline 起一个干净实例,测完即弃 |
| 跨平台交付 | Linux 容器里的 SQL Server 让 .NET Core 跨平台运行真正可行 |
| 资源隔离 | 给每个客户/项目单独容器,避免一台机器装多版本冲突 |
| 版本快照 | 数据卷打 tag → 镜像化 → 跨环境一致 |
注意:生产环境仍建议用物理机/RDS/云数据库,Docker 化适合"非关键路径"——演示、测试、临时验证。Oracle 官方对容器的支持在 12c 之后才完善,11g 主要是社区镜像。
二、Oracle 11g(helowin 镜像)
helowin/oracle_11g 是国内开发者基于 Oracle 11g 打包的镜像(含 sqlplus / expdp / impdp),体积约 2.5GB,是 Docker 圈里最常用的"演示用 Oracle"。
2.1 拉取与启动
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 1. 拉镜像
docker pull registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g
# 2. 创建数据目录并授权(容器里 oracle 用户 UID=500)
mkdir -p /home/data/oracle/test/data_emp
chown -R 500.500 /home/data/oracle/test/data_emp
# 3. 启动容器
docker run -d --name oracle_11g_test \
-p 1523:1521 \
--restart=always \
-v /home/data/oracle/test/data_emp:/home/oracle/data_temp \
registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g
|
挂载 /home/oracle/data_temp:这是 Oracle 的 DIRECTORY 路径,导入导出文件都走这里。把宿主机目录挂载进来,备份文件就能直接在宿主机拿到。
2.2 修改 system 密码 & 创建用户
1
2
3
4
5
6
7
8
9
| # 1. 进入容器
docker exec -it <container_id> /bin/bash
# 2. 加载环境变量,切换到 oracle 用户
source ~/.bash_profile
sqlplus /nolog
SQL> connect /as sysdba; # OS 认证,最高权限
SQL> select status from v$instance; -- 应为 OPEN
SQL> alter user system identified by oracle; -- 改密码
|
解锁 scott 示例账户(helowin 镜像默认带 scott 库):
1
2
3
4
5
6
| SQL> alter user scott account unlock;
SQL> commit;
SQL> grant dba to scott;
SQL> grant resource to scott;
SQL> grant connect to scott;
SQL> alter user scott identified by 123456;
|
2.3 修改字符集为 ZHS16GBK
Oracle 11g 默认是 WE8MSWIN1252(美式编码),中文数据会乱码。改成 ZHS16GBK:
1
2
3
4
5
6
7
8
9
10
11
12
| SQL> select * from nls_database_parameters where parameter = 'NLS_CHARACTERSET';
-- 记录当前值
SQL> shutdown immediate;
SQL> startup mount;
SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;
SQL> alter database open;
SQL> ALTER DATABASE character set INTERNAL_USE ZHS16GBK;
SQL> shutdown immediate;
SQL> startup;
|
关键:INTERNAL_USE 关键字跳过字符集子集检查,从 AL32UTF8 / WE8MSWIN1252 强制改 ZHS16GBK。改完重启后用第 1 步的 select 复查。
2.4 创建表空间、用户、授权
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| -- 查询临时表空间路径(用它的父目录)
SQL> select name from v$tempfile;
-- 创建表空间
SQL> create tablespace cmcc
datafile '/home/oracle/app/oracle/oradata/helowin/cmcc.dbf'
size 2G reuse autoextend on next 500M maxsize unlimited
default storage(initial 128k next 128k minextents 2 maxextents unlimited);
-- 创建用户(指定默认表空间)
SQL> create user test01 identified by testpasswd
default tablespace cmcc
temporary tablespace TEMP;
-- 授权
SQL> grant connect, dba, exp_full_database, imp_full_database
to test01 with admin option;
|
2.5 创建 DIRECTORY(数据泵路径)
1
| SQL> create or replace directory DATA_TEMP as '/home/oracle/data_temp';
|
这样 expdp / impdp 用 directory=DATA_TEMP 导出/导入的文件直接在宿主机就能看到。
2.6 数据泵导入/导出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 导出 scott 用户的全 schema
expdp scott/123456@helowin schemas=scott dumpfile=expdp.dmp DIRECTORY=DATA_TEMP;
# 导入到 test01 用户
impdp scott/123456@helowin schemas=scott dumpfile=expdp.dmp DIRECTORY=DATA_TEMP;
# 替换 schema(把 scott 导入到 test01)
impdp test01/testpasswd@helowin table_exists_action=replace \
directory=DATA_TEMP dumpfile=BPM.EXPDP \
logfile=BPM_20180124.log \
REMAP_SCHEMA=scott:test01 schemas=scott;
# 旧版 imp(10g 时代的 dmp 文件)
imp scott/123456@helowin file=/home/oracle/data_temp/dbzznew_2020-03-26.dmp full=y;
|
2.7 定时备份脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
| cat << 'EOF' > /home/oracle/oracle_backup.sh
#!/bin/bash
source /home/oracle/.bash_profile
a=$(date +%Y%m%d)
expdp scott/123456@helowin schemas=scott \
dumpfile=bpm_$a.dmp DIRECTORY=DATA_TEMP
EOF
chmod 777 /home/oracle/oracle_backup.sh
# 每天凌晨 3 点备份
echo "* 3 * * * root /home/oracle/oracle_backup.sh" >> /etc/crontab
service crond start
|
三、SQL Server 2019/2022
微软从 SQL Server 2017 开始官方支持 Linux,2019/2022 在 Linux 上的稳定性已经非常好。Docker 镜像基于 Ubuntu,是 .NET 跨平台部署的关键拼图。
3.1 拉取与启动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # 查看可用版本
docker search mssql
docker pull mcr.microsoft.com/mssql/server:2022-latest
docker pull mcr.microsoft.com/mssql/server:2019-latest
# 创建数据目录
mkdir -p /home/docker/mssql/2022
chmod 777 /home/docker/mssql/2022
# 启动 SQL Server 2022
docker run -d --name mssql2022 \
--restart=always \
-e "ACCEPT_EULA=Y" \
-e "MSSQL_SA_PASSWORD=<your-org>@123456" \
-p 1433:1433 \
-v /home/docker/mssql/2022:/var/opt/mssql \
mcr.microsoft.com/mssql/server:2022-latest
|
关键参数:
ACCEPT_EULA=Y:必须接受许可MSSQL_SA_PASSWORD:必须满足强密码策略(≥8 字符、含大写/小写/数字/非字母数字符号,如 <your-org>@123456)- 不满足强密码策略会启动失败,日志里会写
Password validation failed
创建数据库 + 应用账号(可选,启动时也可以指定):
1
2
3
4
5
6
7
8
9
10
11
| docker run -d --name mssql \
-e "ACCEPT_EULA=Y" \
-e "MSSQL_SA_PASSWORD=<your-org>@123456" \
-e "MSSQL_PID=Express" \ # 指定 Express 版(免费)
-e "SQLSERVER_DATABASE=demo" \ # 启动时创建 demo 库
-e "SQLSERVER_USER=xiaofei" \ # demo 库的专属用户
-e "SQLSERVER_PASSWORD=<your-org>@123456" \
-p 1433:1433 \
--restart=always \
-v /home/docker/mssql:/var/opt/mssql \
mcr.microsoft.com/mssql/server:2019-latest
|
3.2 进入容器操作
1
2
3
4
5
6
7
8
9
10
11
12
| docker exec -it mssql bash
# 使用 sqlcmd 连接
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "<your-org>@123456"
# 在 sqlcmd 中
1> use master
2> go
1> select * from ftable
2> go
3> exit
# 容器里 Ctrl+D 退出
|
Why sqlcmd? sqlcmd 是微软官方的命令行客户端,linux 版工具包在 /opt/mssql-tools/bin/。比图形化工具轻量,适合 CI 脚本和排错。
3.3 客户端连接(Windows)
SQL Server 容器跑在 Linux 上,Windows 客户端用 ODBC Driver 18(2022 之后强制)连接:
坑:旧的 SQL Server Native Client 11.0 已经被微软停维护(2025 年),新项目不要再用它。
3.4 Navicat 创建数据库的建议配置
| 项 | 推荐值 |
|---|
| 排序规则 | Chinese_PRC_CI_AS(中文、不区分大小写) |
| 恢复模式 | SIMPLE(开发/演示环境;生产用 FULL + 定期日志备份) |
| 兼容级别 | 100(SQL Server 2008 兼容)或 150(SQL Server 2019) |
| 文件初始大小 | 数据 100MB、日志 50MB(按业务增长可调) |
四、Oracle 11g vs SQL Server 2019/2022:选型速查
| 维度 | Oracle 11g | SQL Server 2019/2022 |
|---|
| 起源 | 1977(最早商用 RDBMS) | 1989(Sybase 衍生) |
| Docker 官方支持 | 12c 之后才有 | 2017 之后 |
| 推荐镜像 | helowin/oracle_11g(社区) | mcr.microsoft.com/mssql/server(官方) |
| 镜像大小 | ~2.5GB | ~1.5GB |
| 内存需求 | ≥2GB | ≥2GB(Express 256MB) |
| 字符集 | 默认 WE8MSWIN1252,要手动改 ZHS16GBK | 默认 SQL_Latin1_General_CP1_CI_AS(中文/西文混排可接受) |
| 备份工具 | expdp/impdp(数据泵) | BACKUP DATABASE / VDP / Ola Hallengren 脚本 |
| 客户端 | sqlplus、PL/SQL Developer | SSMS、Azure Data Studio、sqlcmd |
| 跨平台 | Linux/Win(11g 主要跑在 Linux) | 2017 之后完整 Linux 支持 |
| 授权模式 | 按 CPU 授权,贵 | 标准版/企业版/Express(免费) |
经验法则:
- 老项目迁云、ERP/金融 → Oracle
- .NET Core 跨平台 / 中小企业 OA → SQL Server
- 临时演示 / 培训 → 两个都可以容器化,SQL Server 启动更轻
五、扩展阅读