第 3 章 · 数据库第 1 页,共 4 页
服务器重启以后,数据还在吗?
读者在百家菜收藏的菜谱要一直留着。这一页先让服务器重启一次,看只记在内存里的收藏怎样丢掉;再把数据交给数据库,并把一道菜谱整理成数据表里的一行。
为什么需要
百家菜是本课程虚构的家常菜谱网站,运行在一台上。现在读者可以收藏菜谱,以后随时翻出来看。菜谱、用户和收藏都要长期保存;读者还想按配料找菜,比如找出用到番茄的菜。
最省事的做法,是让服务器上的程序把收藏记在里。第 2 章讲过,内存很快,却一断电就清空。不断电也一样:程序记在内存里的东西只归这个程序用,程序一停下、重新运行就没了。而服务器总会重启:程序每次更新都要重新运行,机器也可能断电。
重启:只记在内存里的收藏丢了,交给数据库的还在
先看这里收藏几道菜、重启一次、再打开「我的收藏」,两种存法各做一遍。
| 重启之前收藏了 | 重启之后读到 | |
|---|---|---|
| 服务器的内存里 | — | — |
| 数据库里 | — | — |
时间线
还没有操作。
还没有收藏。先按「收藏一道菜」。
「断电重启」让图上每台机器都断电;「更新程序,重新运行」不断电,只让服务器上的程序重新运行。收藏的菜是虚构的。
怎样做
换成「数据库里」,收藏就交给了(database):专门长期保存数据、并能按条件很快找出数据的软件。它把数据写在上,常用的部分也放在内存里,好取得快。每一部安卓手机和苹果手机里都装着一种叫 SQLite 的数据库;SQLite 的网站估计,正在使用的 SQLite 数据库很可能超过一万亿个。
网站的数据库常单独运行在一台机器上。专门替别的程序存取数据的这个程序叫(database server);百家菜服务器向它发请求,是它的。箭头从发出请求的一方指向接到请求的一方,所以图里两条箭头都从服务器指向数据库:交给数据库保存叫(write),新增、修改、删除都算;向数据库要数据叫(read),不改变数据。
按 PostgreSQL、MySQL 这些常用数据库的默认设置,数据库要等改动真正写进硬盘,才回报「保存成功」,服务器再告诉读者「收藏成功」。所以就算数据库所在的机器也断了电,重新开机以后,说过保存成功的数据还在,这叫(durability)。
数据库里最常见的摆法是(table)。你平时说的「表格」,比如电子表格,格子里什么都能填;多数数据库里,数据表的每一(column)只放一类信息,比如菜名,并规定放文字还是数字;每一(row)是一条记录,比如一道菜谱。每一行还要有一个与别的行都不同、也不能空着的值,准确地指出是哪一行,叫(primary key)。菜谱表用编号作主键:两位作者可以各发一道番茄炒蛋,编号却不会重复。
整理成表:把第 1024 号菜谱的各项信息放进各列
先看这里先选一张卡片,再选它该放进哪一列,或者另起一张表。
| 编号 | 菜名 | 作者编号 | 做法 | 收藏数 |
|---|---|---|---|---|
| 1022 | 红烧茄子 | 5 | 茄子切条煎软,加酱油焖熟 | 26 |
| 1023 | 清炒菠菜 | 7 | 蒜爆香,下菠菜大火快炒 | 9 |
| (空) | (空) | (空) | (空) | (空) |
先选一张卡片。
作者编号指向没有画出来的用户表;表里只列出几行,内容是虚构的。
做法也有好几步,却放在一格里:它只整段读出来看,没有人按其中某一步去找,算一个值就行。配料不同,读者要按配料找菜:几种配料连成一段字塞进一格,只能逐段比对着找,又慢又容易找错;一格只放一个值,才好准确地查,也才能为它建普通的(下一页讲)。所以配料另起一张表,一种一行,每行都写着菜谱编号 1024。一道菜谱对应好几行配料,每行配料只属于一道菜谱,这叫(one-to-many)。菜谱编号在这里会重复,同一道菜又不会把一种配料写两次,所以两列合起来当主键。
配料表的菜谱编号存的是菜谱表里某一行的主键,叫(foreign key)。建表时写明这一列指向菜谱表,叫声明外键;声明了,写一个不存在的菜谱编号,数据库就会拒绝。像这样用几张表保存数据、表之间靠编号关联的数据库,叫(relational database)。
代价是什么
数据库是多出来的一个组件,要运行,也要照看;每次存取都要交给另一个程序去办,它在另一台机器上时还要经过网络,比服务器读自己内存里的数据慢得多。
本章只讲一台机器上的持久性:硬盘本身坏了,或者数据被人误删,要靠第 8 章讲的多存几份和备份。
资料来源
以下资料均于 2026-10-23 访问。
- Semiconductor glossary: DRAM
- Virtual Address Space
- Terminating a Process
- Most Widely Deployed SQL Database Engine
- 1.2. Architectural Fundamentals
- 19.5. Write Ahead Log
- InnoDB Startup Options and System Variables
- 28.1. Reliability
- Appendix M. Glossary
- 2.2. Concepts
- 5.5. Constraints
- Guide to table relationships
- 3.3. Foreign Keys
- SQLite Foreign Key Support