数据库重启以后还在吗

为什么需要

百家菜是本课程虚构的家常菜谱网站,运行在一台上。现在读者可以收藏菜谱,以后随时翻出来看。菜谱、用户和收藏都要长期保存;读者还想按配料找菜,比如找出用到番茄的菜。

最省事的做法,是让服务器上的程序把收藏记在里。第 2 章讲过,内存很快,却一断电就清空。不断电也一样:程序记在内存里的东西只归这个程序用,程序一停下、重新运行就没了。而服务器总会重启:程序每次更新都要重新运行,机器也可能断电。

重启:只记在内存里的收藏丢了,交给数据库的还在

先看这里收藏几道菜、重启一次、再打开「我的收藏」,两种存法各做一遍。

收藏存在

两种存法比一比
重启之前收藏了重启之后读到
服务器的内存里——
数据库里——

时间线

还没有操作。

还没有收藏。先按「收藏一道菜」。

「断电重启」让图上每台机器都断电;「更新程序,重新运行」不断电,只让服务器上的程序重新运行。收藏的菜是虚构的。

怎样做

换成「数据库里」,收藏就交给了(database):专门长期保存数据、并能按条件很快找出数据的软件。它把数据写在上,常用的部分也放在内存里,好取得快。每一部安卓手机和苹果手机里都装着一种叫 SQLite 的数据库;SQLite 的网站估计,正在使用的 SQLite 数据库很可能超过一万亿个。

网站的数据库常单独运行在一台机器上。专门替别的程序存取数据的这个程序叫(database server);百家菜服务器向它发请求,是它的。箭头从发出请求的一方指向接到请求的一方,所以图里两条箭头都从服务器指向数据库:交给数据库保存叫(write),新增、修改、删除都算;向数据库要数据叫(read),不改变数据。

按 PostgreSQL、MySQL 这些常用数据库的默认设置,数据库要等改动真正写进硬盘,才回报「保存成功」,服务器再告诉读者「收藏成功」。所以就算数据库所在的机器也断了电,重新开机以后,说过保存成功的数据还在,这叫(durability)。

数据库里最常见的摆法是(table)。你平时说的「表格」,比如电子表格,格子里什么都能填;多数数据库里,数据表的每一(column)只放一类信息,比如菜名,并规定放文字还是数字;每一(row)是一条记录,比如一道菜谱。每一行还要有一个与别的行都不同、也不能空着的值,准确地指出是哪一行,叫(primary key)。菜谱表用编号作主键:两位作者可以各发一道番茄炒蛋,编号却不会重复。

整理成表:把第 1024 号菜谱的各项信息放进各列

先看这里先选一张卡片,再选它该放进哪一列,或者另起一张表。

第 1024 号菜谱的六项信息
放到哪里
菜谱表
编号菜名作者编号做法收藏数
1022红烧茄子5茄子切条煎软,加酱油焖熟26
1023清炒菠菜7蒜爆香,下菠菜大火快炒9
(空)(空)(空)(空)(空)

先选一张卡片。

作者编号指向没有画出来的用户表;表里只列出几行,内容是虚构的。

做法也有好几步,却放在一格里:它只整段读出来看,没有人按其中某一步去找,算一个值就行。配料不同,读者要按配料找菜:几种配料连成一段字塞进一格,只能逐段比对着找,又慢又容易找错;一格只放一个值,才好准确地查,也才能为它建普通的(下一页讲)。所以配料另起一张表,一种一行,每行都写着菜谱编号 1024。一道菜谱对应好几行配料,每行配料只属于一道菜谱,这叫(one-to-many)。菜谱编号在这里会重复,同一道菜又不会把一种配料写两次,所以两列合起来当主键。

配料表的菜谱编号存的是菜谱表里某一行的主键,叫(foreign key)。建表时写明这一列指向菜谱表,叫声明外键;声明了,写一个不存在的菜谱编号,数据库就会拒绝。像这样用几张表保存数据、表之间靠编号关联的数据库,叫(relational database)。

代价是什么

数据库是多出来的一个组件,要运行,也要照看;每次存取都要交给另一个程序去办,它在另一台机器上时还要经过网络,比服务器读自己内存里的数据慢得多。

本章只讲一台机器上的持久性:硬盘本身坏了,或者数据被人误删,要靠第 8 章讲的多存几份和备份。

资料来源

以下资料均于 2026-10-23 访问。

  1. Semiconductor glossary: DRAM三星半导体,未注明日期
  2. Virtual Address Space微软 Learn(Win32 文档),2018-05-31
  3. Terminating a Process微软 Learn(Win32 文档),2025-07-14
  4. Most Widely Deployed SQL Database EngineSQLite,2026-04-21
  5. 1.2. Architectural FundamentalsPostgreSQL 全球开发组(PostgreSQL 18.6 文档),未注明日期
  6. 19.5. Write Ahead LogPostgreSQL 全球开发组(PostgreSQL 18.6 文档),未注明日期
  7. InnoDB Startup Options and System VariablesOracle(MySQL 8.4 参考手册),未注明日期
  8. 28.1. ReliabilityPostgreSQL 全球开发组(PostgreSQL 18.6 文档),未注明日期
  9. Appendix M. GlossaryPostgreSQL 全球开发组(PostgreSQL 18.6 文档),未注明日期
  10. 2.2. ConceptsPostgreSQL 全球开发组(PostgreSQL 18.6 文档),未注明日期
  11. 5.5. ConstraintsPostgreSQL 全球开发组(PostgreSQL 18.6 文档),未注明日期
  12. Guide to table relationships微软支持,未注明日期
  13. 3.3. Foreign KeysPostgreSQL 全球开发组(PostgreSQL 18.6 文档),未注明日期
  14. SQLite Foreign Key SupportSQLite,2026-03-20