集合类型 #

一、集合类型概述 #

1.1 三种集合类型 #

类型 描述 特点
List 有序列表 有序、可重复
Set 无序集合 无序、唯一
Map 键值对映射 键值对、键唯一

1.2 集合限制 #

text
集合限制:

单个元素
├── 最大64KB

集合大小
├── 建议 < 1000个元素
├── 最大 65535个元素
└── 大量数据建议使用独立表

查询
├── 读取整个集合
├── 不能索引单个元素(除非建索引)
└── 更新需要读取-修改-写入

二、List类型 #

2.1 创建List列 #

sql
-- 创建包含List的表
CREATE TABLE users (
    user_id UUID PRIMARY KEY,
    name TEXT,
    tags LIST<TEXT>,
    scores LIST<INT>
);

2.2 插入数据 #

sql
-- 插入完整List
INSERT INTO users (user_id, name, tags, scores)
VALUES (
    uuid(), 
    '张三', 
    ['vip', 'active', 'premium'], 
    [85, 90, 78]
);

-- 插入空List
INSERT INTO users (user_id, name, tags)
VALUES (uuid(), '李四', []);

2.3 更新List #

sql
-- 追加元素
UPDATE users 
SET tags = tags + ['new_tag']
WHERE user_id = ?;

-- 前置添加元素
UPDATE users 
SET tags = ['first'] + tags
WHERE user_id = ?;

-- 替换特定位置(索引从0开始)
UPDATE users 
SET tags[0] = 'updated_tag'
WHERE user_id = ?;

-- 删除特定元素
UPDATE users 
SET tags = tags - ['old_tag']
WHERE user_id = ?;

-- 删除特定位置
DELETE tags[0] FROM users WHERE user_id = ?;

2.4 查询List #

sql
-- 查询整个List
SELECT user_id, tags FROM users WHERE user_id = ?;

-- 查询特定位置
SELECT tags[0] FROM users WHERE user_id = ?;

-- 使用CONTAINS查询
SELECT * FROM users WHERE tags CONTAINS 'vip';

-- 使用CONTAINS KEY(需要索引)
CREATE INDEX ON users (tags);
SELECT * FROM users WHERE tags CONTAINS 'vip';

2.5 List特点 #

text
List特点:

有序
├── 元素按插入顺序排列
└── 支持索引访问

可重复
├── 允许重复元素
└── 如 [1, 2, 2, 3]

操作
├── 追加、前置
├── 按索引更新
├── 按值删除
└── 按索引删除

性能
├── 追加性能好
├── 前置性能差(需要移动所有元素)
└── 按索引更新性能差

三、Set类型 #

3.1 创建Set列 #

sql
-- 创建包含Set的表
CREATE TABLE users (
    user_id UUID PRIMARY KEY,
    name TEXT,
    emails SET<TEXT>,
    phone_numbers SET<TEXT>
);

3.2 插入数据 #

sql
-- 插入完整Set
INSERT INTO users (user_id, name, emails)
VALUES (
    uuid(), 
    '张三', 
    {'zhang@example.com', 'zhangsan@example.com'}
);

-- 插入空Set
INSERT INTO users (user_id, name, emails)
VALUES (uuid(), '李四', {});

3.3 更新Set #

sql
-- 添加元素
UPDATE users 
SET emails = emails + {'new@example.com'}
WHERE user_id = ?;

-- 添加多个元素
UPDATE users 
SET emails = emails + {'email1@example.com', 'email2@example.com'}
WHERE user_id = ?;

-- 删除元素
UPDATE users 
SET emails = emails - {'old@example.com'}
WHERE user_id = ?;

-- 删除多个元素
UPDATE users 
SET emails = emails - {'email1@example.com', 'email2@example.com'}
WHERE user_id = ?;

3.4 查询Set #

sql
-- 查询整个Set
SELECT user_id, emails FROM users WHERE user_id = ?;

-- 使用CONTAINS查询
SELECT * FROM users WHERE emails CONTAINS 'zhang@example.com';

-- 创建索引后查询
CREATE INDEX ON users (emails);
SELECT * FROM users WHERE emails CONTAINS 'zhang@example.com';

3.5 Set特点 #

text
Set特点:

无序
├── 元素没有顺序
└── 不支持索引访问

唯一
├── 元素不能重复
├── 自动去重
└── 如 {1, 2, 3} 而非 {1, 2, 2, 3}

操作
├── 添加元素
├── 删除元素
└── 不能更新单个元素

