
很多人第一次接触数据库都会把它当成一门“语法课”来学背了一堆 SQL 关键字知道 SELECT 怎么写、JOIN 怎么写可真到了做课程设计、或者被面试官问到“为什么这个查询这么慢”“为什么两个事务会互相卡住”的时候一下子就懵了。我带过不少做课程设计和刚转行做开发的读者发现大家缺的往往不是某一个命令而是缺少一条能把数据库基础知识串起来的线数据放哪、怎么放、怎么查、多个人同时操作怎么不冲突、出了问题怎么救。这篇内容想按这条线把数据库相关的基础知识重新捋一遍。MySQL、Oracle、SQLite、达梦、人大金仓这些常见库都会涉及到也会带上热词里反复出现的数据库死锁、连接池、ER 图、数据迁移等实际问题。适合正在准备课程设计、数据库面试或者刚接触后端开发的人。内容尽量说人话能用例子讲清楚的绝不用空概念糊弄。1. 先搞明白数据库到底解决了什么问题1.1 数据库的本质是一套存取规则很多同学是从 Excel 开始理解数据的但表格和数据库之间隔着一道巨大的鸿沟。一个人用 Excel 做记录完全没问题但是当有十个人同时往同一张表里填数据有人改、有人删、有人查Excel 很快就会乱套——没有并发控制没有权限管理数据量大了以后查找也慢得让人崩溃。数据库做的事情本质上就是把“结构化数据的存储、检索、并发控制、一致性保障”打包成一套标准服务。你可以把它理解成一个高度规范化的仓库不是随便往里丢东西而是按照既定规则登记、摆放、检索。关系型数据库遵循关系模型用二维表组织数据行是一条记录列是一个字段表与表之间通过键建立关联。这个模型的厉害之处在于它让数据之间的关联变得可描述、可查询、可约束。所以学数据库先别急着背命令而是建立这个心智模型数据存在哪里、以什么结构存在、怎么把需要的数据高效取回来、并发场景下怎么保证不错不乱。后面所有知识点包括索引、事务、锁、死锁都是围绕这几个问题展开的。1.2 关系型与非关系型不是对立关系热词里能看到的数据库特别多MySQL、Oracle、SQLite、达梦、人大金仓、ClickHouse、Doris、时序数据库、向量数据库……如果按传统分类逻辑可以分成两大阵营。第一类是关系型数据库强调事务和一致性适合账务、订单、用户等核心业务数据。MySQL 开源免费普及率最高Oracle 在企业级市场深耕多年达梦、人大金仓这类国产数据库在语法和功能上对标 Oracle在政务、金融、能源等项目中越来越常见。第二类是非关系型数据库形态更自由Redis 做缓存、MongoDB 存文档、Elasticsearch 做搜索、ClickHouse 和 Doris 做分析、时序数据库处理监控指标、向量数据库服务 AI 知识库。但这些类型的边界正在变模糊很多数据库既能 OLTP 又能 OLAP也支持 JSON 等半结构化数据。选型的关键不是“谁火就用谁”而是看你面临的场景数据量大不大、并发高不高、是要频繁更新还是只读分析、能不能容忍小概率延迟。搞清楚场景再谈选型这才是数据库基础知识的正确打开方式。2. 关系型数据库的核心概念别绕开表、键、SQL 与事务2.1 主键、外键和索引关系型数据库的设计基本都围绕表展开。每张表要有主键主键用来唯一标识一行记录。这里有一个我反复强调的建议主键尽量别用业务字段比如身份证号、手机号、邮箱。原因是业务字段可能会变而且可能重复一旦当成主键会给后续修改带来很大的麻烦。更稳妥的做法是用自增整数 ID 或者 UUID 这类无业务含义的字段只承担标识职责。外键用来表达表与表之间的关系。比如博客系统文章表里有一个 author_id 指向用户表的 id这就是外键。外键能保证数据完整性但也不是越多越好——外键过多写入时需要检查关联表的合法性性能会受影响而且在高并发场景下容易造成锁竞争。实际开发中很多团队会选择在应用层维护关系数据库层面只建索引不加物理外键这是一种取舍。索引是提升查询效率的核心手段。它的底层结构通常是 B 树可以理解为给数据建了一本带目录的字典不用一页页翻。但索引不是越多越好因为每次写入、更新时索引也要同步维护索引多了写入会明显变慢。判断是否需要索引要看查询条件里的字段是不是经常出现在 WHERE、JOIN、ORDER BY 中。如果一张表只有几百行数据索引的意义其实不大全表扫描就够了。2.2 SQL 四类操作与分组选择数据SQL 最基础的就是四种操作也就是热词里反复出现的“增删改查”INSERT 插入数据DELETE 删除数据UPDATE 修改数据SELECT 查询数据。不要小看这四个操作绝大部分业务逻辑最终都落在这四类语句上。举一个课程设计里很常见的例子。假设有一个学生表 student字段包括 id、name、class_id、score。要查每个班级的平均分SQL 可以这样写SELECT class_id, AVG(score) AS avg_score FROM student GROUP BY class_id;这里 GROUP BY 就是“分组选择数据”的核心语法把同一班级的记录聚合在一起再用 AVG 求平均。如果还想过滤出平均分大于 80 的班级就要用 HAVING 而不是 WHERESELECT class_id, AVG(score) AS avg_score FROM student GROUP BY class_id HAVING AVG(score) 80;初学者最容易混的点就是 WHERE 和 HAVINGWHERE 是在分组之前过滤行HAVING 是在分组之后过滤分组。把 80 分这个条件写进 WHERE结果就完全不对了。还有一个高频坑是 JOIN。INNER JOIN 只返回两边都匹配的记录LEFT JOIN 会返回左表全部记录右表没有匹配就补 NULL。业务上统计“所有用户以及他们的订单数量”时必须用 LEFT JOIN否则没有订单的用户会被直接丢掉。2.3 事务 ACID 与隔离级别事务是关系型数据库和其他存储方案拉开差距的关键能力。拿转账举例A 给 B 转 100 块钱这涉及两条更新操作A 扣钱、B 加钱。如果第一条成功第二条失败钱就凭空消失了。事务把这组操作打包成一个原子单元要么全部成功要么全部失败。事务有四个特性简称 ACID原子性保证操作不可分割一致性保证数据从一种合法状态变到另一种合法状态隔离性保证并发事务互不干扰持久性保证提交后的数据不会丢失。理解 ACID 之后下一步就是隔离级别。SQL 标准定义了四种隔离级别隔离级别脏读不可重复读幻读读未提交可能可能可能读已提交不可能可能可能可重复读不可能不可能可能串行化不可能不可能不可能MySQL 默认是可重复读Oracle 默认是读已提交。MySQL 选可重复读一个重要原因是它的主从复制在 statement 模式下可重复读能保证从库复制的数据一致性Oracle 则更强调并发性能读已提交在大多数业务场景下已经够用。理解隔离级别很多面试连环题都能解开。3. 数据库选型遇到具体场景怎么挑库3.1 嵌入式场景SQLite 和本地数据库热词里有一类很显眼“linux下的单文件数据库”“flutter 内嵌数据库”“flet datatable 数据库”。这些场景背后大概率都是同一个库SQLite。SQLite 是一个嵌入式关系型数据库整个数据库就是一个文件零配置、跨平台、API 简单非常适合桌面工具、移动端 App、本地缓存、IoT 设备等场景。Flutter 做本地存储时常用的 sqflite 插件底层就是 SQLite用 Python 写桌面小工具配 flet也可以用 SQLite 存数据启动快、迁移方便。我自己写一些脚本工具和数据分析预处理时也经常顺手开一个 SQLite比维护一个 MySQL 实例省心太多。但 SQLite 的适用边界也很明显它擅长单机读写不擅长高并发写入。多个进程同时写同一个库文件时会出现“database is locked”的报错。如果做 Flutter 本地数据库加后端同步通常的架构是本地用 SQLite 做缓存和离线读写联网后把增量数据同步到 MySQL 或 PostgreSQL 这类服务端数据库。这个“本地嵌入 服务端主库”的组合是很多 App 的标准做法。3.2 服务端关系型MySQL、Oracle 和国产数据库服务端场景最常见的依然是 MySQL。它开源、社区活跃、资料多中小型项目和互联网业务占据绝对主流。MySQL 安装不算复杂但有几个细节容易翻车字符集要选 utf8mb4不然 emoji 和生僻字会变问号时区最好设置成明确的时区而不是默认的 SYSTEM否则 Java 连接池连上以后容易出现时间差 8 小时的问题。Oracle 在企业级场景中依然大量存在热词里“oracle数据库安装教程”“pl/sql developer如何连接局域网其他机器的oracle数据库”“oracle数据库修改结构”能看出新人接触 Oracle 时的常见痛点。Oracle 的体系比 MySQL 复杂实例、表空间、用户之间的关系需要时间消化。个人学习建议装 Oracle XE 版本内存占用小功能对学习来说足够。国产数据库这几年热度很高达梦、人大金仓、瀚高在项目里越来越常见。达梦的语法和 Oracle 高度兼容很多从 Oracle 迁移过来的 SQL 几乎不用改人大金仓基于 PostgreSQL 内核提供 MySQL 和 Oracle 兼容模式。热词里“nacos使用达梦数据库”“flowable 6.7.2 适配达梦数据库”“瀚高数据库切换mysql模式”都属于国产化适配的范畴。我的经验是把 MySQL 或 PostgreSQL 的基础打牢遇到达梦、人大金仓时先查官方兼容性文档大部分时候是能平滑迁移的真正费时间的往往不是语法而是驱动配置和特殊函数差异。3.3 OLAP 与时序场景ClickHouse、Doris 与时序数据库OLTP 和 OLAP 是两个经常听到的词。OLTP 是联机事务处理对应日常业务系统特点是大量小事务、频繁增删改查OLAP 是联机分析处理对应报表、数据仓库特点是数据量大、以只读查询为主、聚合计算多。MySQL 和 Oracle 主要承担 OLTP而 ClickHouse、Doris 这类属于 OLAP 分析型数据库。ClickHouse 是列式存储数据库在大宽表、海量数据的聚合分析上性能极其突出。很多团队把日志、埋点、业务明细数据导入 ClickHouse做实时报表和多维分析。但 ClickHouse 也有脾气不适合高频单行更新复杂 JOIN 的能力相对弱。Doris 是另一款分析型数据库适合大规模数据集上的实时查询在互联网公司里用得很多。热词里“dolphinscheduler 数据库数据抽取”正好对应数据进入分析型系统之前的管道环节通过 DolphinScheduler 这类调度工具定时从业务库抽数清洗后写入 ClickHouse 或 Doris。时序数据库则是另一条赛道典型产品有 InfluxDB、TDengine、IoTDB专门处理监控指标、传感器数据这类带时间戳、写入频繁、按时间范围查询的数据。选型时别拿 MySQL 硬扛千万级监控点位时序数据库的压缩和聚合能力是通用关系库比不了的。3.4 向量数据库与 AI 知识库热词里有一条很有意思“ai智能体的企业知识库是存放在向量数据库中的吗”。答案是很多 AI 知识库确实会用到向量数据库但不代表所有知识库都必须用。向量数据库存的是向量也就是把文本、图片等内容经过嵌入模型转换成的一组浮点数。查询的时候它不是做精确匹配而是通过余弦相似度或欧氏距离找出最相似的向量实现语义检索。AI 智能体做 RAG检索增强生成时会把企业文档切块、向量化后存进向量数据库用户提问时先向量检索出相关片段再把片段交给大模型生成回答这样能显著减少幻觉。常见的向量库有 Milvus、Qdrant、Weaviate还有一些关系型数据库也内置了向量检索能力。但要注意向量数据库解决的是非结构化数据的语义检索问题它替代不了关系型数据库在事务、账务、权限上的能力。一个完整的企业应用通常是关系型数据库做主数据存储向量数据库做知识库检索两者配合而不是互斥。4. 日常开发里最高频的库操作与工具4.1 从安装到建库建表的通用流程热词里“mysql数据库安装”“达梦数据库”“oracle数据库安装”占了很大比例。安装本身不算难但安装完之后的初始配置才是区分新手和老手的地方。以 MySQL 为例安装完成后第一步是确认字符集和排序规则建议统一 utf8mb4 / utf8mb4_unicode_ci。然后创建业务专用账号而不是一直用 root权限按最小化原则给比如只给某个库的 SELECT、INSERT、UPDATE、DELETE 权限。很多安全问题是 root 裸奔造成的。启动服务后用命令行或客户端工具连接先跑一句 SELECT VERSION() 确认连通性再开始建库。达梦数据库的安装路径和 MySQL 类似但有几个特有概念。默认端口是 5236管理工具是 DM 管理工具初始化实例时会要求设置数据库名、实例名、端口。连接达梦时驱动包要选对版本Java 项目还需要把 DmJdbcDriver 放进依赖。Oracle 安装相对重个人学习建议装 XE 版本注意监听配置和 tnsnames.ora否则客户端连不上。不管装哪种数据库建完库第一时间把备份策略想好这永远是第一步不是最后一步。4.2 连接池为什么不能每次请求都连一次库“mysql的数据库连接池”是热词里很经典的一条。很多初学者写代码时会写每次执行 SQL新建一个连接执行完再关闭。这个写法在小项目里没问题但并发一上来就崩。建立数据库连接是一个比较重的操作涉及 TCP 握手、认证、分配资源一次可能要几十甚至上百毫秒。如果每个请求都经历一遍数据库和应用的 CPU 都耗在建立连接上了。连接池的思路是提前创建一批连接放着应用需要时从池里借用完归还不够时再按需扩充。常见的连接池有 HikariCP、Druid、dbcp2。关键参数包括 initialSize 初始连接数、maxActive 最大连接数、maxWait 获取连接的超时时间。maxActive 设置太小高并发时请求会排队等待设置太大数据库自身连接数可能被打爆。我一般建议先压测再调参而不是照抄网上的配置。曾经接手过一个项目连接池最大连接数配到了 200数据库实例 max_connections 只有 150高峰期直接把库打挂了这就是典型的参数不匹配。4.3 建表脚本、数据导入与常用工具日常开发少不了一组顺手的数据库工具。热词里“idea导出数据库脚本”很常用IDEA 的 Database 面板可以反向查看表结构右键导出 DDL 脚本适合做版本管理和给同事 review。“dbx数据库工具”也有不少人用界面友好适合快速查询和导出数据。Navicat 和 DBeaver 是更常见的通用客户端前者商业后者开源免费功能都不弱。“excel导入数据库”是另一个高频需求。小数据量直接用 Navicat 或 DBeaver 的导入向导选择 Excel 文件映射字段生成 INSERT 语句几分钟搞定。但导入前要先检查 Excel 里的列名、类型和空值情况否则经常出现日期格式错乱、数字变成科学计数法的尴尬。大数据量导入建议先导出 CSV再用 LOAD DATA 或 COPY 这类批量导入工具比逐条 INSERT 快几个数量级。热词里提到的“北风数据库”是很多教程里的经典练习库适合拿来练 SQL无论是查订单还是做统计数据粒度都比较合适。5. 设计、面试与并发数据库的“进阶基础”5.1 课程设计/毕业论文ER 图怎么画热词里有“我成考毕业设计论文数据库er图用哪种方法”“数据库设计 - 博客系统”。做课程设计或写毕业论文ER 图几乎是绕不开的环节。ER 图的核心是三个要素实体、属性、联系。实体是业务里的对象比如博客系统里的“用户”“文章”“评论”属性是实体的特征联系是实体之间的关系比如用户和文章是一对多文章和标签是多对多。画 ER 图的方法按成本从低到高排序。第一是手绘或者用 draw.io、ProcessOn 这类在线工具拖拽实体框连线表示关系适合快速梳理思路。第二是用 Visio 或 PowerPoint 画得更精致一些商业软件功能全适合毕业论文。第三是直接用工具反向生成比如 PowerDesigner可以基于现有数据库自动生成 ER 图也可以画完图直接生成建表 SQL适合项目比较正式的场景。我的建议是无论用什么工具画图之前先把业务规则说清楚——一篇博客能不能有多个作者删掉用户后文章是保留还是删除这些规则不明确图画到一半必然卡壳。从 ER 图到物理表是有固定套路的每个实体落成一张表一对多关系通过外键表达多对多关系要拆成一张中间表。比如博客系统的“文章”和“标签”是多对多就需要 post_tag 中间表里面至少有三个字段id、post_id、tag_id。很多同学一上来就建表建到一半发现关系理不清回头再补中间表这种返工完全可以靠先画 ER 图避免。5.2 死锁和并发锁为什么两条 SQL 会互相卡住“数据库死锁”“数据库并发锁”是面试和实际运维里的常客。要理解死锁先理解锁。数据库在并发操作时会加锁最基础的是共享锁和排他锁。读操作加共享锁S 锁多个读可以同时拿到写操作加排他锁X 锁拿到排他锁期间其他事务既不能读也不能写。死锁发生的经典场景是事务 A 先锁了表 1 的一行想再锁表 2 的一行同时事务 B 先锁了表 2 的那一行想再锁表 1 的那一行。两边都拿着对方想要的资源谁也不让于是卡死。这就是死锁的“循环等待”。解决死锁有几个常用思路一是要求所有事务按照相同的顺序访问资源比如先操作表 1 再操作表 2而不是相反二是设置锁等待超时时间让等待方主动放弃三是合理设置隔离级别降低锁的粒度四是在代码层面减少长事务事务里尽量不要做远程调用、批量计算这类耗时操作。MySQL 检测到死锁后会自动回滚其中一个事务应用层要做的事务是捕获死锁异常做重试或者提示用户稍后再试而不是什么都不做干等。5.3 高频面试题和复习路线热词里“数据库面试题”占比很高说明这是求职的硬骨头。我的经验是数据库面试题看起来又多又散但翻来覆去就那么几大类。第一是索引B 树为什么适合做索引聚簇索引和非聚簇索引的区别组合索引的最左前缀原则。第二是 SQL 优化用 EXPLAIN 看执行计划关注 type 字段有没有走全表扫描、key 字段有没有命中索引、Extra 里有没有 filesort 或 temporary。第三是事务与锁ACID、隔离级别、MVCC、死锁。第四是架构问题读写分离、分库分表、主从复制。第五是扩展问题数据库和缓存的最终一致性怎么保证。复习时不要只背结论要能拿一个实际例子讲清楚。比如“mysql设置唯一已经有重复数据库”这条热词背后其实是给表加唯一索引时表里已经存在重复数据导致 ALTER TABLE 失败。解决办法是先查重、清理或合并重复记录再加唯一索引。这种问题面试官很喜欢问因为它既考 SQL 基础又考数据治理意识。6. 运维与排障实录装不上、连不上、报错怎么办6.1 安装和连接类故障排查速查表热词里有好几条是典型的报错类问题我把这些常见场景整理成一张表。这张表的内容基于实用主义适合当作排查手册。现象常见原因解决方向borland database engine数据库无法初始化BDE 配置损坏或缺少别名检查 BDE Administrator 配置重建数据库别名确认路径权限multisim访问数据库发生错误数据库服务未启动或连接字符串被修改确认对应数据库服务和 ODBC 数据源检查软件配置中的连接参数pl/sql developer无法连接局域网其他机器的oracle监听服务未开、tnsnames.ora 配置错误、防火墙拦截在服务器端启动监听客户端配置好主机名和端口测试 tnspingdocker内部iserver连接达梦数据库容器网络不通、驱动未安装、连接地址写错使用 host 网络或正确映射端口确认驱动和 JDBC URL 格式mysql设置唯一约束但已有重复数据表内已存在重复记录加索引失败先查重清理再添加唯一索引超出最大数据库坐标值字段精度或长度不足以承载导入的数据检查字段类型扩大精度或改用更合适的类型遇到连接类问题我的排查顺序永远是先确认服务真的在跑再确认端口可达然后确认账号密码和权限最后才去查客户端工具配置。很多人一上来就改配置文件折腾半天发现数据库服务根本没启动这个顺序搞反了。6.2 数据库迁移的几个实用套路热词里“clickhouse数据库整体迁移”“mysql数据库整体迁移”“达梦数据库”“瀚高数据库切换mysql模式”指向同一个大主题数据库迁移。迁移最核心的原则是先备份再迁移最后对账。通用流程分五步。第一步梳理源库的库表结构、存储过程、触发器、定时任务形成清单。第二步选择迁移方式小数据量可以直接导出 SQL 再导入大数据量用官方迁移工具或数据同步组件同构数据库可以用物理备份恢复速度最快。第三步在目标库建好库和表结构注意字符集、排序规则、自增主键初始值这些容易被忽略的差异。第四步迁移数据跑完后做数据对比抽样核对行数和关键字段。第五步切换前把应用连接串切到新库观察一段时间确认无异常再把旧库下线。跨数据库类型迁移比如从 Oracle 迁移到达梦或者从 MySQL 模式切换到瀚高最大的坑往往是 SQL 方言差异。日期函数、分页写法、字符串拼接、空值处理都有可能不一样。热词里“flowable 6.7.2 适配达梦数据库”这类问题本质就是工作流引擎生成的 SQL 要在达梦上平滑执行这需要驱动兼容、语法适配和回归测试三层配合。不要指望一把梭迁移前先拿业务最核心的 100 条 SQL 跑一遍兼容性测试能省大量返工。6.3 数据导入导出中的“小坑”热词里有一条“超出最大数据库坐标值。此错误的一个可能原因是dxf导入时使用的单位与其导出时的单位不匹配”看起来和数据库关系不大但这类问题的排查思路和数据库非常像报错的信息只是一个结果真正的原因往往在数据源头。在数据库导入导出中类似的坑有几个。字段长度不够是最常见的Excel 里一段 200 个字的备注导入到 VARCHAR(100) 的字段直接报错。解决方法是导入前检查目标表结构或者对超长内容做截断处理。精度问题也一样坐标、金额这类数值如果字段声明成 INTEGER导入带小数点的数据可能直接四舍五入或被拒。日期格式混乱也是高频问题Excel 里日期显示是 2024-01-05实际存的是 45266 这种序列号直接导入数据库就变成一串数字。解决这类问题的关键是在导入前先对源数据做一次“体检”把类型、长度、空值、格式都看清楚再建表导数据。不要让数据库去迁就数据而是让数据先适配数据库的约束。7. 几条踩过坑才总结出来的实操习惯7.1 写 SQL 前先想清楚数据模型我见过太多项目数据库表结构是写到哪算哪今天加一个字段明天改一个类型最后表里的字段含义只有写代码的人自己能看懂。好的习惯是先画 ER 图、列出核心查询语句清单再落建表 SQL。改表结构要趁早数据量小的时候怎么改都行数据量大了以后一个 ALTER TABLE 在千万级表上可能要锁表很久业务会被拖死。7.2 备份和可回滚永远是第一位无论是做迁移、改结构还是批量更新数据执行之前先备份。哪怕只是更新一张表也可以先 SELECT 出要改的记录导出成一份备份文件再执行 UPDATE。这个习惯成本极低但能救命无数次。删数据的时候尤其要小心我吃过没加 WHERE 直接 UPDATE 全表的亏那一瞬间的感觉至今记得。7.3 把“问题题”变成“排查路径”学了数据库基础知识之后最重要的是形成排查路径。连接不上按服务、端口、账号、权限、客户端配置逐层排查查询慢用 EXPLAIN 看执行计划从扫描行数、命中索引、排序方式定位瓶颈报错看不懂把错误信息里的库名、表名、字段名摘出来去查对应版本的官方文档。数据库是一门非常依赖实操的学科出了问题别怕踩过一次坑对这个系统的理解就会深一层。我的体会是数据库基础知识的真正价值不在于记住多少命令而在于建立对数据存储、读取和一致性的完整直觉。把这个直觉建立起来后面不管是学新数据库、做性能优化还是面试都会顺很多。