第2章:数据库基础与SQL回顾

说实话,很多Agent开发者一上来就搞复杂架构,结果连个简单的SQL查询都写不对。我见过太多这样的案例了。这一章,咱们把关系型数据库的核心概念、CRUD操作、JOIN查询、事务与索引好好捋一遍。这些东西,是Agent跟数据库对话的基础语言。

2.1 关系型数据库核心概念

关系型数据库,说白了就是一张张表格的集合。你想想看,Excel表格你会用吧?关系型数据库就是更强大、更规范的Excel。

核心概念速览:

  • 表(Table):数据的容器,类似Excel的一个sheet
  • 行(Row):一条完整的数据记录
  • 列(Column):数据的一个属性字段
  • 主键(Primary Key):唯一标识一行数据的字段
  • 外键(Foreign Key):关联其他表的字段
  • 索引(Index):加速数据检索的数据结构

我个人习惯把数据库想象成一个大型仓库。表就是货架,行就是每个货架上的商品,列就是商品的属性(名称、价格、库存)。主键就是商品的唯一编号,外键就是商品所属的分类编号。

我的经验:设计表结构时,一定要先想清楚主键。我早期做过一个项目,用了UUID做主键,结果查询性能惨不忍睹。后来改成自增整数,速度直接提升10倍。记住:能用整数就别用字符串,能用自增就别用随机数。

2.2 CRUD操作

CRUD是数据库操作的四大金刚:Create(创建)、Read(读取)、Update(更新)、Delete(删除)。Agent跟数据库交互,90%的时间都在干这些事。

2.2.1 创建(INSERT)

-- 插入单条记录
INSERT INTO users (name, email, age) 
VALUES ('张三', 'zhangsan@example.com', 28);

-- 插入多条记录
INSERT INTO users (name, email, age) VALUES 
('李四', 'lisi@example.com', 32),
('王五', 'wangwu@example.com', 25);

注意:插入数据时,主键字段通常不需要手动指定,数据库会自动生成。但如果你用了业务主键(比如身份证号),那就得自己传了。

2.2.2 读取(SELECT)

-- 查询所有字段
SELECT * FROM users;

-- 查询特定字段
SELECT name, email FROM users;

-- 带条件查询
SELECT * FROM users WHERE age > 25;

-- 排序
SELECT * FROM users ORDER BY age DESC;

-- 分页
SELECT * FROM users LIMIT 10 OFFSET 20;

我曾经犯过一个低级错误:在生产环境直接执行 SELECT * FROM huge_table,结果把数据库内存打爆了。嗯,从那以后我再也不敢在生产环境用 SELECT * 了,必须加 LIMIT

2.2.3 更新(UPDATE)

-- 更新单条记录
UPDATE users SET age = 29 WHERE id = 1;

-- 批量更新
UPDATE users SET status = 'active' WHERE age >= 18;

警告:UPDATE语句一定要加WHERE条件!不加WHERE会更新整张表。我有个同事,刚入职第一天就把全公司员工的工资都改成了1000块...还好有备份。

2.2.4 删除(DELETE)

-- 删除单条记录
DELETE FROM users WHERE id = 1;

-- 清空表(保留表结构)
DELETE FROM users;

-- 快速清空表(不保留事务日志)
TRUNCATE TABLE users;

DELETE和TRUNCATE的区别:DELETE可以加WHERE条件,而且支持事务回滚。TRUNCATE是直接清空,速度快但无法回滚。我建议Agent操作时优先用DELETE,安全第一。

2.3 JOIN查询

Agent经常需要从多个表中获取数据。JOIN就是把这些表连接起来的桥梁。说白了,就是根据某些字段的对应关系,把多张表的数据拼成一张大表。

2.3.1 内连接(INNER JOIN)

-- 查询用户及其订单信息
SELECT u.name, o.order_id, o.amount
FROM users u
INNER JOIN orders o ON u.id = o.user_id;

内连接只返回两个表中匹配的数据。不匹配的行会被忽略。

2.3.2 左连接(LEFT JOIN)

-- 查询所有用户及其订单(包括没有订单的用户)
SELECT u.name, o.order_id, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;

左连接以左表为主,左表的数据全部保留。右表没有匹配的数据就用NULL填充。

2.3.3 右连接(RIGHT JOIN)

