GaussDB常用的数据类型之数值类型
【摘要】 GaussDB的数据类型的使用是数据库开发者的基础,要根据业务场景合理的选择数值类型是本篇技术论文的要点。
1 问题现象
数据类型是一组值的集合以及定义在这个值集上的一组操作。GaussDB数据库是由表的集合组成的,而各表中的列定义了该表,每一列都属于一种数据类型,GaussDB根据数据类型有相应内置函数对其内容进行操作,例如GaussDB可对数值型数据进行加、减、乘、除操作等。
2 技术背景
数据类型是用来定义数据存储格式和数据范围的规范。每种数据类型都有自己的特点和适用范围,它们在数据库中的作用主要有以下几点:
存储数据:数据库中的每个字段都必须指定数据类型,这样才能确定它们在数据库中的存储格式。不同的数据类型使用不同的存储方式,例如整型会以二进制形式存储,而字符型则以ASCII码或Unicode编码形式存储。
约束数据范围:数据类型可以限制某个字段存储的数据范围,例如整型只能存储整数值,小数型只能存储浮点数等。这样可以确保数据的准确性和完整性,防止非法值进入数据库。
提高查询效率:数据库在查询数据时会根据字段的数据类型进行优化,例如对整型字段的查询会比对字符型字段的查询更快,因为整型字段的数据存储格式更简单,计算也更快。
降低存储空间:不同的数据类型使用不同的存储方式,一些数据类型可以在存储时减少存储空间的占用。例如使用整型可以减少存储空间的占用,因为整型在存储时只需要占用4个字节,而字符型则需要占用更多的存储空间。
提高数据安全性:数据类型可以帮助数据库对数据进行有效的过滤和验证,限制不合法的数据输入,增强数据的安全性和可靠性。
3 数值类型使用案例
3.1 整数类型
名称 |
描述 |
存储空间 |
范围 |
TINYINT |
微整数,别名为INT1 |
1字节 |
0 ~ 28 - 1 |
SMALLINT |
小范围整数,别名为INT2 |
2字节 |
-215 ~ 215 - 1 |
INTEGER |
常用的整数,别名为INT4 |
4字节 |
-231 ~ 231 - 1 |
BINARY_INTEGER |
常用的整数INTEGER的别名 |
4字节 |
-231 ~ 231 - 1 |
BIGINT |
大范围的整数,别名为INT8 |
8字节 |
-263 ~ 263 - 1 |
int16 |
十六字节的大范围整数,目前不支持用户用于建表等使用 |
16字节 |
-2127 ~ 2127 - 1 |
3.1.1 案例
gsql ((GaussDB Kernel 505.2.0 build 679b40b2) compiled at 2024-09-16 02:05:48 commit 9967 last mr 19883 release)
SSL connection (cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.
--创建具有TINYINT类型数据的表
gaussdb=> CREATE TABLE int_type_t1 (IT_COL1 TINYINT);
CREATE TABLE
--向创建的表中插入数据
gaussdb=> INSERT INTO int_type_t1 VALUES(10);
INSERT 0 1
--查看数据
gaussdb=> SELECT * FROM int_type_t1;
it_col1
---------
10
(1 row)
--删除表
gaussdb=> DROP TABLE int_type_t1;
DROP TABLE
--创建具有TINYINT,INTEGER,BIGINT类型数据的表
gaussdb=> CREATE TABLE int_type_t2 (a TINYINT, b TINYINT, c INTEGER, d BIGINT);
CREATE TABLE
--插入数据
gaussdb=> INSERT INTO int_type_t2 VALUES(100, 10, 1000, 10000);
INSERT 0 1
--查看数据
gaussdb=> SELECT * FROM int_type_t2;
a | b | c | d
-----+----+------+-------
100 | 10 | 1000 | 10000
(1 row)
--删除表
gaussdb=> DROP TABLE int_type_t2;
DROP TABLE
3.1.2 说明
I. TINYINT、SMALLINT、INTEGER、BIGINT和INT16类型存储各种范围的数字,也就是整数。如果存储超出范围以外的数值将会导致错误。
II. 常用的类型是INTEGER,因为它提供了在范围、存储空间、性能之间的最佳平衡。一般只有取值范围确定不超过SMALLINT的情况下,才会使用SMALLINT类型。而只有在INTEGER的范围不够的时候才使用BIGINT,因为INTEGER的处理速度相对快得多。
III. 如果指定UNSIGNED,将不允许使用负值。
IV. 无符号数值类型仅支持在sql_compatibility = 'B'时的行存储引擎中使用。
V. 当在整数值(其中一个是UNSIGNED类型)之间使用减号、加号、乘号时,结果是无符号。
VI. INT1/UINT1/UINT2/UINT4/UINT8的+、-、*运算允许返回值超过类型本身范围,INT2/INT4/INT8的+、-、*运算不允许返回值超过类型本身范围。
VII. UNSIGNED类型不支持与SET数据类型间的转换,避免对UNSIGNED类型与SET类型计算或比较。
VIII. 当sql_compatibility = 'B'时,非数值类型的字符输入,会自动截断或返回数值0。
3.1.3 注意事项
I. 当sql_compatibility = 'B'时,设置参数b_format_version = '5.7'和参数b_format_dev_version = 's1'后,整型支持显示宽度和指定ZEROFILL属性。
II. 显示宽度不限制可以存储在列中的值的范围,也不会阻止宽于列显示宽度的值正确显示。例如,指定为SMALLINT(3)的列可以存储-32768到32767的SMALLINT范围的值,并且使用三位以上的数字完整显示三位数所允许的范围之外的值。
III. 当显示宽度与ZEROFILL属性结合使用时,将在数值前填充零以达到显示宽度。例如,对于声明为INT(4) ZEROFILL的列,将检索5的值作为0005。
IV. 如果为数字列指定ZEROFILL,将自动添加UNSIGNED属性。
V. 如果不为数字列指定ZEROFILL,仅指明宽度信息,则宽度信息在表结构描述中不显示。
3.1.4 使用示例
--创建数据库。
gaussdb=# CREATE DATABASE b_database dbcompatibility = 'B';
gaussdb=# \c b_database
--创建具有TINYINT类型数据的表。
b_database=# CREATE TABLE int_type_t1
(
IT_COL1 TINYINT,
IT_COL2 TINYINT UNSIGNED
);
--向创建的表中插入数据。
b_database=# INSERT INTO int_type_t1 VALUES(10,20);
--查看数据。
b_database=# SELECT * FROM int_type_t1;
it_col1 | it_col2
--------+---------
10 | 20
(1 row)
--删除表。
b_database=# DROP TABLE int_type_t1;
DROP TABLE
3.2 任意精度类型
名称 |
描述 |
存储空间 |
范围 |
NUMERIC[(p[,s])], DECIMAL[(p[,s])] |
精度p取值范围为[1,1000],标度s取值范围为[0,p]。p为总位数,s为小数位数 |
用户声明精度。每四位(十进制位)占用两个字节,然后在整个数据上加上八个字节的额外开销 |
未指定精度的情况下,小数点前最大131,072位,小数点后最大16,383位 |
NUMBER[(p[,s])] |
NUMERIC类型的别名 |
用户声明精度。每四位(十进制位)占用两个字节,然后在整个数据上加上八个字节的额外开销。 |
未指定精度的情况下,小数点前最大131,072位,小数点后最大16,383位 |
3.2.1 使用示例
sql ((GaussDB Kernel 505.2.0 build 679b40b2) compiled at 2024-09-16 02:05:48 commit 9967 last mr 19883 release)
SSL connection (cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.
--创建表
gaussdb=> CREATE TABLE decimal_type_t1 (DT_COL1 DECIMAL(10,4));
CREATE TABLE
--插入数据
gaussdb=> INSERT INTO decimal_type_t1 VALUES(123456.122331);
INSERT 0 1
--查询表中的数据
gaussdb=> SELECT * FROM decimal_type_t1;
dt_col1
-------------
123456.1223
(1 row)
--删除表
gaussdb=> DROP TABLE decimal_type_t1;
DROP TABLE
--创建表
gaussdb=> CREATE TABLE numeric_type_t1 ( NT_COL1 NUMERIC(10,4));
CREATE TABLE
--插入数据
gaussdb=> INSERT INTO numeric_type_t1 VALUES(123456.12354);
INSERT 0 1
--查询表中的数据
gaussdb=> SELECT * FROM numeric_type_t1;
nt_col1
-------------
123456.1235
(1 row)
--删除表
gaussdb=> DROP TABLE numeric_type_t1;
DROP TABLE
3.2.2 说明
I. 与整数类型相比,任意精度类型需要更大的存储空间,其存储效率、运算效率以及压缩比效果都要差一些。在进行数值类型定义时,优先选择整数类型。当数值超出整数可表示最大范围时,再选用任意精度类型。
II. 使用NUMERIC/DECIMAL进行列定义时,建议指定该列的精度p以及标度s。
III. 当sql_compatibility = 'B'时,设置参数b_format_version = '5.7'和参数b_format_dev_version = 's1'后,NUMERIC[(p[,s])]、DECIMAL[(p[,s])]类型的输入输出范围规格有差异。
a) 输入格式:支持数字或数字字符串输入格式。
i. SQL_MODE参数值包含“strict_trans_tables”时,非法输入或者输入超过范围时,会报错error。
ii. SQL_MODE参数值不包含“strict_trans_tables”时,非法输入或者输入超过范围时,会报warning信息,并返回0值或截断后的值。
b) 输出格式:DECIMAL[(p[,s])]类型当没有指定精度和标度时与NUMERIC[(p[,s])]没有指定精度和标度时的部分输出格式存在差异。如NUMERIC无精度和标度时在类型转换时会保留小数部分,参照未设置参数的场景的输出格式,DECIMAL无精度和标度时在类型转换时则会按照精度为10,标度为0转换。
3.3 序列整型
名称 |
描述 |
存储空间 |
范围 |
SMALLSERIAL |
二字节序列整型 |
2字节 |
-215 ~ 215 - 1 |
SERIAL |
四字节序列整型 |
4字节 |
-231 ~ 231 - 1 |
BIGSERIAL |
八字节序列整型 |
8字节 |
-263 ~ 263 - 1 |
LARGESERIAL |
默认插入十六字节序列整型,实际数值类型和NUMERIC相同 |
变长类型,每四位(十进制位)占用两个字节,然后在整个数据上加上八个字节的额外开销 |
小数点前最大131072位,小数点后最大16383位 |
3.3.1 使用示例
gsql ((GaussDB Kernel 505.2.0 build 679b40b2) compiled at 2024-09-16 02:05:48 commit 9967 last mr 19883 release)
SSL connection (cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.
--创建表
gaussdb=> CREATE TABLE smallserial_type_tab(a SMALLSERIAL);
NOTICE: CREATE TABLE will create implicit sequence "smallserial_type_tab_a_seq" for serial column "smallserial_type_tab.a"
CREATE TABLE
--插入数据
gaussdb=> INSERT INTO smallserial_type_tab VALUES(default);
INSERT 0 1
--再次插入数据
gaussdb=> INSERT INTO smallserial_type_tab VALUES(default);
INSERT 0 1
--查看数据
gaussdb=> SELECT * FROM smallserial_type_tab;
a
---
1
2
(2 rows)
--创建表
gaussdb=> CREATE TABLE serial_type_tab(b SERIAL);
NOTICE: CREATE TABLE will create implicit sequence "serial_type_tab_b_seq" for serial column "serial_type_tab.b"
CREATE TABLE
--插入数据
gaussdb=> INSERT INTO serial_type_tab VALUES(default);
INSERT 0 1
--再次插入数据
gaussdb=> INSERT INTO serial_type_tab VALUES(default);
INSERT 0 1
--查看数据
gaussdb=> SELECT * FROM serial_type_tab;
b
---
1
2
(2 rows)
--创建表
gaussdb=> CREATE TABLE bigserial_type_tab(c BIGSERIAL);
NOTICE: CREATE TABLE will create implicit sequence "bigserial_type_tab_c_seq" for serial column "bigserial_type_tab.c"
CREATE TABLE
--插入数据
gaussdb=> INSERT INTO bigserial_type_tab VALUES(default);
INSERT 0 1
--再次插入数据
gaussdb=> INSERT INTO bigserial_type_tab VALUES(default);
INSERT 0 1
--查看数据
gaussdb=> SELECT * FROM bigserial_type_tab;
c
---
1
2
(2 rows)
--创建表
gaussdb=> CREATE TABLE largeserial_type_tab(c LARGESERIAL);
NOTICE: CREATE TABLE will create implicit sequence "largeserial_type_tab_c_seq" for serial column "largeserial_type_tab.c"
CREATE TABLE
--插入数据
gaussdb=> INSERT INTO largeserial_type_tab VALUES(default);
INSERT 0 1
--再次插入数据
gaussdb=> INSERT INTO largeserial_type_tab VALUES(default);
INSERT 0 1
--查看数据
gaussdb=> SELECT * FROM largeserial_type_tab;
c
---
1
2
(2 rows)
--删除表
gaussdb=> DROP TABLE smallserial_type_tab;
DROP TABLE
gaussdb=> DROP TABLE serial_type_tab;
DROP TABLE
gaussdb=> DROP TABLE bigserial_type_tab;
DROP TABLE
gaussdb=> DROP TABLE largeserial_type_tab;
DROP TABLE
3.3.2 说明
SMALLSERIAL、SERIAL、BIGSERIAL和LARGESERIAL类型不是真正的类型,只是为在表中设置唯一标识做的概念上的便利。因此,创建一个整数字段,并且把它的缺省数值安排为从一个序列发生器读取。应用了一个NOT NULL约束以确保NULL不会被插入。在大多数情况下用户可能还希望附加一个UNIQUE或PRIMARY KEY约束避免意外地插入重复的数值,但这个不是自动的。最后,序列发生器将从属于该字段,这样当该字段或表被删除的时候也一并删除它。目前支持在创建表时候指定SERIAL列,也支持在PG兼容模式下的普通表增加SERIAL列。另外临时表也不支持创建SERIAL列。因为SERIAL不是真正的类型,所以也不可以将表中存在的列类型转化为SERIAL。
3.4 浮点类型
名称 |
描述 |
存储空间 |
范围 |
SMALLSERIAL |
二字节序列整型 |
2字节 |
-215 ~ 215 - 1 |
SERIAL |
四字节序列整型 |
4字节 |
-231 ~ 231 - 1 |
BIGSERIAL |
八字节序列整型 |
8字节 |
-263 ~ 263 - 1 |
LARGESERIAL |
默认插入十六字节序列整型,实际数值类型和NUMERIC相同 |
变长类型,每四位(十进制位)占用两个字节,然后在整个数据上加上八个字节的额外开销 |
小数点前最大131072位,小数点后最大16383位 |
3.4.1 类型说明
I. 二进制浮点数据类型REAL、FLOAT4、DOUBLE、DOUBLE PRECISION、FLOAT8、FLOAT[(p)]和BINARY_DOUBLE为不精确的数值类型,其内部存储为近似值,因此存储和检索时可能会显示轻微的差异。当用户在使用二进制浮点数据类型时需要注意以下几点:
a) 精确存储和计算:如果需要精确存储和计算(例如货币金额),请改用精确的数据类型(例如numeric)。
b) 复杂计算:若使用不精确的数据类型执行复杂计算以获得重要数据,需要仔细评估其结果。
c) 浮点数比较:比较两个浮点数是否相等的结果可能与预期存在差异。
d) 下溢错误:如果一个浮点数过于接近零,反而无法准确表示,会导致下溢错误。
II. 浮点类型表中描述的p为精度,表示整数位最低可以接受的总位数;s为小数位位数。
III. 当sql_compatibility = 'B'时,设置参数b_format_version = '5.7'和参数b_format_dev_version = 's1'后,FLOAT[(p[,s])]、DOUBLE[(p[,s])]、DEC[(p[,s])]和REAL[(p[,s])]类型的输入输出范围规格有差异。
a) 输入格式:支持数字或数字字符串输入格式。
i. SQL_MODE参数值包含“strict_trans_tables”时,非法输入或者输入超过范围时,会报error。
ii. SQL_MODE参数值不包含“strict_trans_tables”时,非法输入或者输入超过范围时,会报warning信息,并返回0值或截断后的值。
b) 输出格式:DEC[(p[,s])]类型当没有指定精度和标度时与其映射的NUMERIC[(p[,s])]类型在没有指定精度和标度时的部分输出格式场景存在差异。如NUMERIC无精度和标度时在类型转换时会保留小数部分,参照未设置参数的场景的输出格式,DEC无精度和标度时在类型转换时则会按照精度为10,标度为0转换。
3.4.2 使用示例
gsql ((GaussDB Kernel 505.2.0 build 679b40b2) compiled at 2024-09-16 02:05:48 commit 9967 last mr 19883 release)
SSL connection (cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.
--创建表
gaussdb=> CREATE TABLE float_type_t2 (FT_COL1 INTEGER, FT_COL2 FLOAT4, FT_COL3 FLOAT8, FT_COL4 FLOAT(3), FT_COL5 BINARY_DOUBLE, FT_COL6 DECIMAL(10,4), FT_COL7 INTEGER(6,3));
CREATE TABLE
--插入数据
gaussdb=> INSERT INTO float_type_t2 VALUES(10,10.365456,123456.1234,10.3214, 321.321, 123.123654, 123.123654);
INSERT 0 1
--查看数据
gaussdb=> SELECT * FROM float_type_t2 ;
ft_col1 | ft_col2 | ft_col3 | ft_col4 | ft_col5 | ft_col6 | ft_col7
---------+------------+---------------------+------------+---------------------+----------+---------
10 | 10.3654556 | 123456.123399999997 | 10.3213997 | 321.321000000000026 | 123.1237 | 123.124
(1 row)
--删除表
gaussdb=> DROP TABLE float_type_t2;
DROP TABLE
4 简单总结
数值类型是GaussDB数据库数据类型中的一种,数据库开发人员在设计数据库时必须充分了解各数值类型的特点和使用场景,合理选用数值类型,才能保证数据库的高效性和稳定性。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
Jack202025/02/25 03:37:491楼编辑删除举报
yd_2624823612025/02/25 13:20:102楼编辑删除举报