插入数据 #

一、INSERT概述 #

1.1 INSERT特点 #

Cassandra的INSERT语句有以下特点:

text
INSERT特点:

✓ 插入或更新(UPSERT语义)
✓ 支持TTL(生存时间)
✓ 支持时间戳
✓ 支持JSON格式
✓ 支持条件插入(轻量级事务)

1.2 基本语法 #

sql
INSERT INTO [keyspace_name.]table_name 
[(column_name, ...)]
VALUES (value, ...)
[USING option [AND option ...]]
[IF NOT EXISTS];

二、基本插入 #

2.1 完整列插入 #

sql
-- 插入所有列
INSERT INTO users (user_id, name, email, age, created_at)
VALUES (
    uuid(),
    '张三',
    'zhangsan@example.com',
    28,
    toTimestamp(now())
);

2.2 部分列插入 #

sql
-- 插入部分列(未指定列为NULL)
INSERT INTO users (user_id, name, email)
VALUES (uuid(), '李四', 'lisi@example.com');

2.3 使用函数 #

sql
-- 使用内置函数
INSERT INTO users (user_id, name, email, created_at)
VALUES (
    uuid(),                    -- 生成UUID
    '王五',
    'wangwu@example.com',
    toTimestamp(now())         -- 当前时间戳
);

-- 使用timeuuid
INSERT INTO events (event_id, device_id, event_data)
VALUES (now(), 'device-001', 'event data');

三、UPSERT语义 #

3.1 插入或更新 #

sql
-- 第一次插入
INSERT INTO users (user_id, name, email)
VALUES (550e8400-e29b-41d4-a716-446655440000, '张三', 'zhang@example.com');

-- 相同主键再次插入(实际上是更新)
INSERT INTO users (user_id, name, email)
VALUES (550e8400-e29b-41d4-a716-446655440000, '张三更新', 'zhang_new@example.com');

-- 结果:原有数据被覆盖

3.2 部分列更新 #

sql
-- 原始数据
INSERT INTO users (user_id, name, email, age)
VALUES (uuid(), '张三', 'zhang@example.com', 28);

-- 仅更新email列
INSERT INTO users (user_id, email)
VALUES (550e8400-e29b-41d4-a716-446655440000, 'new_email@example.com');

-- 注意:name和age保持不变(不是NULL)

四、TTL设置 #

4.1 设置生存时间 #

sql
-- 设置TTL为1小时(3600秒)
INSERT INTO users (user_id, name, email)
VALUES (uuid(), '临时用户', 'temp@example.com')
USING TTL 3600;

-- 设置TTL为1天(86400秒)
INSERT INTO sessions (session_id, user_id, created_at)
VALUES (uuid(), 550e8400-e29b-41d4-a716-446655440000, toTimestamp(now()))
USING TTL 86400;

4.2 TTL应用场景 #

text
TTL应用场景:

临时数据
├── 验证码
├── 会话信息
├── 缓存数据
└── 临时令牌

日志数据
├── 短期日志
├── 调试信息
└── 临时状态

自动清理
├── 过期数据自动删除
└── 无需手动清理

4.3 查看剩余TTL #

sql
-- 查看数据剩余TTL
SELECT TTL(email), user_id, name, email 
FROM users 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

五、时间戳设置 #

5.1 设置写入时间戳 #

sql
-- 设置自定义时间戳
INSERT INTO users (user_id, name, email)
VALUES (uuid(), '张三', 'zhang@example.com')
USING TIMESTAMP 1704067200000000;

-- 同时设置TTL和时间戳
INSERT INTO users (user_id, name, email)
VALUES (uuid(), '李四', 'li@example.com')
USING TTL 3600 AND TIMESTAMP 1704067200000000;

5.2 时间戳作用 #

text
时间戳作用:

冲突解决
├── 相同主键多次写入
├── 时间戳大的覆盖小的
└── 用于数据恢复

数据导入
├── 保留原始写入时间
└── 数据迁移场景

调试分析
├── 追踪数据变更
└── 问题排查

六、JSON插入 #

6.1 JSON格式插入 #

sql
-- JSON格式插入
INSERT INTO users JSON '{
    "user_id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "张三",
    "email": "zhangsan@example.com",
    "age": 28,
    "created_at": "2024-01-15T10:30:00Z"
}';

-- 简化JSON(省略空格)
INSERT INTO users JSON '{"user_id":"550e8400-e29b-41d4-a716-446655440000","name":"李四","email":"lisi@example.com"}';

6.2 JSON插入选项 #

sql
-- DEFAULT UNSET:未指定的列保持原值
INSERT INTO users JSON '{
    "user_id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "new_email@example.com"
}' DEFAULT UNSET;

