注册
达梦数据库初始化参数的总结及思考
技术分享/ 文章详情 /

达梦数据库初始化参数的总结及思考

纯手工老虎 2024/06/27 1392 1 0

1、初始化参数的含义

初始化参数,顾名思义,就是初始化达梦数据库的时候,配置的初始化参数,也即是我们常说的dminit参数。dminit参数非常丰富,可选加必选参数合计有50多个,能满足各种情况下的需求,并且随着版本不断的变化。具体可参考《DM8 dminit使用手册》的dminit参数详解一节。

2、需特别关注的初始化参数

大部分初始化参数实际上无需特别关注,无特殊要求下,使用默认值即可,但也有几个参数需要额外关注,主要是几个初始化配置后,在整个数据库生命周期内都无法修改的参数值。相信有达梦数据库安装实践经验的人都会知道,在测试过程中,发现由于初始化参数配置的不对,需要重新迁移数据,重新初始化数据库有多么痛苦。

在dminit的参数中,以下几个参数均是需要特别关注,且一经设定就无法再次更改的:

2.1 LENGTH_IN_CHAR

LENGTH_IN_CHAR

VARCHAR类型长度是否以字符为单位,默认为否(否即以字节为单位)

LENGTH_IN_CHAR是一个主要作用于varchar类型(即可变长类型)数据的参数,以存储汉字为例,当字符集为默认的gb18030时,若以若以字节为单位,则varchar(3)能存下2个汉字。字符集为uft8时,以字节为单位,varchar(3)只能保存一个汉字。而当该参数设置为1时,实际上varchar的精度会进行拓展,在默认字符集下会变为定义长度的2倍,uft8情况下会变为定位长度的4倍。

举例,当length_in_char=0时,尝试往varchar(3)字段写入汉字

create table t (name varchar2(3)); insert into t values('一') insert into t values('一二')

image.png

length_in_char=1时,尝试往varchar(3)字段写入汉字

create table t (name varchar2(3)); insert into t values('一'); insert into t values('一二'); insert into t values('一二三'); insert into t values('一二三四');

image.png

可以看到在length_in_char=1的情况下,最多可以写入三个汉字。查询该表就能看到,实际上该字段精度是放大了两倍。

image.png

注意!!

24年q2版本之后,该参数已经废弃,所有数据库均按照默认以字节为单位进行初始化。若由mysql迁移过来,需要将varchar映射为nvarchar,从字段粒度实现以字符为单位。

2.2 CHARSET

CHARSET

字符集选项。0 代表 GB18030;1 代表UTF-8;2 代表韩文字符集 EUC-KR

CHARSET=0代表使用GB18030,即一个中文两个字节。CHARSET=1代表使用UTF-8,即一个中文3个字节。

CHARSET参数即前文介绍LENGTH_IN_CHAR参数中提到的字符集选项,根据描述我们看出,不同的字符集配置情况下,汉字所占的字节数是不同的,因此CHARSET参数与LENGTH_IN_CHAR参数存在很强的关联性,两种参数的不同组合情况,决定了varchar字段具体能够存储的数据长度,特别是在涉及汉字的情况下,因此在实际的生产过程中,涉及初始化参数配置时,应当考虑两个参数的组合影响。具体不同组合的情况如下:

在使用GB18030作为字符集类型,且LENGTH_IN_CHAR为0时,只存储了4个中文字符,没有进行自动扩充。LENGTH_IN_CHAR为1时,实际最大存储长度为16,是长度定义的2倍;
在使用UTF-8作为字符集类型,且LENGTH_IN_CHAR为0时,只存储了两个中文字符加两个英文字符。LENGTH_IN_CHAR=1,实际最大存储长度为32,为定义长度的4倍。

2.3 CASE_SENSITIVE

CASE_SENSITIVE

大小写是否敏感。Y、y、1 表示敏感,N、n、0 表示不敏感,缺省值为 Y。当大小写敏感时,小写的标识符应用双引号括起,否则被转换为大写;当大小写不敏感时,系统不自动转换标识符的大小写,系统比较函数会将大写字母全部转为小写字母再进行比较

大小写敏感,是几个不可修改的初始化参数中,配置错误对数据库使用影响最明显的一个,若配置失误,可能导致程序许多查询语句均失效,且该参数并不太易理解,实际上该参数可以理解为字符串大小写比较敏感,主要是针对数据库中的字符值比较时,是否忽略大小写的差异。许多人会误以为大小写敏感是针对表对象名称的配置,实际上他更多是针对内容的配置。

对内容的影响举例如下:

CREATE TABLE TEST_CASE_SENSITIVE(C1 VARCHAR(100)); INSERT INTO TEST_CASE_SENSITIVE VALUES('a'); INSERT INTO TEST_CASE_SENSITIVE VALUES('A'); COMMIT; --大小写敏感的情况 SELECT COUNT(*) FROM TEST_CASE_SENSITIVE WHERE C1='a'; --结果为1 SELECT COUNT(*) FROM TEST_CASE_SENSITIVE WHERE C1='A'; --结果为1 --大小写不敏感的情况 SELECT COUNT(*) FROM TEST_CASE_SENSITIVE WHERE C1='a'; --结果为2 SELECT COUNT(*) FROM TEST_CASE_SENSITIVE WHERE C1='A'; --结果为2

