Apache Doris 极速入门:从零掌握增删改查全攻略(附完整代码示例)
一、初识 Apache Doris
Apache Doris 是一款基于 MPP(大规模并行处理)架构的高性能、实时分析型数据库,以高效、简单和统一的特性著称,能够在亚秒级时间内返回海量数据的查询结果。它同时支持高并发的点查询和高吞吐的复杂分析场景,适合用于报表分析、即席查询、统一数仓构建、用户行为分析、订单分析等场景。
Doris 采用 MySQL 协议,高度兼容 MySQL 语法,支持标准 SQL,可以通过各类 MySQL 客户端工具直接连接,学习成本极低。
本文将聚焦于 Doris 的核心操作——增删改查,从建表到数据查询,提供完整的 SQL 示例,帮助读者快速上手。
二、数据模型概述(建表必读)
Doris 提供三种数据模型,在建表时需要根据业务场景选择:
| 模型 | 特点 | 适用场景 |
|---|---|---|
| DUPLICATE KEY | 保留所有原始数据,按 Key 列排序 | 明细数据存储,需要保留全部历史记录 |
| UNIQUE KEY | Key 列唯一,新数据覆盖旧数据 | 主键去重场景,如订单表、用户表 |
| AGGREGATE KEY | 按 Key 列聚合,支持预聚合 | 报表统计场景,如按维度汇总指标 |
新手注意:DUPLICATE KEY 不是“去重键”,而是“排序键”,数据写入时按该列排序存储,目的是优化查询过滤效率。
三种模型的数据都按 Key 列进行排序存储,建表时确定后无法修改,所以选择合适的数据模型非常重要。
三、准备工作
3.1 连接 Doris
使用 MySQL 客户端连接 Doris:
mysql -h <FE_HOST> -P <FE_PORT> -u <USERNAME> -p
# 默认 root 用户密码为空
3.2 创建数据库
-- 创建数据库
CREATE DATABASE IF NOT EXISTS doris_demo;
-- 切换到数据库
USE doris_demo;
四、建表(CREATE)
4.1 DUPLICATE KEY 模型(明细表)
场景:存储用户行为日志,保留所有访问记录,不进行任何聚合。
CREATE TABLE IF NOT EXISTS user_actions_log (
user_id BIGINT NOT NULL COMMENT "用户ID",
action_time DATETIME NOT NULL COMMENT "行为时间",
action_type VARCHAR(50) NOT NULL COMMENT "行为类型",
page_url VARCHAR(500) NOT NULL COMMENT "页面URL",
duration INT DEFAULT 0 COMMENT "停留时长(秒)"
) DUPLICATE KEY(user_id, action_time)
DISTRIBUTED BY HASH(user_id) BUCKETS 10
PROPERTIES("replication_num" = "1");
4.2 UNIQUE KEY 模型(主键表)
场景:存储用户信息,保证每个 user_id 只有一条最新记录。
CREATE TABLE IF NOT EXISTS user_profile (
user_id BIGINT NOT NULL COMMENT "用户ID",
user_name VARCHAR(100) NOT NULL COMMENT "用户姓名",
age INT COMMENT "年龄",
city VARCHAR(100) COMMENT "城市",
balance DECIMAL(10, 2) DEFAULT 0 COMMENT "账户余额"
) UNIQUE KEY(user_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 10
PROPERTIES("replication_num" = "1");
4.3 AGGREGATE KEY 模型(聚合表)
场景:按日期和商品统计的销售报表,支持预聚合。
CREATE TABLE IF NOT EXISTS sales_summary (
sale_date DATE NOT NULL COMMENT "销售日期",
product_id BIGINT NOT NULL COMMENT "商品ID",
total_amount DECIMAL(20, 2) SUM DEFAULT "0" COMMENT "总金额(SUM)",
sale_count BIGINT SUM DEFAULT "0" COMMENT "销售数量(SUM)",
max_price DECIMAL(10, 2) MAX DEFAULT "0" COMMENT "最高单价(MAX)",
min_price DECIMAL(10, 2) MIN DEFAULT "0" COMMENT "最低单价(MIN)"
) AGGREGATE KEY(sale_date, product_id)
DISTRIBUTED BY HASH(product_id) BUCKETS 10
PROPERTIES("replication_num" = "1");
五、数据插入(INSERT)
5.1 单行插入
-- UNIQUE KEY 表插入单行数据
INSERT INTO user_profile(user_id, user_name, age, city, balance)
VALUES(1001, '张三', 25, '北京', 1000.00);
INSERT INTO user_profile(user_id, user_name, age, city, balance)
VALUES(1002, '李四', 30, '上海', 2500.50);
5.2 多行批量插入
-- DUPLICATE KEY 表批量插入
INSERT INTO user_actions_log VALUES
(1001, '2024-01-15 10:30:00', 'click', '/home', 5),
(1001, '2024-01-15 10:35:00', 'click', '/product', 30),
(1002, '2024-01-15 10:32:00', 'purchase', '/checkout', 120),
(1003, '2024-01-15 10:40:00', 'view', '/home', 10),
(1004, '2024-01-15 10:45:00', 'click', '/search', 8);
-- AGGREGATE KEY 表插入
INSERT INTO sales_summary VALUES
('2024-01-15', 101, 1500.00, 3, 600.00, 400.00),
('2024-01-15', 102, 2500.00, 5, 550.00, 450.00),
('2024-01-16', 101, 800.00, 2, 420.00, 380.00);
5.3 INSERT INTO SELECT(数据复制)
-- 从现有表插入数据到新表
INSERT INTO user_profile_backup SELECT * FROM user_profile;
注意:Doris 默认提供 UPSERT 语义,对于 UNIQUE KEY 表,插入相同主键的数据会覆盖原有记录。
六、数据查询(SELECT)
6.1 基础查询
-- 查询所有数据
SELECT * FROM user_profile;
-- 查询指定字段
SELECT user_id, user_name, city FROM user_profile;
-- 条件查询(WHERE 子句)
SELECT * FROM user_actions_log
WHERE action_type = 'click' AND user_id = 1001;
6.2 聚合查询
-- 统计每种行为类型的数量
SELECT action_type, COUNT(*) as cnt
FROM user_actions_log
GROUP BY action_type;
-- 统计用户行为次数
SELECT user_id, action_type, COUNT(*) as action_count
FROM user_actions_log
GROUP BY user_id, action_type
ORDER BY action_count DESC;
6.3 多条件与范围查询
-- IN 查询
SELECT * FROM user_actions_log
WHERE action_type IN ('click', 'view');
-- 范围查询(BETWEEN)
SELECT * FROM user_actions_log
WHERE action_time BETWEEN '2024-01-15 10:00:00' AND '2024-01-15 12:00:00';
-- LIMIT 分页
SELECT * FROM user_profile ORDER BY user_id LIMIT 10;
6.4 多表关联查询
-- 查询用户行为详情(关联 behavior_log 和 user_profile)
SELECT a.user_id, a.action_type, a.action_time, b.user_name, b.city
FROM user_actions_log a
LEFT JOIN user_profile b ON a.user_id = b.user_id
WHERE a.action_type = 'purchase';
七、数据更新(UPDATE / UPSERT)
7.1 UPDATE 语句
Doris 支持标准 SQL 的 UPDATE 语法,非常适合低频、批量更新场景。
-- 更新指定用户的年龄
UPDATE user_profile SET age = age + 1 WHERE user_id = 1001;
-- 批量更新:将所有北京用户的余额增加 100 元
UPDATE user_profile SET balance = balance + 100 WHERE city = '北京';
-- 更新后查看结果
SELECT * FROM user_profile;
7.2 通过 INSERT 实现 UPSERT
对于 UNIQUE KEY 表,插入相同主键的数据会自动覆盖旧记录,实现 Upsert 效果:
-- 插入相同 user_id(1001)的新数据,自动覆盖原记录
INSERT INTO user_profile(user_id, user_name, age, city, balance)
VALUES(1001, '张三', 26, '北京', 1200.00);
-- 查看更新结果
SELECT * FROM user_profile WHERE user_id = 1001;
7.3 批量 UPSERT
-- 一次性更新多条记录
INSERT INTO user_profile VALUES
(1001, '张三', 26, '北京', 1200.00),
(1002, '李四', 31, '上海', 2700.00),
(1005, '王五', 28, '深圳', 3000.00); -- 新增用户
7.4 部分列更新(2.0 版本以上)
如果只想更新部分列而非整行,需要先开启会话变量:
-- 开启部分列更新功能
SET enable_unique_key_partial_update = true;
-- 只更新 age 和 city 两列(必须包含所有 Key 列)
INSERT INTO user_profile(user_id, age, city)
VALUES(1001, 27, '广州');
注意:使用部分列更新时,插入的列必须至少包含所有 Key 列。
八、数据删除(DELETE)
8.1 DELETE 语句
-- 删除指定用户的行为日志
DELETE FROM user_actions_log WHERE user_id = 1004;
-- 删除特定类型的行为记录
DELETE FROM user_actions_log WHERE action_type = 'view';
-- 删除时间范围内的记录
DELETE FROM user_actions_log
WHERE action_time < '2024-01-15 10:30:00';
8.2 清空表数据
-- 删除表中所有数据(保留表结构)
TRUNCATE TABLE user_actions_log;
-- 或使用 DELETE 不加条件
DELETE FROM user_actions_log;
8.3 删除表
-- 删除整个表
DROP TABLE IF EXISTS user_actions_log;
九、高阶操作:表结构变更
在实际使用中,经常需要修改表结构,Doris 提供了灵活的 SCHEMA CHANGE 能力。
9.1 增加列
-- 增加新列
ALTER TABLE user_profile ADD COLUMN phone VARCHAR(20) DEFAULT '' COMMENT "手机号";
-- 在指定列后增加新列
ALTER TABLE user_profile ADD COLUMN email VARCHAR(200) AFTER city;
9.2 删除列
-- 删除指定列
ALTER TABLE user_profile DROP COLUMN phone;
9.3 修改列类型
-- 修改列类型
ALTER TABLE user_profile MODIFY COLUMN age BIGINT;
9.4 查看 Schema Change 进度
-- 查看表结构变更作业进度
SHOW ALTER TABLE COLUMN;
-- 当作业状态为 FINISHED 时,表示修改完成
十、实战:完整电商用户分析示例
以下是一个完整的电商用户行为分析流程,涵盖建表、插入、查询、更新、删除全链路:
Step 1:建表
-- 创建数据库
CREATE DATABASE IF NOT EXISTS ecommerce;
USE ecommerce;
-- 1. 用户信息表(UNIQUE KEY)
CREATE TABLE users (
user_id BIGINT NOT NULL,
name VARCHAR(100) NOT NULL,
register_date DATE NOT NULL,
level VARCHAR(20) DEFAULT '普通会员'
) UNIQUE KEY(user_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 10;
-- 2. 订单表(UNIQUE KEY + 聚合列)
CREATE TABLE orders (
order_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
order_time DATETIME NOT NULL,
product_id BIGINT NOT NULL,
amount DECIMAL(10, 2) NOT NULL
) UNIQUE KEY(order_id)
DISTRIBUTED BY HASH(order_id) BUCKETS 10;
Step 2:插入数据
-- 用户数据
INSERT INTO users VALUES
(1, 'Alice', '2024-01-10', '金牌会员'),
(2, 'Bob', '2024-01-12', '银牌会员'),
(3, 'Carol', '2024-01-15', '普通会员');
-- 订单数据
INSERT INTO orders VALUES
(1001, 1, '2024-01-15 10:00:00', 501, 299.00),
(1002, 1, '2024-01-15 14:30:00', 502, 99.00),
(1003, 2, '2024-01-16 09:15:00', 501, 299.00);
Step 3:查询分析
-- 查询每位用户的订单总金额
SELECT u.user_id, u.name, SUM(o.amount) as total_spent
FROM users u
LEFT JOIN orders o ON u.user_id = o.user_id
GROUP BY u.user_id, u.name
ORDER BY total_spent DESC;
Step 4:更新用户等级
-- 消费累计超过 500 元的用户升级为金牌会员
UPDATE users SET level = '钻石会员'
WHERE user_id IN (
SELECT user_id FROM orders GROUP BY user_id HAVING SUM(amount) >= 500
);
Step 5:删除数据
-- 删除 2024-01-15 之后的订单记录
DELETE FROM orders WHERE order_time > '2024-01-15 23:59:59';
总结
本文全面介绍了 Apache Doris 的增删改查操作,涵盖:
| 操作 | 核心语法 | 关键注意事项 |
|---|---|---|
| 建表 | CREATE TABLE ... [模型] KEY(...) |
选对数据模型,不可修改 |
| 插入 | INSERT INTO ... VALUES |
UNIQUE KEY 表自动 Upsert |
| 查询 | SELECT ... FROM ... WHERE ... |
兼容 MySQL 语法,支持 JOIN |
| 更新 | UPDATE ... SET ... WHERE ... |
适合低频批量更新 |
| 删除 | DELETE FROM ... WHERE ... |
支持条件删除和清空表 |
| 表结构变更 | ALTER TABLE ... ADD/DROP/MODIFY COLUMN |
Schema Change 异步执行 |
相比传统数据库,Doris 的优势在于其 MPP 架构和列式存储带来的海量数据亚秒级查询能力。本文提供的示例代码在 Doris 2.x 及以上版本均可运行,读者可以根据实际业务场景进行调整。如有疑问,欢迎留言交流!
📌 参考资料:本文基于 Apache Doris 官方文档整理,更多详细信息可访问官网:https://doris.apache.org/zh-CN/
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)