数据库实验中摸索数据表设计的窍门和查询效率提升那些事儿
- 问答
- 2025-12-27 21:55:01
- 6
主要参考了知乎专栏“后端技术漫谈”中《我的数据库优化入门之路》系列文章、CSDN博客“一个程序员的成长笔记”关于数据库设计的经验总结,以及《SQL反模式》一书中的部分核心观点)
数据库实验,说白了就是自己动手搭积木,但搭的不是木头块,而是数据表和各种查询语句,刚开始的时候,我脑子里想的都是“怎么把数据存进去”,结果往往是一团糟,后来才明白,设计表结构这事儿,就像给家里的东西分类收纳,方法不对,以后找什么都费劲。
先别急着建表,拿张纸画画
这是我踩过最大的坑,以前一拿到实验要求,比如要做一个“图书管理系统”,立马打开软件,咔咔就创建了books表,里面有书名、作者、出版社、ISBN号……感觉挺全了,但等到要记录“借阅记录”时,就傻眼了,是把借阅人、借阅日期也塞进books表里吗?那同一本书被借阅第二次、第三次,岂不是要重复记录这本书的所有信息?数据冗余得吓人,而且如果书的信息要修改(比如出版社改名),得改好多条记录,容易出错。
后来学乖了,动手之前先画“实体关系图”(听起来高级,其实就是画圈圈和连线),先圈出几个核心的“东西”:图书、用户、借阅记录,然后想清楚它们之间的关系:一个用户可以有多条借阅记录,但一条借阅记录只属于一个用户;一本书可以有多条借阅记录(在不同时间),但一条借阅记录只对应一本书,这样一想,表结构就清晰了:books表只管书本身的信息;users表管用户信息;中间再建一个borrow_records表,这个表里不需要存书的详细名字或者用户的真实姓名,只需要存书的ID和用户的ID,再加上借阅日期、应还日期就行了,这就是所谓的“规范化”设计,核心思想就是让每个数据只在一个地方存储,避免重复和混乱,参考《SQL反模式》里的说法,这种把多种信息塞进一个表的做法叫“乱穿马路”,非常危险。
给数据表设个“身份证”,事半功倍
上面提到的ID,就是每个表的“身份证”,学名叫主键,这个东西太重要了,千万不要用身份证号、学号这种有业务意义的字段当主键,哪怕它看起来是唯一的,因为业务规则可能会变,比如学号升位了,那你所有关联的表都得跟着改,麻烦大了,最好就是用数据库自己生成的、毫无意义的数字(比如自增ID)或者UUID来当主键,它唯一的作用就是唯一标识这一行数据,稳定可靠,在borrow_records这样的关联表里,存放的就是对方表的这个“身份证”(外键),通过这个ID就能准确地找到对应的书或用户,实验时养成这个习惯,后面做复杂查询时会发现世界都清净了。

查询慢?想想你是怎么“找东西”的
表设计好了,数据也灌进去了,接下来就是查询,查询效率是另一个重灾区,举个例子,你要在几十万本书里找所有“清华大学出版社”出版的书,如果你的查询语句是SELECT * FROM books WHERE publisher = '清华大学出版社',然后发现执行起来慢吞吞,问题出在哪?
问题就在于,数据库就像一间没有目录的巨大仓库,它要执行这个查询,就得派一个人(数据库引擎)从第一本书开始,一本一本地翻看出版社信息,这叫“全表扫描”,数据量小的时候没感觉,数据一多,自然就慢了。
解决办法就是建“索引”,索引就像给这本书仓库做了一个详细的目录卡片,你可以在publisher这个字段上建立一个索引,这样当数据库再执行同样的查询时,它就不用傻乎乎地遍历整个仓库了,而是直接去索引目录里查“清华大学出版社”这个标签,目录会直接告诉它哪些书符合条件,它直接去拿就行了,速度飞快,这就像查字典用拼音检索和一页一页翻的区别。

索引不是建得越多越好,每建一个索引,就像多维护一份目录,当你要往表里新增、删除或修改数据时,数据库不仅要动数据本身,还得更新所有相关的索引,这会降低写入速度,索引要用在刀刃上,通常给那些经常出现在WHERE条件、JOIN条件或者ORDER BY排序里的字段建索引,效果最明显,知乎专栏“后端技术漫谈”里打了个比方:索引就像书的索引,不是每本书都需要,但对于经常要查阅的专业书籍,索引必不可少。
别让数据库干太多的“体力活”
写查询语句也有窍门,我们一个查询想得到所有信息,就习惯性地写SELECT *,但很多时候,我们可能只需要书名和作者两个字段,如果表里有几十个字段,SELECT *会让数据库把一整行数据,包括你不需要的那些大段文本(比如图书简介)都搬出来,这无疑是浪费资源,明确写出你需要的字段名,比如SELECT title, author FROM books,能减轻数据库的负担,尤其是在网络传输时,数据量小速度也快。
还有,尽量减少在查询条件里对字段进行计算或者使用函数,想找去年今天借出的书,不要写WHERE borrow_date = DATE_SUB(NOW(), INTERVAL 1 YEAR),因为数据库没法利用borrow_date字段上的索引了,它得对每一行的这个日期都计算一下,再看结果是否符合,更好的做法是在程序里先算好那个日期值,然后直接查询WHERE borrow_date = '某个具体日期',CSDN博客“一个程序员的成长笔记”里强调,要尽量让查询条件的一边是“干净”的字段。
总结一下
在数据库实验中,摸索出的窍门归根结底是两种思维:一是设计阶段的“规划思维”,花时间做好表结构设计,理清关系,用好主外键,这是打好地基;二是查询阶段的“效率思维”,时刻想着如何减少数据库的无效工作,善用索引,优化语句,这些东西光看理论记不住,一定要在一次次失败的实验和缓慢的查询结果中,亲自体验、对比、调整,才能真正变成自己的本事,当你能预见到某种设计或写法可能带来的问题时,就算真正入门了。
本文由革姣丽于2025-12-27发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/69651.html
