🐦 第11章 实战案例:智能室内设计师
📄 一句话概括

字段不是越多越好,是按「以后要查什么」倒推。四个够不够,看你要不要按预算筛。 类型选错,数就不对:预算存成文本,「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 秒实验

  1. 写下你以后要问的三个问题,从问题倒推字段。倒推不出来的字段先别加。
  2. 检查你的表:有没有把编号存成数字的。有就改成文本,重建一次。
  3. 给你最常用的那条查询加一个 ORDER BY。排序变了,看到的东西就变了。

常见误区

  1. 「字段多存几个保险。」多一个字段就多一处要保证它有值。按问题倒推。
  2. 「预算存成文本也能比。」字典序比大小,9 会大于 10。这种错不报错。
  3. 「电话存整数省地方。」前导零被吃掉。编号一律用文本。
自测三问(点开对答案) 1. 字段怎么定? —— 先写三个以后要问的问题,从问题倒推字段。问题里没出现的先别加。 2. 预算为什么不能存文本? —— 文本按字典序比大小,9 会被判成大于 10。查询不报错,结果多一条。 3. 写库为什么要回读? —— 写库节点不报错不等于写进去了。键名错一个字照样返回成功。

表建好了,下一节写人设。人设决定它敢不敢拒绝。

相关笔记