字段不是越多越好,是按「以后要查什么」倒推。四个够不够,看你要不要按预算筛。 类型选错,数就不对:预算存成文本,「9」会被判成比「10」大。 电话、邮编、身份证号一律用文本。它们不是数,是编号。
11.1 节说过存客户的理由:下次不用重问。这一节把它建出来。 本沙箱没有扣子数据库,用真 sqlite 库代替。 SQL 语句、类型、查询结果都是真的,差的是平台那层界面。 这一节的三个坑都是数据层的:字段少了、类型错了、编号当数字存了。 三个都不报错,都会在某个具体查询上现原形。
一、先想查什么,再定字段
定字段的顺序反了,就会变成「先建一张表,再想它能干什么」。 正确的顺序:写下你以后要问的三个问题,再从问题倒推字段。
| 以后要问什么 | 需要哪些字段 |
|---|---|
| 北欧风的客户有几位、预算多少 | 风格、预算、姓名 |
| 这个月新来几个客户 | 日期 |
| 这个小区的客户都想要什么风格 | 小区、风格 |
三个问题一共要五个字段:姓名、风格、预算、日期、小区。 问题里没出现的字段,先别加。 加一个字段就多一处要保证它有值的地方。
二、选数据库类型
平台建库时要选模式。两种最常见:单用户模式、多用户模式。
| 模式 | 数据怎么存 | 适合谁 |
|---|---|---|
| 单用户 | 所有人共用一张表 | 自己用的工具、内部台账 |
| 多用户 | 按用户身份隔离,各看各的 | 对外发布的智能体 |
装修这个场景要选多用户:客户 A 不该看到客户 B 的电话。 隔离做在数据层,不做在提示词里。 在提示词里写「不要透露别人的信息」,那是靠模型自觉; 在数据层隔离,模型根本查不到。 这一条和第 5 章的权限过滤是同一个道理:检索前先过滤,不是检索后再说别念。
三、六个字段和它们的类型
| 字段 | 类型 | 为什么 |
|---|---|---|
| id | 整数,自增 | 主键,别用姓名当主键 |
| name | 文本 | 姓名,可能重名 |
| phone | 文本 | 编号,不是数字 |
| style | 文本 | 风格名 |
| budget | 数字(小数) | 要比较、要算平均 |
| created | 文本 | '2026-10-12' 这种能被排序的写法 |
日期用文本?是的。只要格式统一成「年-月-日」,文本比较就是时间比较。换成时间戳反而不好读。 关键是格式统一。 '2026-10-12' 和 '2026/10/12' 混着存,排序就乱。 id 用自增整数,不用姓名。姓名会重、会改、会写错一个字。
四、三条查询,三种用法
演示里插了五条客户记录,跑三条查询:
| 查什么 | 怎么写 | 拿到什么 |
|---|---|---|
| 北欧风客户,按预算降序 | WHERE style = '北欧' ORDER BY budget DESC | 3 位 |
| 预算 15 万以上 | WHERE budget >= 15 | 3 位 |
| 10 月 25 日以后 | WHERE created >= '2026-10-25' | 3 位 |
三条查询对应三种用法:按风格做客户画像、按预算分层、按时间看新增。
注意第一条带了 ORDER BY budget DESC。
排序不是可有可无的——客户名单按预算从高到低排,跟按 id 排,看到的是两种东西。
五、类型选错,数就不对
同一批数(9、15、18),筛「大于 10」:
| 存成什么 | 筛出几条 | 哪几条 |
|---|---|---|
| 文本 | 3 | 9、15、18 全在 |
| 小数 | 2 | 15、18 |
文本把「9」判成比「10」大:按字典序比第一个字符,9 比 1 大。 于是 9 万那条混进了「10 万以上」的名单。 这种错不报错。 查询照跑,结果照出,只是多了一条。你要是不核对,永远发现不了。 修法只有一条:存数字的字段就用数字类型。已经存错了的,每次比较都要 CAST,又慢又容易漏。
六、电话用文本
把座机号 0771123456 存进整数列,读出来变成 771123456——前导零没了。
按开头的 0 查(LIKE '0771%'),一条都查不到。
所以电话、邮编、身份证号、订单号,一律用文本。它们不是数,是编号——不会拿来做加减乘除。
顺带一个隐含的好处:文本列能存「138 0000 1111」这种带空格的写法,数字列直接报错。
七、写一条记录要走四步
| 步 | 做什么 | 谁做 |
|---|---|---|
| 1 | 抽字段(姓名、电话、风格、预算) | 大模型或智能体 |
| 2 | 查重(同一个电话有没有) | 数据库查询 |
| 3 | 写入或更新 | 数据库节点 |
| 4 | 回读确认 | 再查一次 |
第二步容易被省。省了之后,同一个客户来三次就是三条记录,统计全错。 第四步也容易被省。省了之后,你不知道到底写进去没有——写库的节点不报错,不等于写进去了。 键名错一个字,它照样返回成功。 这一条 11.7 节会专门验。
八、动手 Demo:四个字段够不够,看以后要查什么
真建一张表、插五条、跑三条查询;再故意用文本存预算、用整数存电话。 两个类型坑都不报错,只是结果不对。
CREATE TABLE cust (id INTEGER PRIMARY KEY, name TEXT NOT NULL,
phone TEXT NOT NULL, style TEXT,
budget REAL, created TEXT)
SELECT name FROM cust WHERE budget >= 15 ORDER BY budget DESC
实跑输出:
--------------------------------------------------------------------
四个字段够不够,看以后要查什么
--------------------------------------------------------------------
① 六个字段,先建表再插五条
--------------------------------------------------------------------
| id | 姓名 | 电话 | 风格 | 预算(万) | 日期 |
|---:|---|---|---|---:|---:|
| 1 | 张女士 | 13800001111 | 北欧 | 18.0 | 2026-10-12 |
| 2 | 李先生 | 13900002222 | 日式 | 9.0 | 2026-10-20 |
| 3 | 王女士 | 13700003333 | 北欧 | 25.0 | 2026-10-25 |
| 4 | 赵先生 | 13600004444 | 侘寂 | 12.0 | 2026-10-28 |
| 5 | 陈女士 | 13500005555 | 北欧 | 15.0 | 2026-10-30 |
预算用 REAL,日期用 TEXT('2026-10-12' 这种能被排序的写法)。
② 四个字段能答什么,答不了什么
--------------------------------------------------------------------
| 存了什么 | 能查什么 | 查不了什么 |
|---|---|---|
| 存了姓名、电话、风格、日期 | 按风格筛、按日期筛 | 按预算筛不了 |
| 加上预算 | 按预算段筛,算客单价 | — |
| 再加小区、户型 | 按楼盘统计、按面积段统计 | — |
字段不是越多越好,是按「以后要查什么」倒推。
演示里三条查询,正好对应三种用法:
按风格:北欧 3 位,王女士 25.0 万、张女士 18.0 万、陈女士 15.0 万
按预算(15 万以上):王女士、张女士、陈女士
按日期(10 月 25 日起):王女士、赵先生、陈女士
③ 类型选错,数就不对
--------------------------------------------------------------------
同一批数(9、15、18),筛「大于 10」:
存成文本:3 条 —— 甲、乙、丙
存成 REAL:2 条 —— 乙、丙
文本把「9」判成比「10」大:按字典序比第一个字符,9 比 1 大。
于是 9 万那条混进了「10 万以上」的名单。
! 存数字的字段就用 REAL 或 INTEGER。一旦存成文本,后面每个比较都要 CAST。
④ 电话用文本,不用整数
--------------------------------------------------------------------
存进去再读出来:座机客户 771123456、手机客户 13800001111
按开头的 0 查:找到 0 条。前导零被整数吃掉了。
所以电话、邮编、身份证号一律用 TEXT。它们不是数,是编号——不会拿来做加减乘除。
⑤ 记一条客户要走几步
--------------------------------------------------------------------
| 步 | 做什么 | 谁做 |
|---:|---|---|
| 1 | 抽字段(姓名、电话、风格、预算) | 大模型或智能体 |
| 2 | 查重(同一个电话有没有) | 数据库查询 |
| 3 | 写入或更新 | 数据库节点 |
| 4 | 回读确认 | 再查一次 |
第四步容易被省。省了之后,你不知道到底写进去没有——第 11.7 节会专门验这一条。
①第一张表六行:五条客户记录,预算 9 到 25 万。 ②三条查询:按风格 3 位、按预算 3 位、按日期 3 位,对应三种用法。 ③第三段是类型坑:同样筛「大于 10」,文本给 3 条,小数给 2 条。 ④文本把「9」判成比「10」大,9 万那条混进了 10 万以上的名单。这种错不报错。 ⑤第四段:座机号存整数,前导零被吃掉,按 0 开头查一条都查不到。
30 秒实验
- 写下你以后要问的三个问题,从问题倒推字段。倒推不出来的字段先别加。
- 检查你的表:有没有把编号存成数字的。有就改成文本,重建一次。
- 给你最常用的那条查询加一个 ORDER BY。排序变了,看到的东西就变了。
常见误区
- 「字段多存几个保险。」多一个字段就多一处要保证它有值。按问题倒推。
- 「预算存成文本也能比。」字典序比大小,9 会大于 10。这种错不报错。
- 「电话存整数省地方。」前导零被吃掉。编号一律用文本。
自测三问(点开对答案)
1. 字段怎么定? —— 先写三个以后要问的问题,从问题倒推字段。问题里没出现的先别加。 2. 预算为什么不能存文本? —— 文本按字典序比大小,9 会被判成大于 10。查询不报错,结果多一条。 3. 写库为什么要回读? —— 写库节点不报错不等于写进去了。键名错一个字照样返回成功。表建好了,下一节写人设。人设决定它敢不敢拒绝。
- ☐ (本篇完,下一篇 11.6 配置智能体人设与回复逻辑)
相关笔记
- 使用扣子数据库:数据库基本功
- 企业知识库落地存在的问题及解决思路:权限过滤要在检索前
- 项目背景与整体思路:为什么要存客户
- 🐦 扣子开发 AI Agent · 索引