Supabase数据类型 #
一、数值类型 #
1.1 整数类型 #
| 类型 | 范围 | 存储 | 用途 |
|---|---|---|---|
| SMALLINT | -32768 ~ 32767 | 2字节 | 小范围整数 |
| INTEGER | -21亿 ~ 21亿 | 4字节 | 常用整数 |
| BIGINT | -922亿亿 ~ 922亿亿 | 8字节 | 大整数 |
| SERIAL | 1 ~ 21亿 | 4字节 | 自增整数 |
| BIGSERIAL | 1 ~ 922亿亿 | 8字节 | 大自增整数 |
sql
-- 整数类型示例
CREATE TABLE numbers (
id BIGSERIAL PRIMARY KEY,
small_num SMALLINT,
normal_num INTEGER,
big_num BIGINT,
auto_id SERIAL
);
-- 插入数据
INSERT INTO numbers (small_num, normal_num, big_num)
VALUES (100, 100000, 9999999999999);
1.2 浮点类型 #
| 类型 | 精度 | 存储 | 用途 |
|---|---|---|---|
| REAL | 6位小数 | 4字节 | 单精度浮点 |
| DOUBLE PRECISION | 15位小数 | 8字节 | 双精度浮点 |
| NUMERIC(p,s) | 任意精度 | 可变 | 精确数值 |
sql
-- 浮点类型示例
CREATE TABLE products (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
price NUMERIC(10, 2) NOT NULL,
weight REAL,
rating DOUBLE PRECISION
);
-- 插入数据
INSERT INTO products (name, price, weight, rating)
VALUES ('Widget', 99.99, 1.5, 4.567890123456789);
1.3 货币类型 #
sql
-- 货币类型
CREATE TABLE transactions (
id BIGSERIAL PRIMARY KEY,
amount MONEY NOT NULL,
currency CHAR(3) DEFAULT 'USD'
);
-- 插入数据
INSERT INTO transactions (amount) VALUES (1234.56);
-- 结果: $1,234.56
二、字符串类型 #
2.1 字符串类型对比 #
| 类型 | 说明 | 用途 |
|---|---|---|
| CHAR(n) | 定长字符串 | 固定长度如国家代码 |
| VARCHAR(n) | 变长字符串,有长度限制 | 有长度限制的文本 |
| TEXT | 变长字符串,无限制 | 通用文本 |
sql
-- 字符串类型示例
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
country_code CHAR(2) NOT NULL,
username VARCHAR(50) UNIQUE NOT NULL,
bio TEXT
);
-- 插入数据
INSERT INTO users (country_code, username, bio)
VALUES ('US', 'john_doe', 'A long biography...');
2.2 字符串操作 #
sql
-- 字符串函数
SELECT
UPPER('hello') as upper, -- HELLO
LOWER('HELLO') as lower, -- hello
LENGTH('hello') as length, -- 5
CONCAT('Hello', ' ', 'World'), -- Hello World
SUBSTRING('Hello World', 1, 5), -- Hello
REPLACE('Hello', 'l', 'L'), -- HeLLo
TRIM(' hello '), -- hello
LEFT('Hello', 3), -- Hel
RIGHT('Hello', 3), -- llo
SPLIT_PART('a,b,c', ',', 2); -- b
三、布尔类型 #
3.1 布尔值 #
sql
-- 布尔类型
CREATE TABLE tasks (
id BIGSERIAL PRIMARY KEY,
title TEXT NOT NULL,
completed BOOLEAN DEFAULT FALSE,
is_priority BOOLEAN DEFAULT FALSE
);
-- 插入数据
INSERT INTO tasks (title, completed, is_priority)
VALUES ('Task 1', true, false),
('Task 2', false, true),
('Task 3', 't', 'f'), -- 也可以用 't'/'f'
('Task 4', 'yes', 'no'); -- 或 'yes'/'no'
-- 查询
SELECT * FROM tasks WHERE completed = true;
SELECT * FROM tasks WHERE NOT completed;
四、日期时间类型 #
4.1 日期时间类型 #
| 类型 | 格式 | 用途 |
|---|---|---|
| DATE | YYYY-MM-DD | 日期 |
| TIME | HH:MM:SS | 时间 |
| TIMETZ | HH:MM:SS+TZ | 带时区时间 |
| TIMESTAMP | YYYY-MM-DD HH:MM:SS | 时间戳 |
| TIMESTAMPTZ | YYYY-MM-DD HH:MM:SS+TZ | 带时区时间戳 |
| INTERVAL | 时间段 | 时间间隔 |
sql
-- 日期时间类型
CREATE TABLE events (
id BIGSERIAL PRIMARY KEY,
event_date DATE NOT NULL,
start_time TIME NOT NULL,
end_time TIMETZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
duration INTERVAL
);
-- 插入数据
INSERT INTO events (event_date, start_time, end_time, duration)
VALUES (
'2024-01-15',
'09:00:00',
'17:00:00+08:00',
'8 hours'
);
4.2 日期时间函数 #
sql
-- 当前时间
SELECT NOW(); -- 2024-01-15 10:30:00+08
SELECT CURRENT_DATE; -- 2024-01-15
SELECT CURRENT_TIME; -- 10:30:00+08
SELECT CURRENT_TIMESTAMP; -- 2024-01-15 10:30:00+08
-- 日期计算
SELECT NOW() + INTERVAL '1 day';
SELECT NOW() - INTERVAL '1 week';
SELECT NOW() + INTERVAL '1 month 2 days 3 hours';
-- 日期提取
SELECT EXTRACT(YEAR FROM NOW());
SELECT EXTRACT(MONTH FROM NOW());
SELECT EXTRACT(DAY FROM NOW());
SELECT EXTRACT(HOUR FROM NOW());
SELECT EXTRACT(DOW FROM NOW()); -- 星期几 (0-6)
-- 日期格式化
SELECT TO_CHAR(NOW(), 'YYYY-MM-DD');
SELECT TO_CHAR(NOW(), 'YYYY年MM月DD日');
SELECT TO_CHAR(NOW(), 'HH24:MI:SS');
-- 日期截断
SELECT DATE_TRUNC('month', NOW()); -- 月初
SELECT DATE_TRUNC('week', NOW()); -- 周初
SELECT DATE_TRUNC('day', NOW()); -- 当天零点
-- 年龄计算
SELECT AGE(NOW(), '1990-01-01');
SELECT AGE('1990-01-01');
五、UUID类型 #
5.1 UUID使用 #
sql
-- 启用uuid-ossp扩展
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- UUID表
CREATE TABLE sessions (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
user_id BIGINT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
expires_at TIMESTAMPTZ
);
-- 插入数据
INSERT INTO sessions (user_id, expires_at)
VALUES (1, NOW() + INTERVAL '24 hours');
-- UUID函数
SELECT uuid_generate_v4(); -- 随机UUID
SELECT uuid_generate_v1(); -- 基于时间戳的UUID
5.2 UUID vs SERIAL #
text
SERIAL (自增整数)
├── 优点: 紧凑、高效
├── 缺点: 可预测、迁移复杂
└── 适合: 内部系统、小规模应用
UUID
├── 优点: 全局唯一、不可预测、易于迁移
├── 缺点: 占用空间大、索引效率稍低
└── 适合: 分布式系统、公开API
六、JSON类型 #
6.1 JSON vs JSONB #
| 特性 | JSON | JSONB |
|---|---|---|
| 存储 | 文本 | 二进制 |
| 解析 | 每次查询时解析 | 存储时解析 |
| 索引 | 不支持 | 支持 |
| 性能 | 写入快 | 查询快 |
| 空格 | 保留 | 不保留 |
sql
-- 推荐使用JSONB
CREATE TABLE products (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
attributes JSONB DEFAULT '{}'::jsonb,
metadata JSONB DEFAULT '{}'::jsonb
);
-- 插入数据
INSERT INTO products (name, attributes, metadata)
VALUES (
'Laptop',
'{"color": "silver", "weight": 1.5, "specs": {"cpu": "M1", "ram": 16}}',
'{"views": 100, "tags": ["electronics", "computer"]}'
);
6.2 JSONB操作 #
sql
-- 提取值
SELECT attributes->>'color' FROM products; -- silver (文本)
SELECT attributes->'specs'->>'cpu' FROM products; -- M1
-- 提取数组元素
SELECT metadata->'tags'->0 FROM products; -- "electronics"
-- 条件查询
SELECT * FROM products WHERE attributes->>'color' = 'silver';
-- 包含查询
SELECT * FROM products WHERE attributes @> '{"color": "silver"}';
-- 键存在检查
SELECT * FROM products WHERE attributes ? 'color';
-- 任意键存在
SELECT * FROM products WHERE attributes ?| array['color', 'size'];
-- 所有键存在
SELECT * FROM products WHERE attributes ?& array['color', 'weight'];
6.3 JSONB修改 #
sql
-- 更新值
UPDATE products
SET attributes = jsonb_set(attributes, '{color}', '"gold"');
-- 添加键值
UPDATE products
SET attributes = attributes || '{"brand": "Apple"}';
-- 删除键
UPDATE products
SET attributes = attributes - 'weight';
-- 删除嵌套键
UPDATE products
SET attributes = attributes #- '{specs,ram}';
-- 批量更新
UPDATE products
SET attributes = attributes || '{"new_key": "new_value"}'::jsonb;
6.4 JSONB函数 #
sql
-- 获取所有键
SELECT jsonb_object_keys(attributes) FROM products;
-- 获取所有值
SELECT jsonb_each(attributes) FROM products;
-- 展开数组
SELECT jsonb_array_elements(metadata->'tags') FROM products;
-- 合并JSON
SELECT '{"a": 1}'::jsonb || '{"b": 2}'::jsonb;
-- JSON路径查询
SELECT jsonb_path_query(attributes, '$.specs.cpu') FROM products;
6.5 JSONB索引 #
sql
-- GIN索引
CREATE INDEX idx_products_attributes ON products USING GIN (attributes);
-- 路径索引
CREATE INDEX idx_products_color ON products USING GIN (attributes jsonb_path_ops);
-- 使用索引的查询
SELECT * FROM products WHERE attributes @> '{"color": "silver"}';
七、数组类型 #
7.1 数组定义 #
sql
-- 数组类型
CREATE TABLE posts (
id BIGSERIAL PRIMARY KEY,
title TEXT NOT NULL,
tags TEXT[] DEFAULT '{}',
ratings INTEGER[] DEFAULT '{}',
coordinates NUMERIC[]
);
-- 插入数据
INSERT INTO posts (title, tags, ratings, coordinates)
VALUES (
'My Post',
ARRAY['tech', 'programming', 'javascript'],
ARRAY[5, 4, 5, 3, 5],
ARRAY[40.7128, -74.0060]
);
-- 或使用字符串语法
INSERT INTO posts (title, tags)
VALUES ('Another Post', '{news,world}');
7.2 数组操作 #
sql
-- 访问元素 (索引从1开始)
SELECT tags[1] FROM posts; -- tech
-- 数组切片
SELECT tags[1:2] FROM posts; -- {tech,programming}
-- 数组长度
SELECT array_length(tags, 1) FROM posts; -- 3
-- 包含元素
SELECT * FROM posts WHERE 'tech' = ANY(tags);
-- 包含所有
SELECT * FROM posts WHERE tags @> ARRAY['tech'];
-- 包含任意
SELECT * FROM posts WHERE tags && ARRAY['tech', 'news'];
-- 重叠
SELECT * FROM posts WHERE tags && ARRAY['tech', 'sports'];
7.3 数组函数 #
sql
-- 追加元素
UPDATE posts SET tags = array_append(tags, 'new-tag');
-- 前置元素
UPDATE posts SET tags = array_prepend('first-tag', tags);
-- 删除元素
UPDATE posts SET tags = array_remove(tags, 'tech');
-- 替换元素
UPDATE posts SET tags = array_replace(tags, 'tech', 'technology');
-- 连接数组
SELECT ARRAY[1,2] || ARRAY[3,4]; -- {1,2,3,4}
-- 展开数组
SELECT unnest(tags) FROM posts;
-- 聚合为数组
SELECT array_agg(name) FROM users;
7.4 数组索引 #
sql
-- GIN索引
CREATE INDEX idx_posts_tags ON posts USING GIN (tags);
-- 使用索引的查询
SELECT * FROM posts WHERE tags @> ARRAY['tech'];
八、枚举类型 #
8.1 定义枚举 #
sql
-- 创建枚举类型
CREATE TYPE status_type AS ENUM (
'draft',
'published',
'archived',
'deleted'
);
-- 使用枚举
CREATE TABLE articles (
id BIGSERIAL PRIMARY KEY,
title TEXT NOT NULL,
status status_type DEFAULT 'draft'
);
-- 插入数据
INSERT INTO articles (title, status)
VALUES ('My Article', 'published');
-- 查询
SELECT * FROM articles WHERE status = 'published';
8.2 枚举操作 #
sql
-- 添加枚举值
ALTER TYPE status_type ADD VALUE 'review' AFTER 'draft';
-- 重命名枚举值 (PostgreSQL 12+不支持直接重命名)
-- 需要创建新枚举类型并迁移数据
-- 查看枚举值
SELECT enum_range(NULL::status_type);
九、网络地址类型 #
9.1 网络类型 #
sql
-- 网络地址类型
CREATE TABLE servers (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
ip_address INET,
cidr_block CIDR,
mac_address MACADDR
);
-- 插入数据
INSERT INTO servers (name, ip_address, cidr_block, mac_address)
VALUES (
'Web Server',
'192.168.1.100',
'192.168.1.0/24',
'08:00:2b:01:02:03'
);
-- 查询
SELECT * FROM servers WHERE ip_address << '192.168.1.0/24';
十、其他类型 #
10.1 二进制类型 #
sql
-- 二进制数据
CREATE TABLE files (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
data BYTEA
);
-- 插入数据
INSERT INTO files (name, data)
VALUES ('test.bin', '\x48656c6c6f');
10.2 XML类型 #
sql
-- XML数据
CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
content XML
);
INSERT INTO documents (content)
VALUES ('<root><item>Hello</item></root>');
10.3 范围类型 #
sql
-- 范围类型
CREATE TABLE reservations (
id BIGSERIAL PRIMARY KEY,
room_number INTEGER,
during TSRANGE
);
INSERT INTO reservations (room_number, during)
VALUES (101, '[2024-01-15 14:00, 2024-01-15 16:00)');
-- 查询重叠
SELECT * FROM reservations
WHERE during && TSRANGE('[2024-01-15 15:00, 2024-01-15 17:00)');
十一、类型转换 #
11.1 显式转换 #
sql
-- 使用 ::type 语法
SELECT '123'::INTEGER;
SELECT '2024-01-15'::DATE;
SELECT '{"a": 1}'::JSONB;
-- 使用 CAST 函数
SELECT CAST('123' AS INTEGER);
SELECT CAST('2024-01-15' AS DATE);
11.2 隐式转换 #
sql
-- PostgreSQL会自动进行某些转换
SELECT 1 + '2'; -- 结果: 3 (字符串自动转数字)
-- 但某些情况需要显式转换
SELECT '123' || 456; -- 错误
SELECT '123' || 456::TEXT; -- 正确: '123456'
十二、总结 #
常用数据类型速查:
| 类型 | 用途 |
|---|---|
| BIGSERIAL | 自增主键 |
| TEXT | 文本内容 |
| BOOLEAN | 是/否 |
| TIMESTAMPTZ | 时间戳 |
| JSONB | JSON数据 |
| UUID | 全局唯一ID |
| TEXT[] | 字符串数组 |
| NUMERIC | 精确数值 |
下一步,让我们学习数据插入!
最后更新:2026-03-28