【问题描述】OceanBase虚拟列支持哪些数据类型?
6 个赞
虚拟列支持的数据类型
OceanBase MySQL 模式下的虚拟列支持大部分常规数据类型,但不支持大对象类型。具体分类如下:
支持的数据类型
| 类型分类 | 具体类型 |
|---|---|
| 整数类型 | TINYINT、SMALLINT、MEDIUMINT、INT/INTEGER、BIGINT、BOOLEAN |
| 定点/浮点类型 | DECIMAL、NUMERIC、FLOAT、DOUBLE |
| 字符类型 | CHAR、VARCHAR |
| 二进制类型 | BINARY、VARBINARY |
| 日期时间类型 | DATE、TIME、DATETIME、TIMESTAMP、YEAR |
| 位类型 | BIT |
不支持的数据类型
| 类型分类 | 具体类型 | 不支持原因 |
|---|---|---|
| 文本大对象 | TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT | 大对象类型,无法在行内高效计算 |
| 二进制大对象 | TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB | 同上 |
| 枚举/集合 | ENUM、SET | 不支持作为虚拟列类型 |
| JSON | JSON | 不支持直接作为虚拟列类型 |
| 空间类型 | GEOMETRY 等 | 不支持 |
虚拟列的基本用法
虚拟列包含两种类型:
- Virtual Column(虚拟生成列):不占用存储空间,仅在读取时根据表达式实时计算
- Stored Column(存储生成列):在插入或更新时计算并存储,占用存储空间,查询性能更好
-- 创建虚拟列示例
CREATE TABLE t1 (
id INT PRIMARY KEY,
price DECIMAL(10,2),
quantity INT,
total DECIMAL(12,2) GENERATED ALWAYS AS (price * quantity) VIRTUAL
);
-- 存储生成列示例
CREATE TABLE t2 (
id INT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
full_name VARCHAR(101) GENERATED ALWAYS AS (CONCAT(first_name, ' ', last_name)) STORED
);
虚拟列的使用限制
- 不能直接插入或更新虚拟列的值,其值由表达式自动计算
- 创建虚拟列时必须填写表达式
- 已设置的虚拟列不可修改,只能删除后重建
- 表达式只能引用当前表中的其他列、常量和确定性函数
- 虚拟列支持创建索引(等价于函数索引)
- 虚拟列支持 NOT NULL、UNIQUE、CHECK 等约束
实用技巧:虚拟列模拟 JSON 索引
虽然虚拟列不支持 JSON 类型,但可以利用虚拟列提取 JSON 字段并创建索引,这是 OceanBase 中优化 JSON 查询的常用手段:
-- 从 JSON 列中提取字段作为虚拟列并建索引
ALTER TABLE json_docs
ADD COLUMN product_name VARCHAR(100)
GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(content, '$.name'))) STORED;
CREATE INDEX idx_product_name ON json_docs(product_name);
注意:虚拟列的数据类型(如 VARCHAR(100))需要根据表达式返回值合理设置长度,避免截断。
3 个赞
跟OB 虚拟列扛上了。