-- DEFAULT NULL:未指定的列设为NULL(默认行为)
INSERT INTO users JSON '{
    "user_id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "new_email@example.com"
}' DEFAULT NULL;

6.3 JSON集合类型 #

sql
-- JSON插入集合类型
INSERT INTO users JSON '{
    "user_id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "张三",
    "tags": ["vip", "active"],
    "preferences": {"theme": "dark", "language": "zh"}
}';

七、轻量级事务 #

7.1 条件插入 #

sql
-- 仅当记录不存在时插入
INSERT INTO users (user_id, email, name)
VALUES (uuid(), 'unique@example.com', '张三')
IF NOT EXISTS;

-- 返回结果包含是否成功
-- [applied] | user_id | email              | name
------------+---------+--------------------+-------
--       True | uuid    | unique@example.com | 张三

7.2 应用场景 #

text
轻量级事务应用场景:

唯一性保证
├── 唯一邮箱注册
├── 唯一用户名
└── 唯一标识符

初始化数据
├── 首次创建
└── 避免覆盖

注意事项
├── 性能开销较大(4次往返)
├── 仅在必要时使用
└── 避免频繁使用

八、批量插入 #

8.1 BATCH插入 #

sql
-- 批量插入
BEGIN BATCH
    INSERT INTO users (user_id, name, email)
    VALUES (uuid(), '用户1', 'user1@example.com');
    INSERT INTO users (user_id, name, email)
    VALUES (uuid(), '用户2', 'user2@example.com');
    INSERT INTO users (user_id, name, email)
    VALUES (uuid(), '用户3', 'user3@example.com');
APPLY BATCH;

8.2 BATCH选项 #

sql
-- 带选项的BATCH
BEGIN BATCH
    USING TTL 3600
    INSERT INTO sessions (session_id, user_id)
    VALUES (uuid(), 550e8400-e29b-41d4-a716-446655440000);
    INSERT INTO user_sessions (user_id, session_id)
    VALUES (550e8400-e29b-41d4-a716-446655440000, uuid());
APPLY BATCH;

-- UNLOGGED BATCH(不记录日志,性能更高但非原子)
BEGIN UNLOGGED BATCH
    INSERT INTO logs (log_id, message) VALUES (uuid(), 'log1');
    INSERT INTO logs (log_id, message) VALUES (uuid(), 'log2');
APPLY BATCH;

8.3 BATCH最佳实践 #

text
BATCH最佳实践:

推荐
├── 同一分区的操作
├── 需要原子性的操作
└── 少量操作(< 20条)

不推荐
├── 跨分区的大量操作
├── 纯粹为了批量插入
└── 大量数据导入

九、集合类型插入 #

9.1 List插入 #

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

-- 追加元素
UPDATE users 
SET tags = tags + ['new_tag']
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

-- 前置添加
UPDATE users 
SET tags = ['first'] + tags
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

9.2 Set插入 #

sql
-- 插入Set
INSERT INTO users (user_id, name, emails)
VALUES (uuid(), '李四', {'li@example.com', 'si@example.com'});

-- 添加元素
UPDATE users 
SET emails = emails + {'new@example.com'}
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

9.3 Map插入 #

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

-- 添加键值对
UPDATE users 
SET preferences = preferences + {'notification': 'enabled'}
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

十、UDT插入 #

10.1 UDT插入 #

sql
-- 创建UDT
CREATE TYPE address (
    street TEXT,
    city TEXT,
    state TEXT,
    zip_code TEXT
);

-- 插入UDT
INSERT INTO users (user_id, name, home_address)
VALUES (
    uuid(),
    '赵六',
    {street: '朝阳路100号', city: '北京', state: '北京', zip_code: '100000'}
);

十一、性能优化 #

11.1 批量导入 #

bash
# 使用COPY命令导入CSV
cqlsh -e "COPY my_app.users (user_id, name, email) FROM 'users.csv'"

# 使用sstableloader批量导入
sstableloader -d localhost /path/to/sstables

11.2 插入优化建议 #

text
插入优化建议:

1. 使用UNLOGGED BATCH
   └── 同一分区的批量操作

2. 并行写入
   └── 多线程/多客户端并行

3. 调整一致性级别
   └── ONE或ANY提高吞吐量

4. 预处理语句
   └── 使用绑定变量减少解析开销

5. 连接池优化
   └── 合理配置连接池大小

十二、总结 #

插入数据要点:

  1. UPSERT语义:INSERT实际上是插入或更新
  2. TTL设置:自动过期数据
  3. 时间戳:控制数据版本
  4. JSON插入:方便API集成
  5. 轻量级事务:条件插入保证唯一性
  6. 批量操作:同一分区性能更优

下一步,让我们学习更新数据!

最后更新:2026-03-27