-- 查询所有订单及其用户(包括没有用户的订单)
SELECT u.name, o.order_id, o.amount
FROM users u
RIGHT JOIN orders o ON u.id = o.user_id;

右连接跟左连接相反,以右表为主。

2.3.4 全连接(FULL JOIN)

-- MySQL不支持FULL JOIN,可以用UNION模拟
SELECT u.name, o.order_id, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
UNION
SELECT u.name, o.order_id, o.amount
FROM users u
RIGHT JOIN orders o ON u.id = o.user_id;

我的经验:实际开发中,LEFT JOIN用得最多。我做过一个Agent系统,需要查询用户信息同时带上最新的操作日志。用LEFT JOIN完美解决。记住:JOIN越多,查询越慢。超过3个JOIN就要考虑优化了。

2.4 事务

事务,就是一组要么全部成功、要么全部失败的操作。Agent在处理业务逻辑时,经常需要保证数据的一致性。比如转账:A扣钱,B加钱,这两个操作必须同时成功或同时失败。

2.4.1 事务的四大特性(ACID)

特性 说明 我的理解
原子性(Atomicity) 事务中的所有操作,要么全部完成,要么全部不完成 就像买一包薯片,要么付钱拿走,要么不买
一致性(Consistency) 事务执行前后,数据必须保持一致状态 转账前后,总金额不变
隔离性(Isolation) 并发执行的事务之间互不干扰 两个人同时取钱,不会互相影响
持久性(Durability) 事务一旦提交,数据永久保存 钱转出去了,就算断电也不会丢

2.4.2 事务的使用

-- 开始事务
START TRANSACTION;

-- 执行操作
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;

-- 提交事务
COMMIT;

-- 如果出错,回滚
ROLLBACK;

注意:Agent在操作数据库时,一定要考虑事务超时。我遇到过Agent卡在事务里,导致数据库连接池被占满,整个系统都挂了。建议设置事务超时时间,比如30秒自动回滚。

2.5 索引

索引,就是数据库的目录。没有索引,数据库就得全表扫描,数据量一大就慢得离谱。有了索引,数据库能直接定位到数据位置,速度提升几个数量级。

2.5.1 索引类型

  • 主键索引:自动创建,唯一且非空
  • 唯一索引:保证字段值的唯一性
  • 普通索引:加速查询,不保证唯一性
  • 联合索引:多个字段组合成一个索引
  • 全文索引:用于文本内容的搜索

2.5.2 创建索引

-- 创建普通索引
CREATE INDEX idx_name ON users(name);

-- 创建唯一索引
CREATE UNIQUE INDEX idx_email ON users(email);

-- 创建联合索引
CREATE INDEX idx_name_age ON users(name, age);

-- 查看索引
SHOW INDEX FROM users;

2.5.3 索引使用原则

索引不是越多越好。我见过有人给每个字段都建了索引,结果写入速度慢得像蜗牛。为什么?因为每次插入数据,数据库都要更新所有索引。

索引使用建议:

  • 经常出现在WHERE条件中的字段,建索引
  • 经常用于ORDER BY的字段,建索引
  • 经常用于JOIN的字段,建索引
  • 数据量小的表(少于1000行),不用建索引
  • 频繁更新的字段,谨慎建索引
  • 不要给每个字段都建索引

我曾经接手过一个项目,一张表有50个字段,建了40个索引。每次插入数据要等好几秒。我删掉了30个没用的索引,写入速度直接提升到毫秒级。你想想看,索引这东西,用好了是神器,用不好就是灾难。

2.6 本章知识体系

下面这张图,是我梳理的本章知识结构。你可以把它当作一个快速参考地图。

第2章:数据库基础与SQL回顾 - 知识体系 关系型数据库 核心概念 表、行、列 主键、外键 索引 CRUD操作 INSERT - 创建 SELECT - 读取 UPDATE - 更新 DELETE - 删除 JOIN查询 INNER JOIN LEFT JOIN RIGHT JOIN FULL JOIN 事务 ACID特性 COMMIT / ROLLBACK 索引 主键/唯一/普通/联合索引 使用原则与优化 五大模块相互配合,构成Agent与数据库交互的基础能力

好了,这一章的内容就到这里。数据库基础是Agent开发的地基,地基不牢,楼盖得再高也得塌。下一章,我们会把这些SQL知识应用到实际的Agent开发中,看看Agent怎么跟数据库对话。


公众号:蓝海资料掘金营,微信deep3321