TDengine表字段类型之VARCHAR和NCHAR

对于数据库字段类型的长度是看似简单的问题。但是却经常困扰着使用者。今天我用实践来验证为啥数据类型的长度要这样写。

一、官方字段类型使用说明

数据类型TDengine的说明
VARCHAR存储可变长度的单字节字符串,只用于处理 ASCII 可见字符。VARCHAR 是 BINARY 的别称。
NCHAR存储可变长度的多字节字符串,如中文字符。等同于 MySQL 的 CHAR 和默认字符集(utf8)的 VARCHAR。

大白话就是:VARCHAR可以用来存储例如英文字母等一个字符只占用1个字节的字符串。并且还做了限制,只能存储ASCII 可见字符
NCHAR可以用来存储例如汉字这样一个字符就占用2个字节的字符串。

思考:那么能不能给VARCHAR存储汉字,给NCHAR存储英文字母呢?
答案是:可以的。
但是,长度该是多少呢?下面我们用实践来证明:

二、字符串类型长度与存储内容的对照关系

1)给VARCHAR存储汉字
create stable testvarchar(ts TIMESTAMP, id bigint, name varchar(110)) Tags(class smallint);

insert into testvarcha01 values('2023-08-17 09:40:40', 1001, '按照上面的建表语句');
-- Query OK, 1 of 1 rows affected (0.026000s)
-- 9个汉字入库成功。

insert into testvarcha01 values('2023-08-17 09:40:43', 1003, '按照上面的建表语句存储多个语句总共需要多少字节呢按照上面的建表语句存储多个语句总共需要多少字节呢哈哈');
-- DB error: Value too long for column/tag: name (0.016000s)
-- 50个汉字。长度过程,存储失败。于是我们减少字符长度,再测试

insert into testvarcha01 values('2023-08-17 09:41:53', 1006, '按照上面的建表语句存储多个语句总共需要多少字节呢按照上面的建表语句到底是几');
-- Query OK, 1 of 1 rows affected (0.013000s)
-- 【直到减少到36个汉字时,入库成功!】

-- 查看数据
taos> select * from testvarchar;
           ts            |          id           |              name              | class  |
============================================================================================
 2023-08-17 09:40:40.000 |                  1002 | 按照上面的建表语句             |      1 |
 2023-08-17 09:40:41.000 |                  1002 | 按照上面的建表语句存储多个...  |      1 |
 2023-08-17 09:40:43.000 |                  1003 | 按照上面的建表语句存储多个...  |      1 |

-- 再看看存入英文字母的情况:
insert into testvarcha01 values('2023-08-17 09:45:40', 1005, 'abcdefgaaadddsssdffffadfsdfsdfsfdfabcdefgaaadddsssdffffadfsdfsdfsfdfabcdefgaaadddsssdffffadfsdfsdfsfdfolpmjkiu1');
-- DB error: Value too long for column/tag: name (0.052000s)
-- 111个英文字母,未能入库成功。继续测试:

insert into testvarcha01 values('2023-08-17 09:45:40', 1005, 'abcdefgaaadddsssdffffadfsdfsdfsfdfabcdefgaaadddsssdffffadfsdfsdfsfdfabcdefgaaadddsssdffffadfsdfsdfsfdfolpmjkiu');
-- Query OK, 1 of 1 rows affected (0.009000s)
-- 【110个字母,存储成功!!】

VARCHAR(110)存入110个英文字母,我们可以理解。因为英文字母一个字符代表一个字节,110个字母刚好存入。
思考:那为啥只能存入36个汉字呢?
汉字不同的编码方式占用的字节数如下:

编码1个英文字符1个中文字符
ASCII码1字节2个字节
UTF-8编码1字节3个字节
Unicode编码2字节2个字节
GB2312中文编码-2个字节
GBK编码-2个字节

可以看出如果是UTF-8编码,汉字是占3个字节的。 3 * 36 = 108个字节。接近110个字节的设定了。
思考:那我的Taos数据库是UTF-8编码吗?
立即查看taos.cfg文件,赫然显示默认编码是UTF-8:

# default system charset
# charset                   UTF-8

疑惑:那还差2个字节,去哪儿了?
TDengine数据类型章节说明了。
在这里插入图片描述
是不是因为这个原因呢?
存储英文字母时,却没有额外占用。或者说这里的额外占用并不包含在数据类型设定的长度内。
知道的小伙伴可以@我。谢谢。
我又尝试将这36个汉字转成ANSI编码,刚好是55个字符:
在这里插入图片描述
不知道TDegine是不是用ANSI编码了。

虽然上面我们验证了VARCHAR存储汉字的长度和存储。但是官方还是建议不要存储汉字:
官方说:
在这里插入图片描述

2)给NCAHR存储英文字母

上面我们验证了VARCHAR存储汉字,下面我们验证NCAHR存储汉字和英文字母的情况:

-- 我们新增一列name2,长度设置10
alter stable testvarchar add column name2 nchar(10);
-- Query OK, 0 of 0 rows affected (0.011000s)

insert into testvarcha01 values('2023-08-17 09:42:53', 1008, 'abc110个', '这里只能存储十个汉字吗');
-- DB error: Value too long for column/tag: name2 (0.048000s) 
-- 插入11个汉字,果然超长了!

insert into testvarcha01 values('2023-08-17 09:42:53', 1008, 'abc110个', '这里只能存储十个汉字');
-- Query OK, 1 of 1 rows affected (0.021000s)
-- 10个汉字成功了!

-- 查看数据
select * from testvarchar;

 ts            |          id           |              name              |             name2              | class  |
=============================================================================================================================
2023-08-17 09:42:53.000 |         1008 | abc110个                       | 这里只能存储十个汉字              |      1 |

-- 再测试插入因为的情况
insert into testvarcha01 values('2023-08-17 09:43:53', 1009, 'abc110个', 'cansavesomewordorany');
-- DB error: Value too long for column/tag: name2 (0.027000s)

taos> insert into testvarcha01 values('2023-08-17 09:43:53', 1009, 'abc110个', 'cansavesomewordoran');
-- DB error: Value too long for column/tag: name2 (0.047000s)

taos> insert into testvarcha01 values('2023-08-17 09:43:53', 1009, 'abc110个', 'cansavesomewordo');
-- DB error: Value too long for column/tag: name2 (0.013000s)

taos> insert into testvarcha01 values('2023-08-17 09:43:53', 1009, 'abc110个', 'cansavesomewor');
-- DB error: Value too long for column/tag: name2 (0.023000s)

taos> insert into testvarcha01 values('2023-08-17 09:43:53', 1009, 'abc110个', 'cansavesomewo');
-- DB error: Value too long for column/tag: name2 (0.025000s)

taos> insert into testvarcha01 values('2023-08-17 09:43:53', 1009, 'abc110个', 'cansavesomew');
-- DB error: Value too long for column/tag: name2 (0.013000s)

taos> insert into testvarcha01 values('2023-08-17 09:43:53', 1009, 'abc110个', 'cansavesome');
-- DB error: Value too long for column/tag: name2 (0.029000s)

taos> insert into testvarcha01 values('2023-08-17 09:43:53', 1009, 'abc110个', 'cansavesom');
-- Query OK, 1 of 1 rows affected (0.051000s)
-- 【从20个字母,一直尝试到10个字母,才成功入库!!!】
-- // 理想很丰满,显示很骨干!

经过一番测试。我们发现NCAHR简直就是个“老死板”,说好的10个,哪管你是汉字还是英文字母,就只能插入10个字符。爱咋咋地吧🤣

官方数据类型说明是:
在这里插入图片描述
看起来这个多字节字符也包含单字节字符。😥

三、小结

数据类型建议存储不建议存储
VARCHAR单字符字符串,如英文字母。汉字字符串
NCHAR多字符字符串,如汉字。英文字符串

用什么数据库都可以。但是我们一定要遵守相关规范。合理的利用数据类型,这样才能达到最佳效果呀。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值