TDengine 字符串函数 CHAR_LENGTH 用户手册

CHAR_LENGTH 函数
语法
CHAR_LENGTH(expr)
功能说明
返回字符串的字符数量(字符长度)。与 LENGTH 函数不同,CHAR_LENGTH 以字符为单位计数,而不是字节。对于多字节字符(如中文),CHAR_LENGTH 将每个字符计为 1,而 LENGTH 会计算其实际字节数。
版本
v3.0.0.0
返回结果类型
BIGINT
适用数据类型
VARCHAR、NCHAR
嵌套子查询支持
适用于内层查询和外层查询。
适用于
表和超级表。
使用说明
- 如果
expr为 NULL,返回 NULL。 - 如果
expr为空字符串,返回 0。 - 对于 ASCII 字符,CHAR_LENGTH 与 LENGTH 返回值相同。
- 对于多字节字符(如中文、日文等),CHAR_LENGTH 返回字符数,LENGTH 返回字节数。
- 该函数是多字节安全的,能正确处理 UTF-8 编码的字符串。
示例所用表与数据(可直接复制执行)
-- 建库与使用
CREATE DATABASE IF NOT EXISTS power;
USE power;-- 智能电表表结构
CREATE STABLE meters (ts TIMESTAMP,current FLOAT,voltage INT,phase FLOAT,power DOUBLE,device_name VARCHAR(128),error_msg NCHAR(256),location_desc VARCHAR(256)
) TAGS (groupid INT,location VARCHAR(64)
);-- 子表
CREATE TABLE d1001 USING meters TAGS (1, 'California.SanFrancisco');
CREATE TABLE d1002 USING meters TAGS (2, 'California.LosAngeles');-- 写入数据
INSERT INTO d1001 VALUES('2024-01-01 00:00:00.000', 10.3, 220, 30.0, 2266.0, 'Meter-SF-01', '正常运行', 'San Francisco Bay Area'),('2024-01-01 00:15:00.000', 12.6, 221, 32.0, 2784.6, 'Meter-SF-01', '电压偏高,请检查', 'San Francisco Bay Area'),('2024-01-01 00:30:00.000', 11.5, 222, 31.0, 2553.0, 'Meter-SF-01', 'Warning: High current detected', 'San Francisco Bay Area');INSERT INTO d1002 VALUES('2024-01-01 00:00:00.000', 9.0, 219, 28.0, 1971.0, 'Device-LA-001', 'OK', 'Los Angeles Downtown'),('2024-01-01 00:15:00.000', 14.5, 218, 40.0, 3161.0, 'Device-LA-001', '设备过载告警', 'Los Angeles Downtown'),('2024-01-01 00:30:00.000', 8.2, 220, 25.0, 1804.0, 'Device-LA-002', 'Error: Connection timeout', 'Los Angeles Suburb');
基础示例
示例 1: NULL 和空字符串处理
-- NULL 值
taos> SELECT CHAR_LENGTH(NULL);char_length(null) |
====================NULL |-- 空字符串
taos> SELECT CHAR_LENGTH('');char_length('') |
==================0 |
示例 2: 英文字符串
-- 纯英文字符
taos> SELECT CHAR_LENGTH('Hello World');char_length('Hello World') |
=============================11 |-- 包含空格和标点
taos> SELECT CHAR_LENGTH('TDengine 3.0!');char_length('TDengine 3.0!') |
================================13 |
示例 3: 中文字符串
-- 纯中文
taos> SELECT CHAR_LENGTH('你好世界');char_length('你好世界') |
=========================4 |-- 中英文混合
taos> SELECT CHAR_LENGTH('TDengine数据库');char_length('TDengine数据库') |
================================11 |
示例 4: CHAR_LENGTH 与 LENGTH 对比
-- 英文字符:字符数等于字节数
taos> SELECT CHAR_LENGTH('Hello'), LENGTH('Hello');char_length('Hello') | length('Hello') |
================================================5 | 5 |-- 中文字符:字符数小于字节数
taos> SELECT CHAR_LENGTH('你好'), LENGTH('你好');char_length('你好') | length('你好') |
==============================================2 | 6 |-- 混合字符
taos> SELECT CHAR_LENGTH('Hello世界'), LENGTH('Hello世界');char_length('Hello世界') | length('Hello世界') |
======================================================7 | 11 |
示例 5: 列数据字符长度计算
-- 计算设备名称的字符长度
SELECT ts,device_name,CHAR_LENGTH(device_name) AS name_length
FROM d1001
ORDER BY ts;
ts | device_name | name_length |
===========================================================2024-01-01 00:00:00.000 | Meter-SF-01 | 11 |2024-01-01 00:15:00.000 | Meter-SF-01 | 11 |2024-01-01 00:30:00.000 | Meter-SF-01 | 11 |
智能电表场景示例
示例 6: 错误消息长度统计
目的:统计不同长度范围的错误消息数量,便于分析消息复杂度。
-- 按消息字符长度分组统计
SELECT CASEWHEN CHAR_LENGTH(error_msg) <= 10 THEN '短消息(≤10)'WHEN CHAR_LENGTH(error_msg) <= 30 THEN '中等消息(11-30)'WHEN CHAR_LENGTH(error_msg) <= 50 THEN '长消息(31-50)'ELSE '超长消息(>50)'END AS msg_category,COUNT(*) AS msg_count
FROM meters
WHERE error_msg != ''
GROUP BY CASEWHEN CHAR_LENGTH(error_msg) <= 10 THEN '短消息(≤10)'WHEN CHAR_LENGTH(error_msg) <= 30 THEN '中等消息(11-30)'WHEN CHAR_LENGTH(error_msg) <= 50 THEN '长消息(31-50)'ELSE '超长消息(>50)'END
ORDER BY msg_count DESC;
应用价值:
- 了解错误消息的复杂度分布
- 优化消息存储策略
- 改进日志记录规范
示例 7: 设备命名规范检查
目的:检查设备名称是否符合命名长度规范。
-- 检查设备名称长度是否在合理范围内
SELECT device_name,CHAR_LENGTH(device_name) AS name_length,CASEWHEN CHAR_LENGTH(device_name) < 5 THEN '名称过短'WHEN CHAR_LENGTH(device_name) > 32 THEN '名称过长'ELSE '符合规范'END AS validation_status
FROM meters
GROUP BY device_name
HAVING validation_status != '符合规范';
应用价值:
- 验证命名规范
- 识别异常设备标识
- 保证数据质量
示例 8: 多语言消息长度对比
目的:对比中英文错误消息的字符长度差异。
-- 分析不同语言消息的长度特征
SELECT error_msg,CHAR_LENGTH(error_msg) AS char_len,LENGTH(error_msg) AS byte_len,LENGTH(error_msg) - CHAR_LENGTH(error_msg) AS extra_bytes,CASEWHEN LENGTH(error_msg) = CHAR_LENGTH(error_msg) THEN '纯英文'WHEN LENGTH(error_msg) > CHAR_LENGTH(error_msg) * 2 THEN '多字节为主'ELSE '混合文本'END AS text_type
FROM meters
WHERE error_msg != ''
ORDER BY extra_bytes DESC
LIMIT 10;
应用价值:
- 了解消息的语言特征
- 优化存储空间分配
- 改进国际化设计
示例 9: 位置描述优化
目的:识别过长或过短的位置描述,优化数据录入。
-- 检查位置描述的合理性
SELECT location_desc,CHAR_LENGTH(location_desc) AS desc_length,CASEWHEN CHAR_LENGTH(location_desc) < 10 THEN '描述不够详细'WHEN CHAR_LENGTH(location_desc) > 50 THEN '描述过于冗长'ELSE '描述长度适中'END AS quality_check
FROM meters
GROUP BY location_desc
ORDER BY desc_length;
应用价值:
- 提高位置信息质量
- 标准化数据录入
- 便于数据检索
示例 10: 字段长度统计分析
目的:全面分析各字符串字段的长度分布。
-- 统计各字段的字符长度特征
SELECT 'device_name' AS field_name,AVG(CHAR_LENGTH(device_name)) AS avg_length,MIN(CHAR_LENGTH(device_name)) AS min_length,MAX(CHAR_LENGTH(device_name)) AS max_length
FROM meters
WHERE device_name IS NOT NULL
UNION ALL
SELECT 'error_msg' AS field_name,AVG(CHAR_LENGTH(error_msg)) AS avg_length,MIN(CHAR_LENGTH(error_msg)) AS min_length,MAX(CHAR_LENGTH(error_msg)) AS max_length
FROM meters
WHERE error_msg IS NOT NULL AND error_msg != ''
UNION ALL
SELECT 'location_desc' AS field_name,AVG(CHAR_LENGTH(location_desc)) AS avg_length,MIN(CHAR_LENGTH(location_desc)) AS min_length,MAX(CHAR_LENGTH(location_desc)) AS max_length
FROM meters
WHERE location_desc IS NOT NULL
ORDER BY field_name;
应用价值:
- 了解字段使用情况
- 优化字段定义
- 指导存储规划
示例 11: 消息截断检测
目的:检测可能被截断的错误消息。
-- 检测接近最大长度的消息(可能被截断)
SELECT ts,device_name,error_msg,CHAR_LENGTH(error_msg) AS msg_length,256 - CHAR_LENGTH(error_msg) AS remaining_space
FROM meters
WHERE CHAR_LENGTH(error_msg) > 240
ORDER BY msg_length DESC;
应用价值:
- 识别消息截断问题
- 调整字段长度限制
- 避免信息丢失
示例 12: 文本压缩率评估
目的:评估不同文本内容的存储效率。
-- 计算文本的平均字节/字符比率
SELECT device_name,AVG(LENGTH(error_msg) * 1.0 / NULLIF(CHAR_LENGTH(error_msg), 0)) AS avg_bytes_per_char,COUNT(*) AS sample_count
FROM meters
WHERE error_msg IS NOT NULL AND error_msg != ''AND CHAR_LENGTH(error_msg) > 0
GROUP BY device_name
ORDER BY avg_bytes_per_char DESC;
应用价值:
- 评估存储效率
- 识别压缩机会
- 优化数据结构
生产场景应用
场景 A: 数据质量监控系统
目的:建立基于字符长度的数据质量监控体系。
应用示例:
-- 生成数据质量报告
SELECT _wstart AS time_window,AVG(CHAR_LENGTH(device_name)) AS avg_name_len,AVG(CHAR_LENGTH(error_msg)) AS avg_msg_len,COUNT(CASE WHEN CHAR_LENGTH(error_msg) > 200 THEN 1 END) AS long_msg_count,COUNT(CASE WHEN CHAR_LENGTH(device_name) < 5 THEN 1 END) AS short_name_count
FROM meters
WHERE ts >= NOW - 24h
INTERVAL(1h)
ORDER BY time_window;
场景 B: 存储空间优化
目的:分析字段实际使用长度,优化存储空间分配。
应用示例:
-- 分析字段使用率
SELECT 'device_name' AS field_name,MAX(CHAR_LENGTH(device_name)) AS max_used,128 AS defined_length,MAX(CHAR_LENGTH(device_name)) * 100.0 / 128 AS usage_percent
FROM meters
UNION ALL
SELECT 'error_msg' AS field_name,MAX(CHAR_LENGTH(error_msg)) AS max_used,256 AS defined_length,MAX(CHAR_LENGTH(error_msg)) * 100.0 / 256 AS usage_percent
FROM meters
WHERE error_msg IS NOT NULL;
场景 C: 国际化支持评估
目的:评估系统对多语言的支持情况。
应用示例:
-- 统计不同语言类型的消息分布
SELECT CASEWHEN LENGTH(error_msg) = CHAR_LENGTH(error_msg) THEN 'ASCII'WHEN LENGTH(error_msg) <= CHAR_LENGTH(error_msg) * 2 THEN '混合文本'ELSE '多字节文本'END AS text_encoding,COUNT(*) AS msg_count,AVG(CHAR_LENGTH(error_msg)) AS avg_char_len,AVG(LENGTH(error_msg)) AS avg_byte_len
FROM meters
WHERE error_msg IS NOT NULL AND error_msg != ''
GROUP BY text_encoding;
场景 D: 文本字段优化建议
目的:为字段长度调整提供数据支持。
应用示例:
-- 生成字段优化建议
SELECT tbname,MAX(CHAR_LENGTH(device_name)) AS max_name_len,MAX(CHAR_LENGTH(error_msg)) AS max_msg_len,CASEWHEN MAX(CHAR_LENGTH(device_name)) < 32 THEN '可缩短至VARCHAR(32)'WHEN MAX(CHAR_LENGTH(device_name)) > 64 THEN '建议扩展至VARCHAR(128)'ELSE '当前长度合适'END AS name_suggestion,CASEWHEN MAX(CHAR_LENGTH(error_msg)) < 128 THEN '可缩短至VARCHAR(128)'WHEN MAX(CHAR_LENGTH(error_msg)) > 200 THEN '建议扩展至VARCHAR(512)'ELSE '当前长度合适'END AS msg_suggestion
FROM meters
GROUP BY tbname;
注意事项
-
多字节字符处理:CHAR_LENGTH 正确处理 UTF-8 等多字节编码,一个中文字符计为 1 个字符。
-
与 LENGTH 的区别:
- CHAR_LENGTH:返回字符数量
- LENGTH:返回字节数量
- 对于 ASCII 字符,两者结果相同
- 对于多字节字符,LENGTH 通常是 CHAR_LENGTH 的 2-4 倍
-
NULL 值处理:输入为 NULL 时返回 NULL,需要在 WHERE 子句中特别注意。
-
空字符串:空字符串返回 0,不是 NULL。
-
性能考虑:CHAR_LENGTH 需要遍历字符串解析字符,在超大字符串上可能有性能开销。
-
字符编码:确保客户端和服务端使用一致的字符编码(通常是 UTF-8)。
-
字段类型:仅适用于 VARCHAR 和 NCHAR 类型,其他类型会报错。
数学关系
基本定义:
CHAR_LENGTH(s) = 字符串 s 中的字符数量
与 LENGTH 的关系:
- 对于 ASCII 字符串:
CHAR_LENGTH(s) = LENGTH(s) - 对于 UTF-8 中文字符串:
LENGTH(s) ≈ CHAR_LENGTH(s) × 3 - 对于 UTF-8 日文字符串:
LENGTH(s) ≈ CHAR_LENGTH(s) × 3 - 对于混合字符串:
CHAR_LENGTH(s) ≤ LENGTH(s)
特殊情况:
CHAR_LENGTH('') = 0CHAR_LENGTH(NULL) = NULLCHAR_LENGTH(s) ≥ 0
相关函数
- LENGTH:返回字符串的字节长度
- SUBSTR/SUBSTRING:提取子字符串,按字符位置操作
- LTRIM/RTRIM/TRIM:移除空格,可能改变字符长度
- CONCAT:连接字符串,结果长度为各部分长度之和
- UPPER/LOWER:大小写转换,不改变字符长度
函数意义与价值
数学意义
CHAR_LENGTH 函数实现了对 Unicode 字符串的正确计数,它将多字节字符视为单个字符单位。这对于支持国际化的应用程序至关重要,因为它提供了与人类认知一致的字符串长度概念。
实际应用价值
-
国际化支持
- 正确处理多语言文本
- 统一的长度度量标准
- 跨语言数据一致性
-
数据质量控制
- 验证字段长度限制
- 检测数据截断问题
- 标准化数据录入
-
存储优化
- 评估实际存储需求
- 优化字段长度定义
- 减少空间浪费
-
用户界面设计
- 计算显示宽度
- 控制输入长度
- 优化布局设计
-
性能分析
- 识别大文本字段
- 优化查询性能
- 改进索引策略
本用户手册提供了 CHAR_LENGTH 函数的完整使用说明,特别针对电力系统中的多语言消息处理、数据质量监控、存储优化等实际需求,所有示例均符合 TDengine 语法规范,方便用户快速上手并应用于生产环境。
关于 TDengine
TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。