可以看出,在大小写不敏感的情况下,‘a’和’A’是等价的,无论大小写,对数据库而言都是相同的内容。而大小写敏感的情况下,‘a’和’A’是不相等的,他们视为不同的内容。因此在实际的生产过程中,需要严格确定大小写敏感内容的配置,否则可能会导致返回的结果集不符合预期,或是在写入数据过程后触发违反一致性约束。

而对于对象的比较,实际上并没有那么严格,具体如下

--case_sensitive = 1 CREATE TABLE a(C1 INT); SELECT * FROM a; --执行成功 SELECT * FROM A; --执行成功 SELECT * FROM "A"; --执行成功 SELECT * FROM "a"; --执行失败:无效的表或视图名[A] CREATE TABLE "b"(C1 INT); SELECT * FROM b; --执行失败:无效的表或视图名[B] SELECT * FROM B; --执行失败:无效的表或视图名[B] SELECT * FROM "b"; --执行成功 SELECT * FROM "B"; --执行失败:无效的表或视图名[B] --case_sensitive = 0 CREATE TABLE a(C1 INT); SELECT * FROM a; --执行成功 SELECT * FROM A; --执行成功 SELECT * FROM "a"; --执行成功 SELECT * FROM "A"; --执行成功 CREATE TABLE "b"(C1 INT); SELECT * FROM b; --执行成功 SELECT * FROM B; --执行成功 SELECT * FROM "b"; --执行成功 SELECT * FROM "B"; --执行成功

可以看出,在大小写敏感的情况下,主要影响对象名称的在于创建及查询时是否加了双引号,在不加双引号的情况下,实际上数据库会自动将字符转为大写入库。而加双引号,即相当于显式的指定大小写,在后续涉及该对象的查询中,则都得带上双引号,增加了多余的操作,因此在大小写敏感的库中,除非有特殊要求,否则对于对象名还是统一大写来的方便。

2.4 BLANK_PAD_MODE

BLANK_PAD_MODE

设置字符串比较时,结尾空格填充模式,是否兼容 ORACLE,取值 0 或 1。0不兼容,1 兼容。缺省为 0

该参数也是一个与字符串比较相关的参数,其内容比较简单,从介绍中也可以看出,其主要的目的是为了兼容oracle,在oracle中,‘a’和’a ‘(注意此处多一个空格)是不同的字符,与大小写敏感参数相同,作为一个字符串比较相关的参数,该参数主要影响的还是判断逻辑不同导致结果集返回不同,以及一致性约束的影响。

3.参数配置推荐

在实际的生产过程中,对于初始化参数的配置,需要结合实际情况来判断,下面列举一些根据过往实践经验,总结在不同场景下较为建议的参数配置组合

3.1 由oracle迁移而来

推荐配置

BLANK_PAD_MODE=1,CASE_SENSITIVE=1 --其余视实际情况

在源库是由oracle迁移而来时,为确保对于oracle的兼容性,建议是按照上述配置进行初始化。首先空格填充=1本身即是为了兼容oracle的参数,其次oracle默认为大小写敏感,采用这种参数组合,能够避免前文所述的,对于字符串比较判断逻辑不一致带来的问题。

举例:某项目迁移oracle至dm8,迁移过程中多张表报违反唯一性约束,导致迁移失败,即使将目标表全数清空,再次写入过程中仍会报违反唯一性约束。主要原因则在于上述参数配置有误,在oracle中视为不一致的数值,在错误配置的达梦库中视为一致,便触发违反唯一性约束。

3.2 由mysql迁移而来

推荐配置

BLANK_PAD_MODE=0,CASE_SENSITIVE=0 --其余视实际情况

mysql与oracle不同,‘a’与‘a ‘均视为相同的内容,因此我们无需修改该配置。在实际生产环境中,多是运行中unix环境下,而mysql在unix环境下,默认对于对象大小写敏感(lower_case_table_name=0),但对于字段值不敏感(默认建表编码为UTF8_GENERAL_CI)。而达梦大小写敏感参数的设置主要是针对字段值,因此建议采用大小写不敏感,与mysql默认的表现保持一致。但同时需注意,mysql对于大小写敏感的处理更加灵活,可以设置单表、单字段是否大小写敏感,查询时是否大小写敏感,因此还需要根据实际情况进行额外的适配和改造。

4、总结

初始化参数作为数据库安装时,关键性且最为底层,影响广泛的参数,需要运维人员对其具有足够的了解。在真正的生产过程中,也需要充分的确定好需求,依据实际情况及生产需要,审慎的确定初始化参数的选择,避免因配置失误造成额外的工作成本(重新安装数据库、重新迁移数据、系统运行结果不符合预期等)

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服