性能
├── 添加性能好
├── 删除性能好
└── 适合存储唯一值集合

四、Map类型 #

4.1 创建Map列 #

sql
-- 创建包含Map的表
CREATE TABLE users (
    user_id UUID PRIMARY KEY,
    name TEXT,
    preferences MAP<TEXT, TEXT>,
    scores MAP<TEXT, INT>
);

4.2 插入数据 #

sql
-- 插入完整Map
INSERT INTO users (user_id, name, preferences)
VALUES (
    uuid(), 
    '张三', 
    {'theme': 'dark', 'language': 'zh', 'timezone': 'Asia/Shanghai'}
);

-- 插入空Map
INSERT INTO users (user_id, name, preferences)
VALUES (uuid(), '李四', {});

4.3 更新Map #

sql
-- 添加键值对
UPDATE users 
SET preferences = preferences + {'notification': 'enabled'}
WHERE user_id = ?;

-- 添加多个键值对
UPDATE users 
SET preferences = preferences + {'key1': 'value1', 'key2': 'value2'}
WHERE user_id = ?;

-- 更新特定键
UPDATE users 
SET preferences['theme'] = 'light'
WHERE user_id = ?;

-- 删除特定键
DELETE preferences['language'] FROM users WHERE user_id = ?;

4.4 查询Map #

sql
-- 查询整个Map
SELECT user_id, preferences FROM users WHERE user_id = ?;

-- 查询特定键值
SELECT preferences['theme'] FROM users WHERE user_id = ?;

-- 使用CONTAINS KEY查询
SELECT * FROM users WHERE preferences CONTAINS KEY 'theme';

-- 使用CONTAINS查询值
SELECT * FROM users WHERE preferences CONTAINS 'dark';

-- 使用CONTAINS ENTRY查询键值对
SELECT * FROM users WHERE preferences CONTAINS ENTRY('theme', 'dark');

-- 创建索引
CREATE INDEX ON users (KEYS(preferences));  -- 键索引
CREATE INDEX ON users (VALUES(preferences)); -- 值索引
CREATE INDEX ON users (ENTRIES(preferences)); -- 条目索引

4.5 Map特点 #

text
Map特点:

键值对
├── 存储键值对
├── 键唯一
└── 值可重复

操作
├── 添加键值对
├── 更新特定键
├── 删除特定键
└── 查询特定键值

性能
├── 键查找快
├── 适合存储属性映射
└── 如配置、偏好设置

五、嵌套集合 #

5.1 集合嵌套限制 #

sql
-- 不支持直接嵌套
-- LIST<LIST<TEXT>> -- 不支持
-- SET<SET<TEXT>>   -- 不支持
-- MAP<TEXT, MAP<TEXT, TEXT>> -- 不支持

-- 解决方案:使用UDT
CREATE TYPE address (
    street TEXT,
    city TEXT,
    country TEXT
);

-- 然后使用集合
CREATE TABLE users (
    user_id UUID PRIMARY KEY,
    addresses LIST<FROZEN<address>>
);

5.2 FROZEN关键字 #

sql
-- FROZEN用于冻结集合,使其可以作为单个值处理
CREATE TABLE example (
    id UUID PRIMARY KEY,
    frozen_list FROZEN<LIST<TEXT>>,
    frozen_set FROZEN<SET<TEXT>>,
    frozen_map FROZEN<MAP<TEXT, TEXT>>
);

-- FROZEN集合特点:
-- 1. 整体更新,不能部分更新
-- 2. 可以作为主键的一部分
-- 3. 可以嵌套在其他集合中

六、集合最佳实践 #

6.1 选择指南 #

text
集合类型选择:

需要有序?
├── 是 → List
└── 否 → 需要唯一?

需要唯一?
├── 是 → Set
└── 否 → 需要键值对?

需要键值对?
├── 是 → Map
└── 否 → List

6.2 性能建议 #

text
性能建议:

1. 控制集合大小
   └── < 1000个元素

2. 避免频繁更新
   └── 特别是List前置操作

3. 大数据用独立表
   └── 超过1000个元素

4. 合理使用索引
   └── 根据查询需求

七、总结 #

集合类型要点:

  1. List:有序、可重复,支持索引访问
  2. Set:无序、唯一,适合唯一值集合
  3. Map:键值对,适合属性映射
  4. 大小限制:建议<1000个元素
  5. FROZEN:冻结集合,支持嵌套
  6. 大数据:使用独立表存储

下一步,让我们学习用户定义类型!

最后更新:2026-03-27