达梦数据库 DM8 大小写敏感配置与 Docker 部署实战
达梦数据库 DM8 大小写敏感配置与 Docker 部署实战
以“我到底是不是大小写敏感、怎么改成不敏感”为主线,梳理一套可直接操作的 DM8 使用笔记。
1. 场景背景
在容器环境下部署达梦数据库 DM8(单机版)时,我们通常会写出类似的命令:
docker run -itd -p 5236:5236 --restart=always --name dm8_test --privileged=true -e PAGE_SIZE=16 -e LD_LIBRARY_PATH=/opt/dmdbms/bin -e EXTENT_SIZE=32 -e BLANK_PAD_MODE=1 -e LOG_SIZE=1024 -e UNICODE_FLAG=1 -e LENGTH_IN_CHAR=1 -e INSTANCE_NAME=dm8_test -v /data/dm8/data:/opt/dmdbms/data dm8_single:dm8_20240715_rev232765_x86_rh6_64
一切都启动得很顺利,但在开发和联调阶段,表名 / 字段名 / 字符串条件的大小写问题就开始频繁“背刺”我们:
- 有时
select * from user报错,说找不到表; - 有时框架生成的 SQL 默认小写,而我们在工具里一直用大写;
- 有时字符串比较发现
"abc"和"ABC"并不相等……
这背后其实都指向同一个核心问题:DM8 的大小写敏感配置(CASE_SENSITIVE)。
本文围绕以下几个问题展开:
- 我现在这套 DM8 实例到底是不是大小写敏感?
- 如果现在是大小写敏感,有没有办法改成不敏感?
- 在 Docker 部署场景下,应该如何正确设置大小写敏感?
- 不想删库的前提下,有哪些“折中方案”?
2. DM8 的大小写敏感到底管什么?
DM8 里常说的“大小写敏感”,由一个初始化参数控制:CASE_SENSITIVE。它主要影响两类行为:
- 数据库对象标识符
- 表名、字段名、索引名、视图名、用户等。
- 字符串比较行为
- 如
WHERE NAME = 'abc'是否把'abc'和'ABC'看作相等。
- 如
2.1 标识符的基本规则
-
未加双引号的标识符:会被自动转换为大写
CREATE TABLE test(id INT); -- 等价于 CREATE TABLE "TEST"("ID" INT); -
加了双引号的标识符:完全按原始大小写存储和匹配
CREATE TABLE "test"( "Id" INT );
在大小写敏感的库中:
SELECT * FROM TEST和SELECT * FROM test:- 如果表是
CREATE TABLE TEST建的,一般都没问题,因为内部是"TEST"; - 如果你曾经使用过乱七八糟的双引号写法,就可能出现“有的 SQL 能查,有的查不到表”的情况。
- 如果表是
2.2 字符串比较的差异
DM8 在大小写敏感库中,字符串比较默认区分大小写:
SELECT 'abc' = 'ABC'; -- 结果通常为 0(不相等)
而在大小写不敏感库中:
SELECT 'abc' = 'ABC'; -- 可以认为是相等
这对应用框架非常关键,尤其是:
- 用户名 / 账号名称的匹配;
- 代码里写死的字符串常量;
- ORM 框架生成的 SQL 习惯;
- 老系统迁移过来之后,原来在其它数据库里“不区分大小写”的查询,在 DM8 里突然查不到数据。
3. 如何确认当前实例是否大小写敏感?
判断一个 DM8 实例是否大小写敏感,是通过查询函数,而不是看 docker 命令。
3.1 连接到 DM8
以 Docker 单机镜像为例,在宿主机执行:
docker exec -it dm8_test bash
disql SYSDBA/SYSDBA001
说明:
SYSDBA/SYSDBA001是默认账号密码,实际按你的配置为准。
3.2 查询 CASE_SENSITIVE 状态
在 disql> 提示符下执行:
SELECT CASE_SENSITIVE();
或者部分版本的函数名可能为:
SELECT SF_GET_CASE_SENSITIVE_FLAG();
返回值含义:
- 返回
1:大小写敏感 - 返回
0:大小写不敏感
一般情况下,如果你在 docker 启动时 没有显式指定 CASE_SENSITIVE 环境变量,那么大概率是默认的 1(敏感)。
4. CASE_SENSITIVE 的关键点:只在“建库那一次”生效
这一步是很多人踩坑的地方。结论先说:
CASE_SENSITIVE 是建库(初始化)参数,数据库一旦创建成功,该属性就不能修改。
表现为:
-
第一次启动 DM8 容器时,如果挂载的 data 目录是空的,入口脚本会自动调用
dminit初始化数据库,这时会读取CASE_SENSITIVE环境变量:- 设为
0⇒ 建一个大小写不敏感库; - 设为
1(或不设置,使用默认值)⇒ 建一个大小写敏感库。
- 设为
-
之后再重启容器时,只要 data 目录里已有数据库文件:
- 不会再次执行 dminit;
- 也就不会再理会
CASE_SENSITIVE这个环境变量; - 即使你后来 docker run 时加上
-e CASE_SENSITIVE=0,也不会改变库的属性。
-
官方文档也说明:
- 可通过
CASE_SENSITIVE()或SF_GET_CASE_SENSITIVE_FLAG()查询; - 数据库创建成功后无法修改。
- 可通过
4.1 改环境变量能不能“救回来”?
不能。典型错误操作:
docker run -itd -p 5236:5236 --name dm8_test ... -e CASE_SENSITIVE=0 -v /data/dm8/data:/opt/dmdbms/data dm8_single:dm8_20240715_rev232765_x86_rh6_64
如果 /data/dm8/data 里已经有之前初始化好的库,那:
- 容器可以启动;
- 数据库照常工作;
- 但是仍然是老的大小写敏感属性。
所以 不能指望“改个 docker 环境变量+重启”就把库变成不区分大小写。
5. 想改成不敏感,有哪些方案?
我们分几种典型需求来分析。
5.1 方案一:数据还不重要,直接重建库(最简单)
适用于:刚试用 DM8,库里数据只是临时测试,不需要保留。
步骤:
- 停容器并删除:
docker stop dm8_test
docker rm dm8_test
- 清空原有数据目录(慎重):
rm -rf /data/dm8/data/*
- 带上
CASE_SENSITIVE=0重新启动容器(新库):
docker run -itd -p 5236:5236 --restart=always --name dm8_test --privileged=true -e PAGE_SIZE=16 -e LD_LIBRARY_PATH=/opt/dmdbms/bin -e EXTENT_SIZE=32 -e BLANK_PAD_MODE=1 -e LOG_SIZE=1024 -e UNICODE_FLAG=1 -e LENGTH_IN_CHAR=1 -e CASE_SENSITIVE=0 \ # ★ 不区分大小写
-e INSTANCE_NAME=dm8_test -v /data/dm8/data:/opt/dmdbms/data dm8_single:dm8_20240715_rev232765_x86_rh6_64
- 重新建库成功后,
SELECT CASE_SENSITIVE();应该返回0。
优点:
- 简单粗暴,一步到位;
- 不会有历史数据遗留问题。
缺点:
- 原来的数据全部丢弃,只适用于测试环境或数据可抛弃的场景。
5.2 方案二:保留旧库 + 新建一个不敏感新库(推荐)
适用于:
- 目前这套大小写敏感的库已经在使用,有数据、有业务;
- 又希望后续逐步迁移到大小写不敏感的环境。
核心思路:
老库不动,新起一个“大小写不敏感”的 DM8 实例,然后通过导出导入的方式迁移数据。
5.2.1 新建一个不敏感 DM8 实例
- 创建一个新的数据目录:
mkdir -p /data/dm8/data_cs0
- 启动一个新容器(端口换一个,避免冲突):
docker run -itd -p 5237:5236 --restart=always --name dm8_cs0 --privileged=true -e PAGE_SIZE=16 -e LD_LIBRARY_PATH=/opt/dmdbms/bin -e EXTENT_SIZE=32 -e BLANK_PAD_MODE=1 -e LOG_SIZE=1024 -e UNICODE_FLAG=1 -e LENGTH_IN_CHAR=1 -e CASE_SENSITIVE=0 \ # ★ 新库不敏感
-e INSTANCE_NAME=dm8_cs0 -v /data/dm8/data_cs0:/opt/dmdbms/data dm8_single:dm8_20240715_rev232765_x86_rh6_64
现在你有两套库:
- dm8_test:原库(大小写敏感),端口 5236,对应
/data/dm8/data; - dm8_cs0:新库(大小写不敏感),宿主机访问端口 5237,对应
/data/dm8/data_cs0。
5.2.2 导出导入数据
根据实际情况选择工具:
- 使用 DM 自带的
dexp/dimp; - 使用 DTS 或图形化工具;
- 或者写脚本从旧库 SELECT,再插入新库。
迁移的一般步骤:
- 在旧库上导出目标用户/模式的数据;
- 在新库上创建对应用户/表空间;
- 在新库上导入数据;
- 回归测试:对应用指向新库连接串,观察业务功能是否正常;
- 迁移完成后,再考虑是否下线旧库。
优点:
- ✅ 不破坏旧环境,出现问题还能立即切回;
- ✅ 可以逐步迁移,不用“一刀切”;
- ✅ 对生产环境更安全。
缺点:
- 需要一套导出导入流程,工作量稍大;
- 应用侧需要切换连接串。
5.3 方案三:不重建库,SQL 层“伪装”成不敏感
如果暂时不想折腾两套实例,或者生产环境短期没法迁移,也可以在 SQL 层做一些折中处理。注意,这不能改变底层的大小写敏感属性,只是减轻部分问题。
5.3.1 对字符串查询使用 UPPER/LOWER
例如,对用户名做不区分大小写的匹配:
SELECT * FROM T_USER
WHERE UPPER(USERNAME) = UPPER(:name);
优点:快速见效,不需要改库。
缺点:
- 影响查询性能(索引可能无法走等值匹配);
- 需要在大量 SQL 中人为维护这个习惯。
5.3.2 规范对象命名:统一使用大写且不加双引号
在大小写敏感库中,统一使用“大写 + 不加双引号”的写法,会好很多:
-- 推荐:
CREATE TABLE USER_INFO (
ID INT,
USERNAME VARCHAR(64)
);
-- 不推荐:
CREATE TABLE "user_info"(
"Id" INT,
"UserName" VARCHAR(64)
);
这样做的好处是:
- 应用中
select * from user_info这类 SQL,一般都能正常工作(会转为大写匹配); - 避免“偶尔加了一次双引号,从此永远要按那个奇怪的大小写写 SQL”这种坑。
6. 实战总结与最佳实践
结合 Docker 部署 DM8 的场景,推荐的实践顺序如下:
-
在第一次部署前就想清楚:是否需要大小写不敏感?
- 如果系统来自 MySQL/Oracle 等且原本就是“不太 care 大小写”的写法,建议一开始就设置
CASE_SENSITIVE=0。
- 如果系统来自 MySQL/Oracle 等且原本就是“不太 care 大小写”的写法,建议一开始就设置
-
初始化新实例时显式设置
CASE_SENSITIVE:- 想不敏感 ⇒
CASE_SENSITIVE=0; - 想敏感 ⇒
CASE_SENSITIVE=1(或默认值)。
- 想不敏感 ⇒
-
始终把 data 目录挂载到宿主机,避免库被误删:
-v /data/dm8/data:/opt/dmdbms/data -
千万不要指望“加环境变量+重启”能改变大小写敏感:
- 环境变量只在“data 目录为空,首次初始化”的时候生效;
- 数据库一旦创建成功,CASE_SENSITIVE 就不能改。
-
需要从敏感切换到不敏感时:优先考虑“新建库+迁移数据”的温和方案:
- 老库继续对外提供服务;
- 新库逐步导入数据、调试、验证;
- 等新库验证通过,再切换应用连接串。
-
短期内无法迁移时,可在业务层/SQL 层增加大小写兼容逻辑:
- 字符串比较使用
UPPER()/LOWER(); - 严格规范对象命名规则,统一大写无引号。
- 字符串比较使用
7. 简要 FAQ
Q1:我不删容器,只是清空挂载目录,再加 CASE_SENSITIVE=0,行不行?
- 技术上可以:容器启动时发现 data 目录为空,会重新初始化库,新的库会按
CASE_SENSITIVE=0设置; - 但是本质上等价于“重建库”,原数据全部丢失,和删容器没太大区别。
Q2:我能不能只在同一个容器里,新建第二套库(不敏感),然后改配置让实例用新库?
- 理论上可以,但需要改容器里的脚本和配置,操作复杂且不符合容器“一次性”的理念;
- 实际上 新起一个容器+新 data 目录 更干净、可控。
Q3:字符串大小写不敏感,但对象名我还是希望区分大小写,可以吗?
- 这涉及更细粒度的配置和具体版本特性,通常建议按“整体敏感 / 不敏感”来规划;
- 若有精细化需求,建议在测试环境充分验证后再上生产。
8. 结语
DM8 在大小写敏感这件事上和很多人习惯的数据库略有不同:
- 一旦库建好,属性就固定;
- 想改,只能通过新建实例 + 数据迁移的方式来实现。
好处是:行为非常确定,没有“半路改配置导致各种诡异兼容问题”;
坏处是:如果前期没设计好,后期调整会有点麻烦。
如果你正打算在新的项目里引入 DM8,强烈建议在刚开始就把 CASE_SENSITIVE 设计清楚,免得上线后才发现“原来框架默认是大小写不敏感的写法”,再回头填坑就费劲多了。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)