三步:建库、建表、定字段。 前两步点两下,第三步要动脑。 字段类型在平台上是硬约束:整数位填字母,写入时就报错。 这是好事——错在写的时候比错在读的时候好查。 最容易漏的是自增主键。它不为了唯一,为了「改数据时能指到那一行」。
上一节讲它是什么,这一节讲怎么建。 建表这一步决定了后面所有事:字段定少了以后要补,定多了永远空着,没有主键就等着改错数据。 这一节的 Demo 用 sqlite3 的宽松来反衬平台的严格——同一个错误,两边反应完全不同。
一、建库:名字和用途
建库只要两样:名字和用途说明。名字用英文或拼音,别用中文——有些节点的 SQL 里要拼表名。 用途说明是给谁看的?给人看的,也是给智能体看的。挂到智能体上时,它靠这段说明判断该不该碰这个库。 所以说明要写成「用户会怎么说」:「登记来访人员,记录姓名、单位、事由与时间」, 比「访客表」有用得多。这一条第 3.1 节讲过一遍。
二、建表:字段怎么定
字段是这张表的全部。定之前先列三样东西。 一、这条记录最少要有哪几个字段才不废? 那几个设为必填,其余可空。 二、哪些字段将来要用来查? 那些字段的写法要统一(日期统一格式、单位用下拉)。
三、哪些字段其实属于另一件事? 那些该拆走,别硬塞进来。 三样列完,字段表就出来了。 演示里访客表定了五个字段:姓名(必填)、电话、来访人数、是否 VIP、到访时间。
三、字段类型:平台严,这里松
演示里试了四种插法:正常插入、整数位塞字母、必填位填空、布尔位塞 2。
| 试什么 | sqlite 的反应 | 平台的反应 |
|---|---|---|
| 正常插入 | 收下 | 收下 |
| 整数位塞字母 | 收下,类型变 text | 写入时报错 |
| 必填位填空 | 报 NOT NULL | 写入时报错 |
| 布尔位塞 2 | 收下 | 写入时报错 |
三种「收下」里,第一种和第三种最坑:它悄悄改了类型,之后读出来是另一种东西。 平台严一点是好事。错在写入那一步,你能看到报错;错在读出来时,你看到的是一句缺了角的答复。
四、为什么一定要自增主键
很多人不加主键,觉得「姓名够用了」。不够。
演示里那一步:要改张伟那一行,没有主键只能写 WHERE name = '张伟'。两个张伟,就一起改了。
有 gid,写 WHERE gid = 1,改一个是一个。主键的价值在改和删,不在查。
这一条在下一节会变成一个真事故——忘写 WHERE 那次,五行全被覆盖。加个主键,至少能精确补回来。
五、定多了和定少了
定多了:空字段永远空着,占位置,还让下游提示词里多出几个「未知」。 定少了:以后要加。 加字段本身不难(一句 ALTER TABLE 或点一下),难的是已经写进去的历史记录,新字段是空的, 那批数据要补。 所以定字段时多问一句:这个字段三个月后还会用吗? 不会就别加。
反过来也有一条: 记录之间要对比的字段,一定要单独存。把「三点半」和「来访人数三个」混在一个文本字段里, 以后统计就做不了。
六、建表的三条规矩
一、至少一个必填字段。 允许全空的表,早晚会被插进一堆空行。 二、加自增主键。 不为了唯一,为了能精确指到一行。 三、日期用日期类型,别用文本。 文本日期排序会出错——「2026-9-1」排在「2026-10-1」后面。
三条都是「现在多做一步,以后少一次事故」。
七、动手 Demo:建库、建表、定字段
建一张访客表,五个字段。然后故意插四种错数据,看 sqlite 收不收。 再看收下来的那些,读出来变成了什么。
CREATE TABLE guest (
gid INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
phone TEXT,
count INTEGER,
vip BOOLEAN,
come_at DATETIME)
INSERT INTO guest (name, count) VALUES ('李四', 'abc') -- 整数位塞字母
INSERT INTO guest (name) VALUES (NULL) -- 必填位填空
INSERT INTO guest (name, vip) VALUES ('王五', 2) -- 布尔位塞 2
实跑输出:
--------------------------------------------------------------------
建库、建表、定字段
--------------------------------------------------------------------
① 四种字段类型,各试一遍
--------------------------------------------------------------------
正常插入:收下了
整数位塞字母:收下了
必填位填空:被拦,NOT NULL constraint failed: guest.name
布尔位塞 2:收下了
② 收下来的那些,读出来是什么
--------------------------------------------------------------------
| gid | name | count | count 的类型 | vip | vip 的类型 |
|---:|---|---:|---|---:|---|
| 1 | 张伟 | 3 | integer | 1 | integer |
| 2 | 李四 | abc | text | None | null |
| 3 | 王五 | None | null | 2 | integer |
「abc」塞进整数位,sqlite 收了,类型变成 text。「2」塞进布尔位,也收了。
这就是宽松:类型只是建议,不是约束。
③ 平台那一侧会怎么处理
--------------------------------------------------------------------
平台数据库的字段类型只有几种:文本、整数、数字、布尔、日期。
整数位填「abc」,平台在写入时就报错,不会存进去。
这一步是好事:错在写的时候,比错在读的时候好查。
真正插进一行,看它长什么样:
(1, '张伟', '13900000001', 3, 1, '2026-10-30 09:00')
④ 字段定多了和定少了
--------------------------------------------------------------------
定多了:空字段永远空着,占位置,还让下游的提示词里多出几个「未知」。
定少了:以后要加。
加字段在 sqlite 里是一句 ALTER TABLE,在平台上也是点一下——但已经写进去的历史记录,新字段是空的,
之前那批数据要补。
所以定字段的时候多问一句:这个字段三个月后还会用吗? 不会就别加。
⑤ 自增主键该不该要
--------------------------------------------------------------------
要。理由不是「唯一」,是改数据的时候需要它。
没有主键,你要改张伟那一行,只能写 WHERE name = '张伟'——两个张伟就一起改了。
有 gid,写 WHERE gid = 1,改一个是一个。
这一条在第 7.3 节会变成一个真事故。
①第一段四种插法。只有「必填位填空」被拦,报 NOT NULL;另外两种都收下了。
②第二段最关键:收下来的那些,typeof 一看就露馅。
「abc」塞进整数位后类型变成 text,「2」塞进布尔位还是 integer。
③所以宽松不是好事:类型只是建议,不是约束。 错在写入时你能看见,错在读出来时你看不见。
④平台那一侧会在写入时就报错。这一步是好事——错在写的时候比错在读的时候好查。
⑤最后那段讲主键:它的价值在改和删,不在查。没有主键,改张伟那一行要靠姓名,两个张伟就一起改了。
30 秒实验
- 数一下你那张表有几个字段,其中几个是必填的。一个必填都没有的,早晚会进空行。
- 检查你的日期字段类型。是文本的话,试一下按它排序,看顺序对不对。
- 给你所有的表补一个自增主键。补完想想上次改数据是怎么定位那一行的。
常见误区
- 「类型不重要,反正是文本存。」整数位存了字母,读出来算数就会崩。平台会在写入时拦,别绕过。
- 「姓名够唯一了,不用主键。」两个同名的人就一起被改。主键是为了精确指到一行。
- 「字段先都加上,以后用得上。」空字段永远空着,还会让下游提示词里多几个「未知」。
自测三问(点开对答案)
1. 建表前要列哪三样东西? —— 最少要哪几个字段才不废、哪些字段将来要查、哪些字段其实属于另一件事。 2. 为什么说「类型宽松」不是好事? —— 它会悄悄改类型,读出来是另一种东西。错在写入时能看见,错在读出来时看不见。 3. 自增主键真正的用途是什么? —— 改和删的时候能精确指到一行。不为了唯一,为了不误伤同名的行。表建好了,下一节往里写数据。四种操作各有一个坑,其中一个能让整张表在一秒钟内被覆盖。
- ☐ (本篇完,下一篇 7.3 使用扣子数据库)
相关笔记
- 扣子数据库概述:平台库的形状
- 什么是插件:插件描述该怎么写
- 15 数据库基础 · 索引
- 🐦 扣子开发 AI Agent · 索引