
1. 内容整体设计与思路拆解1.1 这份数据库笔记到底在记什么干数据库这块十几年我最大的感受就是这行的知识边界宽得吓人。从大学课程里的SQL增删改查到生产环境里的死锁排查、主从同步、连接池调优再到这两年冒出来的向量数据库每一样都能让人折腾好一阵子。最近整理自己电脑里的数据库笔记发现光是标题就攒了几百条从“数据库基础知识”到“达梦数据库安装”从“Navicat连接达梦数据库”到“数据库并发锁”跨度大得不像同一个行业的产物。但仔细梳理之后这些散落的笔记其实能串成一条清晰的学习主线概念是地基工具是手脚踩坑是日常面试是检验。这份“数据库笔记”不是某一本教材的读书笔记而是一个从业者在实际项目里摸爬滚打后留下的经验沉淀。它涵盖了数据库领域的核心概念、常用工具、运维实战和面试准备四个维度几乎每个方向都能对应到生产环境中真实发生过的问题。比如数据库死锁教科书上讲的是四个必要条件但现实里你碰到的可能是两个事务互相等对方释放行锁把一张订单表卡得死死的。比如数据库连接池文档上写的是“复用连接、减少开销”但线上真实情况可能是连接池被打满、Tomcat报错连不上数据库业务直接雪崩。这份笔记适合谁看如果你刚入行正在学数据库基础知识准备数据库课程设计或者即将去面试数据库岗位那笔记里关于关系型数据库原理、常用工具操作、面试题整理的部分可以直接抄作业。如果你已经工作了两三年正在负责某个系统的数据库维护那笔记里关于死锁排查、同步工具选型、达梦人大金仓这类国产数据库部署的内容能帮你少走不少弯路。说白了这份笔记既是一本入门指南也是一份排障手册更是一套面试题库。1.2 一份靠谱的数据库笔记应该怎么组织我整理笔记时坚持一个原则按问题组织而不是按产品组织。很多人写笔记习惯用“MySQL教程”“Oracle教程”这种思路但我发现按产品写容易把知识孤立起来换个数据库就抓瞎。按问题组织就灵活得多比如“数据库连接池怎么配”“数据库同步怎么做”“死锁怎么排查”不管你用的是MySQL还是达梦还是人大金仓遇到同样的问题都能立刻找到对应的思路。所以这份笔记的正文部分我分成了四大块概念梳理、工具实操、踩坑实录、面试冲刺。概念梳理讲的是关系型数据库、向量数据库、国产数据库这些底层的东西让你知道每个选型背后是什么逻辑。工具实操讲的是Navicat、dbx、同步工具、连接池这些实际干活时离不开的东西每一款都给出操作步骤和参数选择。踩坑实录就是真实生产环境的复盘从死锁到先写数据库还是先写MQ每一个坑都是花了代价才填平的。面试冲刺则是把这些年攒下的常见面试题和回答思路做个沉淀帮你在关键时刻不卡壳。这种组织方式最大的好处是查起来快用起来顺手。你不需要把几千页文档全背下来只要脑子里有这张问题地图遇到什么情况知道去哪一节翻就已经比大多数同行强了。2. 核心概念梳理从关系型到向量数据库2.1 关系型数据库的底层逻辑关系型数据库到现在依然是绝对的主流MySQL、Oracle、SQL Server、PostgreSQL这些名字大家都不陌生。关系型数据库的核心就是“关系”二字用二维表来存数据表跟表之间通过主键外键建立关联。你大学里学的数据库基础知识什么实体完整性、参照完整性、三范式都是在讲怎么把这个世界抽象成一张张表。但概念归概念实际用的时候很多人会犯一个毛病动不动就设计出一堆表连个用户地址都恨不得拆成省、市、区三张表。我在实际项目里见过最离谱的设计是一张业务表关联了二十多张从表每次查询都是七表连查慢得让人想砸电脑。三范式是理论指导不是死板教条互联网业务特别是高并发场景下适当的冗余反而能换来查询性能的提升。这就是为什么你会看到很多大厂做数据库设计时故意“反范式”在表里冗余一些常用字段减少JOIN次数。关系型数据库的ACID特性是它的立身之本。原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability这四个属性保证了银行转账这类业务不会出错。举个最直白的例子你从A账户转100块到B账户扣款和加款这两个操作必须同时成功或者同时失败绝不能出现A扣了钱B没收到的情况这就是原子性。实际工程里事务隔离级别读未提交、读已提交、可重复读、串行化影响着并发场景下的数据行为MySQL默认的RR可重复读级别解决了大部分问题但如果你不理解MVCC多版本并发控制的原理碰到幻读问题的时候就会一头雾水。2.2 向量数据库为什么会火起来这几年向量数据库的热度一路飙升很多以前只跟MySQL打交道的人也开始问“向量数据库到底是个啥”。简单说传统数据库存的是结构化的行数据而向量数据库存的是向量——就是一堆浮点数组成的数组。这个东西在大模型时代特别有用因为不管是文本、图片还是音频都可以通过嵌入模型Embedding Model转成一个向量然后靠向量之间的相似度计算来实现语义搜索。打个比方你就懂了传统数据库像是图书馆里按分类编号摆放的书架你得知道书在哪个分类下面才能找到。向量数据库则像一个熟记所有书内容的图书管理员你只要描述一句“我想找一本讲怎么种番茄的书”他就能凭语义理解帮你把相关的书都抱过来哪怕这些书的标题里根本没有“番茄”两个字。这里背后的技术是近似最近邻搜索ANN常用的算法包括HNSW、IVF等它们通过空间切分和索引结构在海量向量里快速找到“最相似的TopK”。实际工程中向量数据库的典型搭档是文本向量化加RAG检索增强生成。比如做一个企业知识库问答系统先把文档切片、向量化存储到Milvus或者Chroma里用户提问时把问题也转成向量去向量库里检索最相关的文档片段再把片段丢给大模型生成回答。原生的pgvector是在PostgreSQL里加了向量类型和索引支持这样你就不需要额外部署一套数据库数据同步和事务处理都能沿用原有的生态。选型的时候如果向量量级在百万以内、团队不想维护额外组件pgvector很香如果量级上千万甚至过亿对查询时延要求又高那独立部署Milvus这类专用向量库会是更靠谱的选择。2.3 国产数据库和开源数据库怎么选国产数据库这两年是绕不开的话题。达梦数据库、人大金仓KingbaseES、GBase这几个名字频繁出现在各种项目里尤其是信创环境下很多银行政务项目要求必须跑在国产数据库上。达梦数据库的SQL语法高度兼容Oracle如果你以前写过Oracle的PL/SQL上手达梦会非常快。它的安装和配置流程我后面实操部分会详细讲。人大金仓则更多兼容PostgreSQL语法甚至直接支持PostgreSQL的不少扩展。GBase偏向分析型场景在数据仓库领域有它的位置。开源数据库这边MySQL和PostgreSQL是开源数据库里的双子星。MySQL胜在生态成熟、运维资料多、绝大多数业务系统跑它都没问题但分区表、并行查询这些高级功能相对薄弱。PostgreSQL功能更全面内置JSON、数组、GIS等丰富类型对复杂查询的支持也更强这几年在中后台系统、GIS应用里越来越受欢迎。SQLite则是一个极致的轻量方案单文件数据库一个文件就是整个库不需要安装服务端移动端App、嵌入式设备、小工具项目里大量使用。Linux服务器上如果你只想快速存点配置数据sqlite3命令一条条敲下去比装个MySQL省太多事。选型没有绝对的对错关键在于看场景。如果你做一个日活百万的互联网应用MySQL或者PostgreSQL搭配合理的缓存设计是主流选择。如果你做的是银行核心交易系统那达梦、Oracle这类对事务和稳定性打磨更深的产品更合适。如果你只是给内部工具加个存储SQLite单文件就能解决。我见过不少团队盲目跟风上了分布式数据库结果业务量根本到不了需要分库分表的程度反而把简单的查询搞得很复杂这就是选型时没想清楚场景的代价。3. 常用工具与实操从数据库连接到同步方案3.1 Navicat连接达梦数据库的完整流程达梦数据库的安装部署有一定的门槛但连接它其实很简单。Navicat从16版本开始原生支持达梦数据库如果你用的还是老版本也不用担心选择“其他数据库”里的“达梦”或者用ODBC方式也能连上。这里我把最稳的一版操作步骤写给你。第一步在达梦服务器上确认数据库实例已经启动默认端口是5236。第二步打开Navicat点击“连接”按钮选择“达梦数据库”。第三步填写连接参数主机填达梦服务器的IP端口填5236用户名默认SYSDBA密码是安装时设置的。第四步点击“测试连接”如果提示成功就保存连接之后就可以像操作MySQL一样查看库表、执行SQL了。这里有个常见坑Navicat连接达梦时会提示需要安装达梦的ODBC驱动这时候你需要到达梦官网下载对应版本的ODBC驱动安装完重启Navicat再试。Windows系统下安装ODBC驱动后还要去“ODBC数据源管理器”里确认驱动名称能正常出现在列表中。如果连不上先别急着换工具按这个顺序排查服务器防火墙有没有放行5236端口达梦服务是否正常监听客户端和服务器之间的网络能不能ping通账号密码是不是正确。我实际处理过的一个案例是开发反馈Navicat连接达梦报“初始化DMS失败”最后查下来是远程机器上没有配置达梦的环境变量把DMS_HOME配置好才解决。3.2 人大金仓的Docker部署与连接人大金仓KingbaseES跑在Docker里是现在很多团队采用的部署方式省去了繁琐的安装向导一条命令就能拉起来。基本的运行命令长这样docker run -d \ --name kingbase \ -p 54321:54321 \ -v /data/kingbase:/home/kingbase/data \ -e DB_USERsystem \ -e DB_PASSWORD123456 \ registry.cn-hangzhou.aliyuncs.com/kingbase/kinger:latest注意端口映射金仓默认端口是54321和PostgreSQL的5432不一样。挂载卷这步很重要把容器里的数据目录映射到宿主机否则容器一删数据全没了这种低级错误我见过不止一次。启动后你可以用金仓自带的ksql命令行工具连接ksql -U system -d TEST -p 54321 -h 127.0.0.1这里的-U是用户名-d是数据库名TEST是金仓默认创建的测试库。如果开发语言是PHP需要访问金仓数据库那就要用qsqldatabase相关的驱动配置确认PHP的pdo_pgsql扩展已启用因为金仓兼容PostgreSQL的通信协议JDBC和ODBC驱动也都有对应的版本。金仓数据库的备份恢复用自带工具就行sys_backup.sh脚本做物理备份逻辑备份用ksql里的dump命令。Docker容器里执行备份命令时注意路径映射备份文件最好写到挂载卷里这样宿主机直接就能拿到。3.3 数据库同步工具到底怎么选数据库同步是分布式架构里绕不开的话题。业务量上来之后一个库扛不住了读写分离把读流量分流到从库这就涉及主从复制。更进一步不同业务系统之间需要共享数据比如订单数据要同步到数仓做分析那就要用专业的同步工具。市面上的数据库同步工具五花八门但思路无非下面几条。Canal是阿里巴巴开源的工具专门解析MySQL的binlog日志然后把自己伪装成从库把变更数据发给下游。它适合MySQL之间的实时同步也适合把MySQL数据实时同步到消息队列或者ES。Debezium类似但它是基于Kafka Connect架构的对PostgreSQL、SQL Server、MongoDB的兼容性更好。如果你需要全量和增量同步都做DataX是个老牌选择它擅长各种异构数据源之间的批量同步比如把Oracle的表一次性搬到MySQL里全量搬运非常稳。如果两家数据库之间不想引入额外组件最简单的方案是中间件双写在应用代码里同时写两个数据源。比如先写数据库、再写消息队列下游消费消息后写入目标库。但双写会带来一致性问题这个我在下一节会详细讲。还有一个常见场景是从线上库同步数据到分析库你可以直接用数据库自带的复制功能比如MySQL组复制、Oracle DataGuard这些就不用额外写代码了。选同步工具的标准是实时性要求多高数据量多大源和目标库是什么类型。轻量任务用DataX全量搬一次就完事。实时性要求高就得Canal加Kafka那套组合。数据一致性要求极高甚至要考虑分布式事务方案那就不要自己拼工具了直接用现成的数据同步中间件再加补偿机制。3.4 数据库连接池的核心参数与配置建议讲到数据库连接池很多人以为就是框架里填几个数字其实远没那么简单。连接池存在的意义是解决“频繁建立数据库连接开销太大”的问题。一次TCP握手加MySQL认证大概要几十毫秒高并发下如果每个请求都现建立连接数据库会被拖垮。连接池复用已建立的连接能大幅降低延迟和资源消耗。以Java后端最常用的HikariCP为例几个核心参数你一定要理解透。maximumPoolSize是连接池里最大连接数minimumIdle是最小空闲连接数connectionTimeout是等待获取连接的超时时间maxLifetime是连接的最大存活时间。很多团队把maximumPoolSize配成几百以为越大越好实际上连接数跟数据库CPU核数和磁盘IO能力强相关。PostgreSQL官方对连接数的经验公式是连接数(核数×2)有效磁盘数。简单业务场景下一个4核8G的MySQL实例HikariCP的maximumPoolSize配20到30就完全够用了配成200反而会让数据库线程切换频繁吞吐量下降。连接池还有几个坑值得注意。第一个是maxLifetime要小于数据库的wait_timeout否则连接会被数据库服务端主动断开而连接池还傻傻地拿失效连接给应用用报“Connection is not available”这种错。第二个是连接池预热系统刚启动时连接池是空的第一个请求要等待建连所以可以在应用启动后做一次简单的SELECT 1预热。第三个是连接池泄漏应用代码里拿到连接后忘记归还连接池被慢慢耗尽这是最常见的线上故障之一排查手段是通过HikariCP自带的泄漏检测参数leakDetectionThreshold设置成比如60000毫秒有连接超过60秒没归还就打印告警日志。4. 高频踩坑实录死锁、双写和让人抓狂的报错4.1 数据库死锁的排查思路和真实案例数据库死锁这个问题只要你的系统并发上来早晚会碰见。死锁发生的原理用一句话概括两个或多个事务各自持有资源同时又在等待对方持有的资源谁也不让谁就僵住了。教科书上讲死锁的四个必要条件——互斥、持有并等待、不可剥夺、循环等待但实际工作里你不需要背这些你只需要会看两条东西死锁日志和事务执行顺序。我处理过的一个典型死锁案例是这样的。系统里有两张表订单表orders和库存表stock。事务A先更新orders再更新stock事务B正好反过来先更新stock再更新orders。并发上来后事务A锁住了orders里的某行等着锁stock里的某行事务B锁住了stock里的那行等着锁orders里的那行两个事务互相等待数据库检测到死锁后自动回滚了其中一个事务然后应用程序里就抛出了Deadlock found的异常。排查死锁有固定套路。第一步执行SHOW ENGINE INNODB STATUS查看LATEST DETECTED DEADLOCK部分的日志里面会清楚写出两个事务各持有什么锁、正在等待什么锁。第二步根据日志找到有问题的SQL看它们加锁的顺序是否一致。第三步统一业务代码里的加锁顺序比如规定所有事务都必须先操作orders再操作stock死锁自然就不存在了。第四步如果业务逻辑没法统一顺序那就靠降低隔离级别、延迟锁等待时间、或者使用SELECT ... FOR UPDATE SKIP LOCKED这类方式缓解。另外监控死锁不要靠肉眼刷日志用Prometheus加mysqld_exporter把死锁计数器采集起来或者定期轮询information_schema.innodb_trx表查看长时间未提交的事务。死锁不是玄学它一定能从日志里找到根源。4.2 先写数据库还是先写MQ这是个一致性问题分布式系统里有个经典的取舍业务操作是先落数据库还是先发消息队列如果你去网上搜会看到大量争论但结论其实没那么复杂核心诉求是保证数据库和消息队列之间的最终一致性也就是两边都不能丢数据。先写数据库再发MQ问题在于如果数据库事务提交成功但MQ发布时网络抖动或者MQ服务宕机消息发不出去下游消费者永远感知不到这次变更数据就丢了。先发MQ再写数据库反过来如果MQ成功写入但数据库操作失败消费者那边已经处理了这条消息可数据库里根本没有这条数据就会出现下游系统和数据库对不上账的情况。比较稳妥的方案是本地消息表加定时补偿也叫Outbox模式。具体做法是在业务数据库里建一张outbox表业务操作和写入outbox在同一个数据库事务里完成事务提交后消息自然就持久化了。然后由一个异步任务定时扫描outbox表把未发送的记录投递到MQ收到MQ的确认后把outbox记录标记为已发送。这套方案的好处是简单可靠坏消息是业务表多一张消息表、定时任务还会带来秒级延迟。如果不想维护本地消息表可以用RocketMQ的事务消息。RocketMQ要求你先发送一条半消息Half Message然后执行本地事务根据本地事务结果提交或回滚半消息MQ会通过状态回查机制保证消息最终被正确投递。这套机制比Outbox模式省事但前提是你用了RocketMQKafka和RabbitMQ都没有现成的事务消息支持。实际生产中我的建议很简单对一致性要求高、又不想引入重型框架的场景优先用Outbox模式已经用了RocketMQ的团队直接用事务消息。两套方案我都上线过最怕的不是选哪个而是选了之后不做补偿机制这才是数据不一致的真正根源。4.3 MySQL修改表结构、唯一约束和配额限制的坑MySQL运维中的坑实在太多了挑三个最常见的说。第一个是修改表结构。MySQL 5.6以后的版本支持Online DDL也就是ALTER TABLE的时候不锁表但并不是所有操作都支持INPLACE算法。比如修改列默认值用ALGORITHMINPLACE没问题但某些场景下MySQL会退化成COPY算法直接拷贝整张表大表直接被锁死读操作全部阻塞。稳妥的做法是生产环境修改大表结构前先看执行计划评估影响行数或者直接用pt-online-schema-changept-osc工具在后台限速执行避免长时间锁表。第二个是唯一约束重复的问题。很多人在建表时没考虑好唯一索引跑了一段时间后业务要求某列必须唯一这时才去加唯一索引结果发现库里已经有大量重复数据ALTER TABLE ADD UNIQUE直接报错。正确流程是先查重复再清理数据最后加索引。重复数据清理要跟业务方确认保留哪一条别随手DELETE删错了数据代价很大。这里有个实际经验清理重复数据时建议保留id最小的那条因为id越小往往意味着记录创建越早历史记录里的原始数据更有参考价值。第三个是数据库资源配额限制。我在项目里遇到过Oracle数据库报“只能使用40个核心”的情况查下来是License的限制CPU核数被限制在了40个以内再多核也不会被利用。MySQL也有类似限制不过不是License问题而是实例配置问题比如innodb_buffer_pool_size设置太小导致性能瓶颈。遇到这种问题先确认是什么类型的限制如果是License限制需要联系厂商申请扩容如果是配置参数问题调整对应的系统变量即可。4.4 Access数据库的报错和SQL Server跨服务器调用Access数据库看似老旧但不少老系统还在用。最常见的报错是“找不到数据库引擎启动句柄”和“64位引擎不支持DBC数据只支持Access数据”。这两个报错的核心是64位系统上运行的Office或者权限工具需要64位的Access数据库引擎如果你安装的是32位驱动就会提示找不到引擎或者不支持格式。解决办法是在微软官网下载“Microsoft Access Database Engine 2016 Redistributable”选x64版本安装。装的时候注意如果机器上同时装了32位的Office直接装64位驱动会报冲突得用/quiet参数静默安装或者把Office也换成64位。Multisim这类仿真软件访问Access数据库报错原理大同小异基本都是ODBC驱动位数不匹配导致的。先用odbcad32.exe检查系统里已有的驱动确认列表里有“Microsoft Access Driver (*.mdb, *.accdb)”位数也要对应上然后重启软件再试。SQL Server跨服务器调用数据库是另一个经典需求。场景通常是服务器A的IIS站点需要访问服务器B上的数据库或者反过来。最省事的方案是配置SQL Server的Linked Server在服务器A的SQL Server Management Studio里执行EXEC sp_addlinkedserver serverServerB, srvproduct, providerSQLNCLI, datasrc192.168.1.100; EXEC sp_addlinkedsrvlogin rmtsrvnameServerB, useselffalse, rmtusersa, rmtpasswordpassword;配置完就可以用四段式命名直接访问SELECT * FROM ServerB.DatabaseName.dbo.TableName。这里要提醒的是Linked Server跨服务器查询性能并不好大数据量查询可能会很慢建议只在小数据量的场景下用。另外别忘了配置服务器B的防火墙默认1433端口要放行否则连接会直接超时。5. 数据库知识体系搭建与面试冲刺5.1 数据库面试题到底在考什么数据库岗位的面试问来问去就是那些核心主题索引、事务、锁、日志、优化。面试官不是要你背定义而是看你能不能把知识点串起来解释一个现象。比如经典的“为什么MySQL索引要用B树”这个问题如果你只回答“因为B树矮胖查询快”那只是第一步。你需要进一步解释B树所有的数据都存在叶子节点并且叶子节点之间有指针相连天然适合范围查询而且因为非叶子节点不存数据单层能容纳更多索引项树的高度更矮IO次数更少。如果你能再补一句对比哈希索引不支持范围查询对比跳表在磁盘上不友好那面试官基本就满意了。再比如“什么是回表”这个问题覆盖索引的概念要理解透。假设你有一个联合索引(a, b)执行SELECT b FROM table WHERE a 1时索引里已经有b的值不需要回表查聚簇索引这就是覆盖索引带来的优化。但如果你执行SELECT c FROM table WHERE a 1索引里没有c就要根据索引叶子节点上的主键ID回到聚簇索引再查一次这个过程就是回表。回答这类问题时掏出实际SQL举例比空谈理论强得多。另一个高频考点是MVCC机制也就是多版本并发控制。MySQL的InnoDB用版本链加ReadView实现快照读让普通的SELECT在可重复读隔离级别下不用加锁就能做到“看到一致的数据”。redo log保证事务持久性undo log用来回滚和实现MVCCbinlog负责主从复制。把这几个log的区别和联系讲清楚是面试分水岭。5.2 数据库课程设计怎么做才能拿高分如果你是学生正在为数据库课程设计发愁我给你一套完整的流程。第一步选题。别选太简单的图书馆管理系统、学生选课系统这些年年有人做老师看得审美疲劳。选一个稍微带点业务复杂度的比如“社区团购平台数据库设计”“校园二手交易平台”业务逻辑更丰富ER图画出来也更完整。第二步画ER图转关系模式。实体、属性、联系理清楚了转到关系模式再按第三范式消除冗余。第三步建库建表把约束加全。主键、外键、非空、默认值、CHECK约束一个都不能少。第四步写存储过程、触发器、视图。课程设计的大头分在这几个数据库对象上。第五步做界面展示。用Java Swing、Python Flask或者HTMLPHP连上数据库实现增删改查界面让老师看到系统能跑起来。这些步骤基本就是一份课程设计的骨架。另外一定把文档写好数据库设计说明书里至少要有ER图、关系模式表、主要SQL语句、功能模块说明。老师给高分的关键不是功能有多炫而是设计过程规范完整、逻辑清晰能清楚说出每个表为什么这么设计。5.3 从“数据库笔记”到“数据库思维”很多人学数据库是学完MySQL学Oracle学完Oracle学达梦结果学到后面全是语法差异没有沉淀出自己的方法论。我自己的体会是数据库这东西底层的原理是共通的索引的本质是空间换时间事务的本质是状态机的状态流转分布式的本质是牺牲一致性换可用性。你把这三个本质理解透了不管换什么数据库都能快速上手。比如你理解了索引的底层是B树那么当你在达梦数据库上遇到SQL慢的情况你会本能地去看执行计划看是不是索引没建对而不是干瞪眼。你理解了事务的隔离级别那么在人大金仓上遇到并发问题你会直接去查事务隔离级别设置和锁等待情况。所谓“数据库思维”就是遇到问题能自动套用“存储结构、并发控制、故障恢复、性能优化”这四个维度去分析而不是背某一种数据库的操作命令。写这篇笔记的过程本身就是一次很好的体系梳理。我强烈建议你也把手上的数据库笔记重新整理一遍先按主题归类再补上实际案例最后标出哪些知识点你真正在项目里用过、哪些只有面试时才想得起来。经过这轮整理你会发现自己对数据库的理解层次完全不一样了。