数据类型 #
一、数据类型概览 #
1.1 类型分类 #
text
CockroachDB 数据类型
├── 数值类型
│ ├── 整数类型
│ │ ├── INT / INTEGER / BIGINT
│ │ ├── INT2 / SMALLINT
│ │ └── INT4 / INT
│ ├── 浮点类型
│ │ ├── FLOAT / FLOAT8
│ │ └── REAL
│ └── 定点类型
│ └── DECIMAL / NUMERIC
│
├── 字符串类型
│ ├── CHAR / CHARACTER
│ ├── VARCHAR / CHARACTER VARYING
│ ├── TEXT / STRING
│ └── BYTES
│
├── 日期时间类型
│ ├── DATE
│ ├── TIME
│ ├── TIMESTAMP
│ ├── TIMESTAMPTZ
│ └── INTERVAL
│
├── JSON类型
│ ├── JSON
│ └── JSONB
│
├── 数组类型
│ └── ARRAY
│
└── 其他类型
├── BOOLEAN / BOOL
├── UUID
├── ENUM
├── BIT
└── INET
1.2 PostgreSQL兼容性 #
CockroachDB 高度兼容 PostgreSQL 数据类型。
| 兼容级别 | 说明 |
|---|---|
| 完全兼容 | 数值、字符串、日期时间类型 |
| 高度兼容 | JSON、数组、UUID 类型 |
| 部分兼容 | 某些精度和边界值处理 |
二、数值类型 #
2.1 整数类型 #
类型范围
| 类型 | 字节 | 范围 |
|---|---|---|
| INT2 / SMALLINT | 2 | -32768 ~ 32767 |
| INT4 / INT | 4 | -2147483648 ~ 2147483647 |
| INT8 / BIGINT / INT | 8 | -2^63 ~ 2^63-1 |
使用示例
sql
-- 创建表
CREATE TABLE integers (
id INT PRIMARY KEY DEFAULT unique_rowid(),
small_col SMALLINT,
int_col INT,
big_col BIGINT
);
-- 插入数据
INSERT INTO integers (small_col, int_col, big_col)
VALUES
(32767, 2147483647, 9223372036854775807);
-- 查询
SELECT * FROM integers;
自动生成ID
sql
-- 使用 unique_rowid()
CREATE TABLE users (
id BIGINT PRIMARY KEY DEFAULT unique_rowid(),
name VARCHAR(100)
);
-- 使用序列
CREATE SEQUENCE user_seq;
CREATE TABLE users2 (
id BIGINT PRIMARY KEY DEFAULT nextval('user_seq'),
name VARCHAR(100)
);
-- 使用 UUID
CREATE TABLE users3 (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(100)
);
2.2 浮点类型 #
类型说明
| 类型 | 字节 | 精度 |
|---|---|---|
| FLOAT / FLOAT8 / DOUBLE PRECISION | 8 | 约15位有效数字 |
| REAL / FLOAT4 | 4 | 约6位有效数字 |
使用示例
sql
CREATE TABLE floats (
id INT PRIMARY KEY,
float_col FLOAT,
real_col REAL
);
INSERT INTO floats (id, float_col, real_col)
VALUES
(1, 3.14159265358979, 3.14159);
SELECT * FROM floats;
注意事项
sql
-- 浮点数精度问题
SELECT 0.1::FLOAT + 0.2::FLOAT;
-- 结果可能不是精确的 0.3
-- 金融计算建议使用 DECIMAL
SELECT 0.1::DECIMAL + 0.2::DECIMAL;
-- 结果: 0.3
2.3 定点类型 #
DECIMAL 类型
sql
-- DECIMAL(precision, scale)
-- precision: 总位数
-- scale: 小数位数
CREATE TABLE decimals (
id INT PRIMARY KEY,
price DECIMAL(10, 2),
rate DECIMAL(5, 4),
amount DECIMAL(20, 6)
);
INSERT INTO decimals (id, price, rate, amount)
VALUES
(1, 99999999.99, 1.2345, 12345678901234.567890);
SELECT * FROM decimals;
金融场景示例
sql
-- 账户余额表
CREATE TABLE accounts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id BIGINT NOT NULL,
balance DECIMAL(20, 2) NOT NULL DEFAULT 0.00,
frozen_amount DECIMAL(20, 2) NOT NULL DEFAULT 0.00,
created_at TIMESTAMP DEFAULT NOW()
);
-- 转账事务
BEGIN;
UPDATE accounts SET balance = balance - 100.00 WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100.00 WHERE user_id = 2;
COMMIT;
-- 查询余额
SELECT user_id, balance FROM accounts;
三、字符串类型 #
3.1 CHAR 和 VARCHAR #
类型对比
| 类型 | 说明 | 最大长度 |
|---|---|---|
| CHAR(n) | 定长字符串 | n 字符 |
| VARCHAR(n) | 变长字符串 | n 字符 |
| TEXT / STRING | 变长字符串 | 无限制 |
使用示例
sql
CREATE TABLE strings (
id INT PRIMARY KEY,
char_col CHAR(10),
varchar_col VARCHAR(255),
text_col TEXT,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE
);
INSERT INTO strings (char_col, varchar_col, text_col, name, email)
VALUES
('hello', 'This is a variable length string', 'Long text content...', 'Alice', 'alice@example.com'),
('world', 'Another string', 'More text...', 'Bob', 'bob@example.com');
SELECT * FROM strings;
存储差异
sql
-- CHAR 定长存储,不足补空格
-- CHAR(10) 存储 'hello' 实际存储 'hello '
-- VARCHAR 变长存储,按实际长度
-- VARCHAR(10) 存储 'hello' 实际存储 'hello'
-- TEXT 无长度限制
-- 推荐使用 TEXT 替代 VARCHAR
3.2 BYTES类型 #
sql
-- BYTES 类型存储二进制数据
CREATE TABLE files (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
filename VARCHAR(255) NOT NULL,
mime_type VARCHAR(100),
file_size INT,
file_data BYTES,
created_at TIMESTAMP DEFAULT NOW()
);
-- 插入二进制数据
INSERT INTO files (filename, mime_type, file_size, file_data)
VALUES ('test.bin', 'application/octet-stream', 4, b'\x00\x01\x02\x03');
-- 读取二进制数据
SELECT filename, length(file_data) AS size FROM files;
3.3 字符集和排序规则 #
sql
-- 查看支持的排序规则
SHOW COLLATIONS;
-- 指定排序规则
CREATE TABLE collation_test (
id INT PRIMARY KEY,
name VARCHAR(100) COLLATE en_US
);
-- 使用特定排序规则查询
SELECT * FROM collation_test
ORDER BY name COLLATE en_US;
四、日期时间类型 #
4.1 类型概览 #
| 类型 | 格式 | 范围 |
|---|---|---|
| DATE | YYYY-MM-DD | 0001-01-01 ~ 9999-12-31 |
| TIME | HH:MM:SS | 00:00:00 ~ 23:59:59 |
| TIMESTAMP | YYYY-MM-DD HH:MM:SS | 0001-01-01 ~ 9999-12-31 |
| TIMESTAMPTZ | YYYY-MM-DD HH:MM:SS+TZ | 带时区的时间戳 |
| INTERVAL | 时间间隔 | - |
4.2 DATE 类型 #
sql
CREATE TABLE dates (
id INT PRIMARY KEY,
birth_date DATE NOT NULL,
hire_date DATE,
event_date DATE
);
INSERT INTO dates (birth_date, hire_date, event_date)
VALUES
('1990-05-15', '2020-01-01', '2024-12-25'),
('1985-08-20', '2018-06-15', '2024-01-01');
-- 日期函数
SELECT
birth_date,
EXTRACT(YEAR FROM birth_date) AS year,
EXTRACT(MONTH FROM birth_date) AS month,
EXTRACT(DAY FROM birth_date) AS day,
birth_date + INTERVAL '1 year' AS next_year
FROM dates;
4.3 TIME 类型 #
sql
CREATE TABLE times (
id INT PRIMARY KEY,
start_time TIME,
end_time TIME
);
INSERT INTO times (start_time, end_time)
VALUES
('09:00:00', '18:00:00'),
('08:30:00', '17:30:00');
-- 时间函数
SELECT
start_time,
end_time,
end_time - start_time AS duration
FROM times;
4.4 TIMESTAMP 类型 #
sql
CREATE TABLE events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
event_name VARCHAR(100) NOT NULL,
start_time TIMESTAMP NOT NULL,
end_time TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
INSERT INTO events (event_name, start_time, end_time)
VALUES
('会议', '2024-03-27 10:00:00', '2024-03-27 12:00:00'),
('培训', '2024-03-28 14:00:00', '2024-03-28 17:00:00');
-- 时间戳函数
SELECT
event_name,
start_time,
TO_CHAR(start_time, 'YYYY-MM-DD HH24:MI') AS formatted,
end_time - start_time AS duration
FROM events;
4.5 TIMESTAMPTZ 类型 #
sql
-- 带时区的时间戳
CREATE TABLE events_tz (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
event_name VARCHAR(100) NOT NULL,
event_time TIMESTAMPTZ NOT NULL
);
INSERT INTO events_tz (event_name, event_time)
VALUES ('国际会议', '2024-03-27 10:00:00+08:00');
-- 时区转换
SELECT
event_name,
event_time,
event_time AT TIME ZONE 'UTC' AS utc_time,
event_time AT TIME ZONE 'America/New_York' AS ny_time
FROM events_tz;
4.6 INTERVAL 类型 #
sql
-- 时间间隔
SELECT
INTERVAL '1 year',
INTERVAL '2 months',
INTERVAL '3 days',
INTERVAL '4 hours',
INTERVAL '5 minutes',
INTERVAL '6 seconds';
-- 时间计算
SELECT
NOW() AS current_time,
NOW() + INTERVAL '1 day' AS tomorrow,
NOW() - INTERVAL '1 week' AS last_week,
NOW() + INTERVAL '1 month' AS next_month;
-- 创建间隔列
CREATE TABLE subscriptions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id BIGINT,
duration INTERVAL,
start_time TIMESTAMP DEFAULT NOW()
);
INSERT INTO subscriptions (user_id, duration)
VALUES (1, INTERVAL '1 year');
SELECT
user_id,
start_time,
duration,
start_time + duration AS end_time
FROM subscriptions;
五、JSON类型 #
5.1 JSON vs JSONB #
| 类型 | 说明 | 性能 |
|---|---|---|
| JSON | 存储原始JSON文本 | 写入快,读取慢 |
| JSONB | 存储二进制格式 | 写入慢,读取快 |
推荐使用 JSONB
5.2 基本使用 #
sql
CREATE TABLE json_data (
id INT PRIMARY KEY,
data JSONB,
config JSONB,
created_at TIMESTAMP DEFAULT NOW()
);
-- 插入 JSON 数据
INSERT INTO json_data (id, data, config)
VALUES
(1,
'{"name": "Alice", "age": 25, "skills": ["PostgreSQL", "CockroachDB"]}',
'{"theme": "dark", "language": "zh-CN"}'),
(2,
'{"name": "Bob", "age": 30, "address": {"city": "Beijing", "zip": "100000"}}',
'{"theme": "light", "language": "en-US"}');
SELECT * FROM json_data;
5.3 JSON函数 #
提取数据
sql
-- 提取 JSON 值
SELECT
id,
data->>'name' AS name,
data->'age' AS age,
data->'skills' AS skills
FROM json_data;
-- 提取嵌套数据
SELECT
id,
data->>'name' AS name,
data->'address'->>'city' AS city,
data->'address'->>'zip' AS zip
FROM json_data
WHERE data->'address' IS NOT NULL;
-- 提取数组元素
SELECT
id,
data->'skills'->0 AS first_skill,
jsonb_array_length(data->'skills') AS skills_count
FROM json_data
WHERE jsonb_typeof(data->'skills') = 'array';
修改数据
sql
-- 设置 JSON 值
UPDATE json_data
SET data = jsonb_set(data, '{age}', '26')
WHERE id = 1;
-- 添加新字段
UPDATE json_data
SET data = data || '{"email": "alice@example.com"}'
WHERE id = 1;
-- 删除字段
UPDATE json_data
SET data = data - 'email'
WHERE id = 1;
-- 追加数组元素
UPDATE json_data
SET data = jsonb_set(
data,
'{skills}',
data->'skills' || '"MySQL"'
)
WHERE id = 1;
查询条件
sql
-- JSON 包含
SELECT * FROM json_data
WHERE data @> '{"name": "Alice"}';
-- JSON 路径存在
SELECT * FROM json_data
WHERE data ? 'address';
-- JSON 搜索
SELECT * FROM json_data
WHERE data->>'name' = 'Alice';
5.4 JSON索引 #
sql
-- 创建 GIN 索引
CREATE INDEX idx_data ON json_data USING GIN (data);
-- 创建表达式索引
CREATE INDEX idx_data_name ON json_data ((data->>'name'));
-- 使用索引查询
SELECT * FROM json_data WHERE data->>'name' = 'Alice';
六、数组类型 #
6.1 基本使用 #
sql
-- 创建数组列
CREATE TABLE arrays (
id INT PRIMARY KEY,
tags STRING[],
numbers INT[],
matrix INT[][]
);
-- 插入数组数据
INSERT INTO arrays (id, tags, numbers, matrix)
VALUES
(1, ARRAY['tag1', 'tag2', 'tag3'], ARRAY[1, 2, 3], ARRAY[[1,2], [3,4]]),
(2, ARRAY['a', 'b'], ARRAY[10, 20, 30], ARRAY[[5,6], [7,8]]);
-- 查询数组
SELECT * FROM arrays;
6.2 数组操作 #
sql
-- 访问数组元素 (索引从1开始)
SELECT
id,
tags[1] AS first_tag,
numbers[2] AS second_number
FROM arrays;
-- 数组长度
SELECT
id,
array_length(tags, 1) AS tags_count
FROM arrays;
-- 数组包含
SELECT * FROM arrays
WHERE tags @> ARRAY['tag1'];
-- 数组元素检查
SELECT * FROM arrays
WHERE 'tag1' = ANY(tags);
-- 数组连接
SELECT
id,
array_to_string(tags, ', ') AS tags_str
FROM arrays;
七、其他类型 #
7.1 BOOLEAN类型 #
sql
CREATE TABLE booleans (
id INT PRIMARY KEY,
is_active BOOLEAN DEFAULT TRUE,
is_deleted BOOLEAN DEFAULT FALSE
);
INSERT INTO booleans (is_active, is_deleted)
VALUES (TRUE, FALSE), (FALSE, TRUE), (true, false);
SELECT
id,
is_active,
is_deleted,
is_active IS TRUE AS active_check
FROM booleans;
7.2 UUID类型 #
sql
-- UUID 类型
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(100)
);
INSERT INTO users (name) VALUES ('Alice'), ('Bob');
-- 查询
SELECT id, name FROM users;
-- 从字符串转换
SELECT '550e8400-e29b-41d4-a716-446655440000'::UUID;
7.3 ENUM类型 #
sql
-- 创建枚举类型
CREATE TYPE status_type AS ENUM ('pending', 'active', 'inactive', 'deleted');
-- 使用枚举类型
CREATE TABLE enums (
id INT PRIMARY KEY,
status status_type DEFAULT 'pending',
priority status_type
);
INSERT INTO enums (status, priority)
VALUES
('active', 'pending'),
('inactive', 'active');
-- 查询
SELECT id, status, priority FROM enums;
7.4 INET类型 #
sql
-- IP地址类型
CREATE TABLE networks (
id INT PRIMARY KEY,
ip_addr INET,
cidr_range CIDR
);
INSERT INTO networks (ip_addr, cidr_range)
VALUES
('192.168.1.1', '192.168.1.0/24'),
('10.0.0.1', '10.0.0.0/8');
-- 查询
SELECT
ip_addr,
cidr_range,
host(ip_addr) AS host,
netmask(cidr_range) AS netmask
FROM networks;
八、类型选择建议 #
8.1 数值类型选择 #
| 场景 | 推荐类型 |
|---|---|
| 主键ID | UUID 或 BIGINT |
| 年龄 | SMALLINT |
| 数量 | INT |
| 金额 | DECIMAL(20, 2) |
| 百分比 | DECIMAL(5, 2) |
| 科学计算 | FLOAT |
8.2 字符串类型选择 #
| 场景 | 推荐类型 |
|---|---|
| 用户名 | VARCHAR(50) |
| 邮箱 | VARCHAR(255) |
| 手机号 | VARCHAR(20) |
| 文章标题 | VARCHAR(200) |
| 文章内容 | TEXT |
| 文件数据 | BYTES |
8.3 日期时间选择 #
| 场景 | 推荐类型 |
|---|---|
| 出生日期 | DATE |
| 创建时间 | TIMESTAMP |
| 更新时间 | TIMESTAMP |
| 跨时区时间 | TIMESTAMPTZ |
| 时间间隔 | INTERVAL |
8.4 特殊类型选择 #
| 场景 | 推荐类型 |
|---|---|
| 开关状态 | BOOLEAN |
| 固定选项 | ENUM |
| 配置数据 | JSONB |
| 标签列表 | STRING[] |
| 唯一标识 | UUID |
| IP地址 | INET |
九、类型转换 #
9.1 显式转换 #
sql
-- CAST 函数
SELECT
CAST('123' AS INT) AS int_val,
CAST('123.45' AS DECIMAL(10, 2)) AS decimal_val,
CAST(123 AS VARCHAR) AS char_val,
CAST('2024-03-27' AS DATE) AS date_val;
-- :: 语法
SELECT
'123'::INT AS int_val,
'123.45'::DECIMAL(10, 2) AS decimal_val,
123::VARCHAR AS char_val,
'2024-03-27'::DATE AS date_val;
9.2 隐式转换 #
sql
-- 数值与字符串转换
SELECT '123'::INT + 456;
SELECT CONCAT(123, 'abc');
-- 日期转换
SELECT DATE('2024-03-27 10:30:00');
SELECT TO_CHAR(NOW(), 'YYYY-MM-DD');
十、总结 #
数据类型最佳实践:
| 建议 | 说明 |
|---|---|
| 选择合适类型 | 避免过大或过小 |
| 金额用 DECIMAL | 避免精度丢失 |
| 时间用 TIMESTAMP | 标准时间格式 |
| JSON 用 JSONB | 性能更好 |
| 主键用 UUID | 分布式友好 |
下一步,让我们深入学习 CockroachDB 的核心组件!
最后更新:2026-03-27