前言
安装完达梦数据库后,需要初始化实例,在初始化实例时,需要注意大小写敏感的设置。大小写敏感只能在初始化数据库的时候设置,默认为大小写敏感,一旦设置成功就无法修改,如果想要修改,只能重新初始化实例。本文主要介绍达梦数据库中的大小写敏感问题,将会从对象名、字符串内容、常用工具这三个方面介绍达梦数据库的大小写敏感和大小写不敏感设置的区分和介绍,希望大家看完这篇文章能够完全搞明白。本文验证环境如下:
操作系统 | CPU | 数据库 |
---|---|---|
CentOS7 | x86_64 架构 | dm8_20240920_x86_rh7_64 |
一、概述
1.1 标识符
在介绍大小写敏感之前,我们需要先聊聊什么是 标识符。在 DM 数据库中,标识符(Identifier)是用来唯一标识数据库对象的名称。标识符可以是表、列、视图、索引、存储过程、函数等对象的名称,我们可以在 SQL 查询和数据库操作中引用这些对象。标识符具有以下特性和规则:
-
唯一性:每个标识符在其特定作用域内(例如,在同一个数据库或模式中)必须是唯一的。
-
命名规则:标识符通常遵循一定的命名规则,包括:
- 只能包含字母、数字和下划线
_
- 必须以字母或下划线开头
- 不能使用 SQL 保留字(例如,
SELECT
、FROM
、WHERE
等)作为标识符 - 不同的数据库系统可能对标识符的长度和字符集有不同的限制
- 只能包含字母、数字和下划线
-
大小写敏感性:在达 DM 数据库中,如果初始化数据库是大小写敏感的,标识符就是大小写敏感,如果初始化数据库是大小写不敏感的,标识符就是大小写不敏感。
-
引用方式 :标识符可以用双引号 " 或反引号 ` 包围,这在需要使用保留字或包含特殊字符时非常有用。例如:
sqlCREATE TABLE "My Table" (id INT); CREATE TABLE `My-Table` (id INT);
以下是一些标识符的示例:
标识符 | 举例说明 |
---|---|
表标识符 | Employees、Orders、Products等 |
列标识符 | employee_id、order_date、product_name |
视图标识符 | SalesView、CustomerData |
存储过程标识符 | CalculateTax、GetEmployeeDetails |
1.2 大小写敏感
DM 数据库的大小写是否敏感由初始化参数设置,初始化之后无法修改,也就是说在建库时一定要确认好。对于 DM 数据库的大小写敏感,有以下几种情况:
- 标识符
- 大小写敏感 :小写的标识符应使用双引号
""
括起来,就可以区分大小写,意味着可以创建相同名称不同大小写的表、索引等对象,或者在一张表中拥有不同大小写的列名。 - 大小写不敏感:标识符被双引号括起来也不会使数据库区分大小写。
- 大小写敏感 :小写的标识符应使用双引号
- 数据库用户密码:在达梦中,用户管理相关功能并不受大小写是否敏感参数的影响。用户名会始终强转为大写,无论有没有使用双引号包裹,CREATE USER、ALTER USER 均如此,而密码始终区分大小写。
- 模式管理
- 大小写敏感:可拥有两个同名不同大小写的模式,这两个模式需要属于同一个用户。
- 大小写不敏感:只可以拥有大写的模式名。
- 数据管理
- 大小写敏感:数据存储及数据比较区分大小写。
- 大小写不敏感:数据存储本身仍是保持原有的大小写,但是比较的时候默认不区分。
官方文档中对于大小写敏感的介绍如下:
参数 | 函数 | 建库后是否可修改 |
---|---|---|
CASE_SENSITIVE | 标识符大小写是否敏感。Y、y、1 表示敏感, N、n、0 表示不敏感,缺省值为 Y。 当大小写敏感时,小写的标识符应用双引号括起,否则被转换为大写; 当大小写不敏感时,系统不自动转换标识符的大小写,系统比较函数会将大写字母全部转为小写字母再进行比较 | 不可修改 |
那么,如何查看当前数据库中大小写是否敏感呢?大小写敏感查询命令:
sql
select case_sensitive();
如果 CASE_SENSITIVE
的值为 1,代表是大小写敏感,为 0 则代表不敏感。
二、实战演示
接下来,我们从 DM 数据库安装开始演示一下,大小写敏感在初始化数据库时是如何设置,以及在初始化后对数据库的影响表现。
2.1 初始化数据库
这里使用一键安装脚本快速安装 DM 数据库,如果指定数据库 大小写敏感参数为 1,则执行如下命令:
bash
./DMShellInstall -di dm8_20240920_x86_rh7_64.iso -d /opt/dmdbms -cs 1
若是制定数据库大小写敏感参数为 0,则执行以下命令:
bash
./DMShellInstall -di dm8_20240920_x86_rh7_64.iso -d /opt/dmdbms -cs 0
注意:通过指定脚本参数
-cs
的值即可控制数据库大小写是否敏感。
2.2 数据测试
DM 数据库安装完成后,检查当前数据库是否为大小写敏感:
bash
-- 大小写敏感
SQL> select case_sensitive();
行号 CASE_SENSITIVE()
---------- ----------------
1 1
-- 大小写不敏感
SQL> select case_sensitive();
行号 CASE_SENSITIVE()
---------- ----------------
1 0
2.2.1 创建表验证
创建测试表,表名分别为 T1、t2、"T3"、"t4"`,分别在大小写敏感和不敏感的数据库中执行,结果如何?
sql
CREATE TABLE T1 (id INT, c VARCHAR(50));
CREATE TABLE t2 (id INT, c VARCHAR(50));
CREATE TABLE Tt3 (id INT, c VARCHAR(50));
CREATE TABLE "T4" (id INT, c VARCHAR(50));
CREATE TABLE "t5" (id INT, c VARCHAR(50));
CREATE TABLE "Tt6" (id INT, c VARCHAR(50));
测试表创建完成后,查看创建好的测试表:
bash
-- 大小写敏感
SQL> select table_name from user_tables;
行号 TABLE_NAME
---------- ------------------
2 T1
3 T2
4 TT3
5 T4
6 t5
7 Tt6
-- 大小写不敏感
SQL> select table_name from user_tables;
行号 TABLE_NAME
---------- ------------------
2 T1
3 t2
4 Tt3
5 T4
6 t5
7 Tt6
从上述结果可以发现,在大小写不敏感的数据库中,创建后的表名与创建时的表名保持一致。而大小写敏感的数据库中,表现不一样:
- 不加双引号:T1、t2、Tt3 表,不管创建时表名是大写还是小写,创建后的表名均为大写。
- 加双引号:T4、t5、Tt6 表,由于加了双引号,所以创建后的表名和建表时保持一致。
⚠️注意⚠️:在大小写敏感的情况下,在 DM 管理工具中使用图形化界面的方式创建对象时,如果使用的是小写,系统会自动加上双引号在查询的时候必须使用双引号来访问。
2.2.2 插入数据验证
如果我们使用创建时的表名去插入测试数据,分别在大小写敏感和不敏感的数据库中执行,能插入成功吗?
sql
INSERT INTO T1 (id, c) VALUES (1, 'Test1'), (2, 'Test2');
INSERT INTO t2 (id, c) VALUES (1, 'test1'), (2, 'test2');
INSERT INTO Tt3 (id, c) VALUES (1, 'test1'), (2, 'test2');
INSERT INTO "T4" (id, c) VALUES (1, 'Test3'), (2, 'Test4');
INSERT INTO "t5" (id, c) VALUES (1, 'test3'), (2, 'test4');
INSERT INTO "Tt6" (id, c) VALUES (1, 'test3'), (2, 'test4');
COMMIT;
执行没有报错,是可以成功插入的,可以看到我们在插入数据时,表数据时有大小写区分的,可以验证查询条件的值是否也是区分大小写。
2.2.3 查询数据验证
-
大小写敏感
sql-- 表 T1 中存在符合 Test1 的数据,所以可以成功查询 SQL> SELECT * FROM T1 WHERE c = 'Test1'; 行号 ID C ---------- ----------- ----- 1 1 Test1 SELECT * FROM T1 WHERE c = 'TEST1'; -- 表名小写也不影响查询,但是查询条件的值如果是全小写和全小写的情况下,表 T1 则无法匹配表数据。说明数据存储及数据比较区分大小写。 SQL> SELECT * FROM t1 WHERE c = 'test1'; 未选定行 SQL> SELECT * FROM T1 WHERE c = 'TEST1'; 未选定行 -- 表 Tt6 查询报错,无效表名,是因为表 Tt6 没有指定双引号,在大小写敏感的数据库中,会被识别为表 TT6,而这张表确实不存在,所以表名需要加双引号 SQL> SELECT * FROM Tt6 WHERE c = 'test3'; SELECT * FROM Tt6 WHERE c = 'test3'; 第1 行附近出现错误[-2106]:无效的表或视图名[TT6]. -- 当表 Tt6 加上双引号之后,就可以成功查询数据 SQL> SELECT * FROM "Tt6" WHERE c = 'test3'; 行号 ID C ---------- ----------- ----- 1 1 test3
-
大小写不敏感
sql-- 表 T1 中存在符合 Test1 的数据,所以可以成功查询 SQL> SELECT * FROM T1 WHERE c = 'Test1'; 行号 ID C ---------- ----------- ----- 1 1 Test1 -- 即使 T1 表中不存在 test1 的数据,但是因为不区分大小写,所以可以匹配。说明数据存储本身仍是保持原有的大小写,但是比较的时候默认不区分。 SQL> SELECT * FROM T1 WHERE c = 'test1'; id c ----------- ----- 1 Test1 SQL> SELECT * FROM T1 WHERE c = 'TEST1'; 行号 id c ---------- ----------- ----- 1 1 Test1 -- 表 Tt6 查询成功,因为在大小写不敏感的数据库中,即使标识符被双引号括起来也不会使数据库区分大小写,所以默认都是小写 SELECT * FROM Tt6 WHERE c = 'test3'; 行号 id c ---------- ----------- ----- 1 1 test3
2.3 常用工具
2.3.1 使用 disql
需要注意的是:密码中含有"@"、"/"等特殊字符,此时需要通过转义符来处理,如下所示:
bash
# linux 环境:需要使用双引号将密码包含进来,外层再使用单引号进行转义
./disql SYSDBA/' "abcd@efgh" '@localhost
# windows环境:使用双引号将密码包含进来,同时对双引号使用"\"进行转义
disql SYSDBA/\"abcd@efgh\"@localhost
操作 | 大小写敏感数据库 | 大小写不敏感数据库 |
---|---|---|
创建大写表对象 | 不需要添加双引号来 | 不需要添加双引号来创建 |
创建小写表对象 | 需要添加双引号来 | 需要添加双引号来创建 |
查询大写表对象 | 不需要添加双引号查询 | 不需要添加双引号来查询 |
查询小写表对象 | 需要添加双引号查询 | 不需要添加双引号来查询 |
2.3.2 使用管理工具
操作 | 大小写敏感数据库 | 大小写不敏感数据库 |
---|---|---|
创建大写表对象 | 不需要双引号 | 不需要双引号 |
创建小写表对象 | 需要双引号 | 不需要双引号 |
查询大写表对象 | 不需要双引号 | 不需要双引号 |
查询小写表对象 | 需要双引号 | 不需要双引号 |
2.3.3 dts 迁移数据库
数据库类型 | 表对象 | 需要勾选"保持对象名大小写" | 后期查询方式 |
---|---|---|---|
大小写敏感数据库 | 小写 | 是 | 使用双引号查询 |
大小写敏感数据库 | 大写 | 否 | 不需要使用双引号查询(自动转换为大写) |
大小写不敏感数据库 | 小写 | 是 | 不需要使用双引号查询 |
大小写不敏感数据库 | 大写 | 否 | 不需要使用双引号查询(自动转换为大写) |
总结
经过以上测试,基本已经可以搞清楚大小写是否敏感对于数据库对象以及数据的影响。这里概括以下大小写敏感和不敏感数据库中的表和字段名的处理方式,如下表所示。
特性 | 大小写敏感的数据库 | 大小写不敏感的数据库 |
---|---|---|
表名/列名创建 | 不添加双引号时,自动转换为大写。 添加双引号时,保持指定的大小写形式。 | 无论是否添加双引号,大小写形式保持不变 |
同名字段 | 允许同名字段,大小写不同即视为不同字段。 | 不允许同名字段,即使大小写不同 |
DML/DDL 操作 | 不加双引号时,自动转换为大写。 加双引号时,保持指定的大小写形式。 | 无论加不加双引号,大小写形式保持不变 |
字段过滤 | 使用双引号指定大小写形式,否则不添加双引号 | 不区分大小写,查询时使用的大小写形式均可查询到预期结果 |
查询 | 单引号和双引号区分大小写,字符串形式严格按照大小写匹配 | 单引号和双引号不区分大小写,查询条件的大小写均可获得结果 |
同名数据库对象 | 同名对象(大小写不同)视为不同对象 | 不允许同名对象,即使大小写不同,默认只能存在一个 |