先打开它
点击第一个例子下方的按钮。浏览器会在新标签页中打开 Planche,并载入商城数据库。数据库文件只在页面中处理,你的修改不会影响其他机器。需要恢复初始状态时,可在欢迎页重新载入示例。
表就是一张网格
跑一下这条。它要的是名为 categories 的表里的全部内容。
1
SELECT * FROM categories;
结果 — 共 33 行,这里是前 5 行
| id | name | description | parent_id | sort_order | is_active |
|---|---|---|---|---|---|
| 1 | Electronics | Electronics and related products | NULL | 0 | 1 |
| 2 | Laptops | Laptops in Electronics | 1 | 1 | 1 |
| 3 | Phones | Phones in Electronics | 1 | 2 | 1 |
| 4 | Tablets | Tablets in Electronics | 1 | 3 | 1 |
| 5 | Audio | Audio in Electronics | 1 | 4 | 1 |
浏览器会另开一个标签页打开 Planche,示例数据库已经载入,这条查询也已经放好。本页其他示例都会复用同一个标签页;在你按下 F9 之前,什么都不会执行。
返回的网格就是一张表。先认识三个术语:
- 列是顶部的一个标题——
id、name、description。表里每一条记录都有这同样的六个,而这些名字就是你在查询里要敲的。 - 行是网格里横着的一条,它代表一个东西。这里一行就是一个分类。一共 33 行,说明这家商城有 33 个分类。
- 单元格是行与列相交的地方——一个值,比如某个分类的名字。
这个数据库里的每张表都是同一个形状。products 一行一个商品,orders 一行一个订单,customers 一行一个客户。变的只是各自有哪些列。
有些格子是空的,这有个名字
2
SELECT id, name, parent_id
FROM categories
LIMIT 8;
结果 — 共 8 行,这里是前 5 行
| id | name | parent_id |
|---|---|---|
| 1 | Electronics | NULL |
| 2 | Laptops | 1 |
| 3 | Phones | 1 |
| 4 | Tablets | 1 |
| 5 | Audio | 1 |
看 parent_id。有些行是个数字,有些标着 NULL。这个列表示当前分类挂在哪个分类下面——笔记本挂在电子产品下面——而顶层分类不挂在任何分类下面,所以没有东西可填。
NULL 的意思是"这里没有值"。值得把它当成一个独立的概念来学,而不是当成某种零,因为它确实不是:
- NULL 不是
0。零是你量出来的一个数;NULL 是你根本没有的那次测量。 - NULL 也不是空字符串。名字被记成空白的客户,和名字从来没被记录过的客户,是两回事。
NULL 的比较规则与普通值不同,第三课会详细说明。现在只需记住:它表示未知或缺失的值,而不只是空格子。
每一行都有自己的编号
这里的第一列是 id,它是一个只属于某一行、而且永不重用的数字。这就是该行的主键——别的东西靠它来指向这一行,而不必依赖随时可能被人改掉的名字。
你遇到的表几乎都有一个主键,通常就叫 id。
为什么是 23 张表而不是一张
理论上一个商城可以只用一张巨大的网格:一行一个订单,客户姓名、地址、每个商品和价格全都重复写在那一行上。数据库不这么设计,理由很直白——一个客户搬了家,你就得去改他历史上每一笔订单,而任何一行漏改,都会变成一份和其他行互相矛盾的"事实"。
所以每一类东西各占一张表,行与行之间靠主键互指。products.category_id 存的是 categories.id,orders.customer_id 存的是 customers.id。指向另一张表某一行的列叫外键,顺着它走就是第四课要讲的连接。
这也是为什么你需要一个地方查"某张表有哪些列"。示例数据库那一页列出了每张表、每个列,以及哪个列指向哪张表。把它开在另一个标签页里——每天写 SQL 的人也是把表结构摆在手边写的。
查询是一个问题,答案也是一张表
一行、一列、一个数字。它仍然是一张表,只是非常小——而这正是 SQL 的整套想法:你发出一个问题,回来的东西永远是同一种长方形形状,无论是 400 行还是 1 行。
还要注意,这个答案在数据库里哪儿都找不到。没有任何地方存着 400 这个数字;是你问的时候数据库数出来的。大多数有用的查询都是这样——它们算出答案,而不是把答案找出来。
自己跑一条
在工作区上方的编辑器里写或改一条查询,按 F9 运行;想只跑光标所在的那条语句,就按 Ctrl / ⌘ + Enter。结果出现在下面的网格里,行数显示在底部。
左边那一栏是同一个数据库的树形视图:展开 main,再展开 Tables,双击任意一张表就能看到它的行,一个字都不用写。在查询之前想知道表里有什么,这通常是最快的办法。
本页每个例子都在自己的标签页里打开,所以你可以改一条、跑一次、再改回去,而不会弄丢正在做的事。
出错的时候
一定会出错,而错误信息都很短、很直白。列名写错会得到:
no such column: naem
先读信息的结尾——那里通常写着数据库到底没找到什么。新手的错误绝大多数是三种:列名拼错、列其实在另一张表里、以及文本外面少了引号(SQL 要的是 'paid',单引号;双引号是另一个意思)。
出错就意味着什么都没执行。语句是整条被拒绝的,所以一条失败的查询不会改变任何东西。
接下来
你已经知道表、行、列和 NULL 是什么,会跑查询,也看得懂结果。下一课讲的是几乎每条查询都由之搭成的那四个子句。