尧图精选

关系型数据库核心原理与实战选型指南

🕒 发布时间:2026/9/13 13:16:16 📁 来源:尧图网络
先直接说结论不管你是刚接触编程的学生还是已经在写业务代码的开发者只要你处理过订单、账目、用户信息这类不能出错的业务数据那你八成已经在用关系型数据库了。它就是把数据组织成一张张“表格”表里有行、有列表跟表之间还能通过某个关键字段联系起来所有操作都通过标准化的 SQL 语言完成并且靠一套 ACID 事务机制保证数据不会在出错时变得东缺一块西缺一块。这篇文章我会从“它到底是什么”讲起再拆开讲讲它身上的核心设计原理、真正的优点和让人头疼的缺点最后落到实际选型和排坑经验。适合正在学数据库的学生、刚入行的后端开发、被数据选型搞得焦头烂额的技术负责人。看完以后你会清楚地知道为什么银行转账一天要跑无数次关系型数据库、为什么有些海量数据的互联网场景反而对它又爱又恨以及你自己手上的项目到底该不该选它。1. 关系型数据库到底是什么1.1 先从一张员工表说起最容易理解关系型数据库的方式就是直接看它存数据的样子。比如一家公司要记录员工信息最直观的存法就是拿一张二维表格每一行是一条员工记录每一列是某种属性比如工号、姓名、部门、入职日期、薪资。这张表在关系型数据库里会被称作“关系表”或者说“数据表”。你可以把它想象成 Excel 表格工具的表头就是列名下面的每一行都是一条完整记录。数据库管理系统DBMS负责把这张表持久化到磁盘上、把增删改查的请求翻译成底层的文件操作并保证多个人同时操作时数据仍然正确。关键点来了关系型数据库并不是“只能存一张表”而是允许你有几十张、几百张表并且用一张表里的某个字段去指向另一张表的记录。举例来说员工表里不直接写“技术部”这个文本而是写一个department_id再去部门表里查这个 ID 对应的是哪个部门。这样部门改名时不需要改所有员工行只需要改部门表里的一行。1.2 关系模型的源头一张表怎么变成一套系统“关系型”这个词的正式提出要追溯到 1970 年 E.F.Codd 发表的经典论文。他在论文里提出了一种用数学上的“关系”来组织数据的方式数据被拆成规范化的二维表表与表之间通过键Key建立联系操作时不需要关心数据在磁盘上具体怎么摆放只需要用声明式语言来描述“你要什么”。这个思路在当时非常反直觉。之前的数据库层次模型和网状模型都需要开发者在代码里显式维护指针和路径查一条数据要先清楚数据的物理存储结构。而关系模型把“物理存储”和“逻辑操作”剥离开让普通业务人员也能通过统一的查询语言操作数据而不必理解磁盘块、链表、树这些底层细节。后来的商业数据库 Oracle、DB2再到开源的 MySQL、PostgreSQL底层存储和优化器各不相同但它们对外提供的基本模型都是同一套关系模型加 SQL 语言。这也是为什么一个懂 MySQL 的人换到 PostgreSQL 或 SQL Server 上只需要简单适应语法差异就能很快上手。关系模型没有随时间消失反而成了数据世界里最稳固的地基。1.3 “关系”到底指什么表与表的关联初学者容易有个误会觉得“关系”就是存储时把关联数据放在一起。其实“关系”Relation在数学语境里指的是“一个有行和列的二维集合”而“关系型数据库”最重要的特征是通过主键、外键和连接操作来表达数据之间的关联。拿订单系统举例orders表里有order_id、customer_id、amountcustomers表里有customer_id、name、phone。这两张表之间通过customer_id这个公共字段联起来。如果你想查“张三最近三个月的订单金额”不需要去两个表里手工翻找写一条JOIN语句就能瞬间组合出结果。这种设计带来两个巨大的好处第一数据不会冗余重复。同一个用户的名字、电话只在customers表里存一份订单表里只存一个 ID省空间且改一处就全生效。第二完整性压力被数据库接管了。只要把customer_id设置成外键并加上约束数据库就能拒绝那些指向不存在用户的订单记录不让脏数据混进来。2. 核心设计原理为什么它能稳定撑这么多年2.1 SQL一门让你和数据对话的标准语言SQLStructured Query Language结构化查询语言是关系型数据库的标配操作语言。它能干的活就四类查询SELECT、插入INSERT、更新UPDATE、删除DELETE外加管理表结构的 DDL 语句CREATE、ALTER、DROP。这套语法从几十年前定型到现在主流数据库之间的差异并不大。SQL 最厉害的地方在于它是“声明式”的。你写SELECT * FROM orders WHERE amount 1000只需要告诉数据库“我要金额大于 1000 的订单”至于怎么扫描、怎么建临时表、怎么排序那是优化器的事。而早期非关系型存储往往要求你在代码里手动遍历SQL 把这份体力活从应用层转移到了数据库引擎内部。这就带来一个实际好处业务代码和具体数据库解耦。你今天用 MySQL明天想换 PostgreSQL只要没用到太多数据库私有的特殊函数SQL 语句基本能原样迁移业务代码只改连接配置就行。后面就算团队换了人接手的开发者只要会 SQL就能快速理解数据是怎么流转的。2.2 事务与 ACID最值钱的能力关系型数据库最硬核、也最不容易被替代的能力就是事务Transaction。事务把一组操作打包成一个不可分割的整体要么全部成功要么全部失败不会出现“只做了一半”的中间状态。ACID 是事务的四个特性缩写拆开看特别好理解原子性Atomicity事务里的操作要么全部生效要么全部回滚。比如转账时扣款和入账必须同时成功任何一个失败转账整体失败。一致性Consistency事务执行前后数据必须符合所有预设规则。像账户余额不能为负数这种约束数据库会强制校验。隔离性Isolation多个事务并发执行时彼此不能互相干扰。一个事务没提交之前做的修改其他事务应该“看不到”或者只能看到符合隔离级别的状态。持久性Durability事务一旦提交结果就会永久保存哪怕系统瞬间断电重启后数据也还在。用银行转账的场景来类比最清楚A 转给 B 一千元事务先扣 A 的余额再给 B 加余额。如果第一步完成、第二步还没执行时系统崩溃数据库会在重启后把事务回滚A 和 B 的钱都恢复到转账前的状态。没有这个机制电子转账根本不敢做。开发者容易忽略的是ACID 不是免费的开启事务期间通常会加锁、记录日志、限制并发度。所以事务的长度和跨度要控制好别在事务里做网络请求、慢查询和长时间的计算否则很容易把数据库的并发能力拖垮。2.3 索引查询快的真正原因关系型数据库能处理千万级、亿级数据靠的不只是硬件更关键的是索引Index。索引的本质是一种额外的数据结构拿“键值”来换取查询速度最常见的是 B 树索引哈希索引则适合等值查询。可以把索引想象成书的目录没有目录你要从第一页翻到最后一页才能找到一个词有了目录直接就能翻到对应页码。数据库里的索引会在插入时多维护一份有序结构查询时就能用二分查找这类高效算法快速定位到目标行而不是把整张表从头到尾扫一遍。索引虽好但绝对不是建得越多越好。每建一个索引就相当于额外维护一本目录插入、更新、删除时都要同步修改这本目录。现实中很多慢查询问题其实就是该建的索引没建或者建错了列。比如 WHERE 条件里对字段做了函数运算或隐式类型转换索引就失效了又比如建立了联合索引查询条件没遵循最左前缀原则索引也派不上用场。2.4 范式设计表结构的“套路”关系型数据库的表结构设计有一套经典理论叫“范式”Normal Form。最常见的是第一范式、第二范式和第三范式。第一范式要求每列都不可再分字段是原子的第二范式要求非主键列完全依赖主键不能只依赖主键的一部分第三范式要求非主键列之间不能有传递依赖比如 A 决定 B、B 决定 C那 C 也不该出现在表里。这套规则的核心目标就是减少冗余、避免数据不一致。比如把“部门名称”直接塞进员工表一旦部门改名所有员工记录都要更新漏掉一条就出现脏数据。规范化之后员工表只保留部门 ID部门名称只存在部门表里更新只需改一行。不过实战里不需要死守所有范式。查询需求复杂、表关联层数太多时很多团队会有意做“反规范化”比如在订单表里冗余一个“用户名”字段减少 JOIN 次数。这种权衡是合理的但必须通过应用层逻辑或者定时任务保证冗余数据最终一致。范式是基本功反范式是手段关键看业务场景对一致性和性能哪个更敏感。2.5 约束数据库替你把关数据质量关系型数据库除了存数据还能定义一套约束规则让数据库自己拒绝非法数据。所谓约束包括主键约束Primary Key保证每行记录可以唯一识别且不允许为空。唯一约束Unique保证某列或某几列的组合值不重复。非空约束Not Null不允许字段为空。检查约束Check对字段取值范围做限制比如年龄在 0 到 150 之间。外键约束Foreign Key保证引用的记录一定存在防止孤儿数据。这些约束的价值在于把一部分数据校验从应用代码下沉到了数据层。即便某个开发者在写代码时忘了判空、忘了查重数据库也会在写入时给出错误拦截脏数据。很多人觉得约束麻烦尤其是外键会影响导入性能想省掉。但对真正重要的业务数据约束往往是最后一道安全网省不得。3. 优点盘点什么时候该优先选它3.1 数据一致性关键业务容不得半点差错关系型数据库最大的护城河就是 ACID 事务带来的强一致性。金融、电商、政务、医疗这些场景数据错了不是小事。转账金额多扣零、订单支付状态不一致、库存减了订单没生成这些故障一旦发生轻则客服被打爆重则产生资损纠纷。ACID 事务把“数据一致性”变成了数据库层面的承诺而不是靠程序员靠运气拼代码。开发者在写下单逻辑时可以在一个事务里同时更新订单表、扣减库存表、写入流水表任何一步失败都会让整体回滚应用层不再需要额外写一堆补偿逻辑。分布式场景下跨多个数据库实例的强一致确实难做那也属于后面要讲的“缺点”范畴。单库单机情况下关系型数据库的一致性体验在目前所有存储方案里依然是最理想、最省心的。3.2 SQL 标准化人换了代码照样能接SQL 已经是一个跨公司、跨行业的通用技能。数据库岗位要求里写“熟悉 SQL”意思是候选人无论在哪家公司靠这套语言都能干活。这对团队协作和技术交接非常友好。项目里如果用的是 MySQL关系模型依然一致数据字典依然清晰。遇到问题上网搜一下“乐观锁”“JOIN 优化”“索引失效”能搜出大量经验帖。反观某些自研存储或者小众 NoSQL遇到问题往往只能查官方文档社区资料少踩坑只能自己硬扛。还有一点常常被低估SQL 的出报表能力极强。运营想要“按城市聚合最近一个月的订单量、订单金额、客单价”只需要一条GROUP BY语句几秒钟就能算出来。用对象存储、文档库里存数据这种临时聚合查询往往要写很长的后端代码逐条拉取再到内存里算效率差出一大截。3.3 生态成熟工具链丰富到可怕关系型数据库发展了几十年周边工具链成熟得让人安心。你知道有什么工具可以看慢查询日志吗有。有什么工具可以做可视化建表、数据建模有。有什么工具可以做增量同步到数据仓库有。从连接池、ORM 框架、数据库审计到数据备份恢复全都有大量成熟的开源或商业方案可以选。主流的编程语言无论是 Java、Go、Python、Node.js都有非常成熟的 ORM 框架和驱动。Spring Boot 里有 MyBatis、HibernatePython 里有 SQLAlchemy、Django ORMGo 里有 GORM这些库对关系型数据库的支持都是“一等公民”。一旦业务量增长关系型数据库还能借助各种中间件做读写分离、分库分表、数据归档生态里能找到很多现成方案。哪怕是一些比较冷门的需求比如导出 Excel、生成图表大屏也往往都有现成的工具直接对接 SQL 查询省去很多开发量。3.4 权限与安全控制成熟关系型数据库在权限控制上做得非常细致。你可以精确到某个用户只能查某张表的某些列可以限制用户只能从某个 IP 连接可以配置只读账号、读写账号、管理员账号不同角色权限清晰隔离。这在企业环境里非常重要。给业务方开一个只读账号查数据他会把复杂统计查到主库把数据库压垮吗——不该开的权限一律不开。给外包同学开一个业务库账号他能顺手把整个实例删了吗——管理员权限单独保管需要审批才能用。另外关系型数据库的备份、恢复、Binlog 日志机制相当完善。出故障时可以用备份加快照方式进行时间点恢复尽量把数据损失降到最小。这套安全体系经过无数生产环境检验是新手自研存储很难比得上的。3.5 复杂查询能力联表统计一把梭假设现在有用户表、订单表、商品表、类目表你要统计“每个类目下最近一个月复购率最高的商品 TOP 20”。关系型数据库可以用几条 JOIN、子查询、聚合函数配合完成这也是 SQL 最擅长的领域。这种多表关联的复杂查询换成 NoSQL 或纯内存缓存来做非常别扭。文档型数据库只能针对单文档结构做查询想跨类型关联往往要在应用层多次查询再手工合并键值数据库更是只能依据 Key 取数据连“按多个字段过滤”都要多做一层设计。关系型数据库的 JOIN 和聚合能力就是这类复杂报表需求的最佳解法。当然复杂查询的前提是表结构和索引设计合理。一个 JOIN 写不好同样会变成慢查询拖垮整个库。但“能做复杂查询”和“完全不能做”这两者的差别决定了一个数据库是通用工具还是专用组件。4. 缺点拆解再强也有撑不住的场面4.1 水平扩展难加机器不如加内存关系型数据库最让人头疼的短板其实是“扩展性”。单机性能再强也有上限等数据量、并发量上来以后你不可能像加服务器节点一样无限扩展一台数据库服务器。传统的做法是“读写分离”主库负责写从库负责读稍微缓解读压力。但写压力一旦也上来读写分离就不够用了。继续拆需要做分库分表把一张大表按某个字段拆到几十个数据库实例上查询时要依赖中间件做路由和聚合。拆完以后跨分片的 JOIN、分布式事务、全局唯一 ID、排序分页都变得棘手很多。比起键值存储或文档数据库可以通过增加节点自然扩容关系型数据库的水平扩展更像一场手术需要精细规划、谨慎执行。很多团队数据量大到一定程度后会选择把非核心数据迁到其他存储让关系型数据库只保留最需要强一致性的核心数据。4.2 高并发写入和读多写少场景吃力关系型数据库因为要保证事务和一致性在高并发写入时会付出额外代价。每次事务提交都要处理锁竞争、刷日志、维护索引状态。多个事务同时更新同一行时还会出现锁等待并发越高冲突概率越大性能下降越明显。这和很多互联网业务的实际需求有冲突。比如一个点赞系统每秒有十万次点击真的需要每次都完整开启一个 ACID 事务吗其实不需要用户只是想让计数加一。这种场景用 Redis 的 INCR、或者消息队列异步写入都能比关系型数据库扛下更高的 QPS。反过来说如果业务对一致性要求极高比如抢红包、秒杀扣库存那再高的并发也得在关系型数据库上想办法通过乐观锁、排队、限流等手段控制并发。关系型数据库能做高并发业务但绝对不是在没人做减压设计的情况下硬扛。4.3 Schema 不够灵活改表结构如同动手术关系型数据库要求在写入数据之前先定义好表结构、字段类型、约束。这个“强 Schema”模式能保证数据整齐划一但代价就是“改结构”非常痛苦。业务跑了一段时间想新增一个字段比如给用户表加一个vip_level表里如果有几千万行数据ALTER TABLE可能需要长时间锁表期间写操作全被阻塞。哪怕用 MySQL 8.0 的瞬时加列功能也只是在部分场景下缓解了锁表问题复杂的结构变更依然需要借助大表迁移工具比如 pt-online-schema-change在低峰期小心翼翼执行。如果产品需求变化非常快字段属性三天两头变或者每一条记录的结构都不太一样那么关系型数据库的强 Schema 就会变成开发效率的瓶颈。像日志、配置、爬虫抓取的半结构化 JSON用文档数据库或列式存储反而更自然。4.4 非结构化数据支持先天不足关系型数据库擅长处理的是规整的、结构化的数据比如数字、短字符串、日期。碰到图片、音频、视频、长篇文本、复杂的嵌套 JSON 这类非结构化或半结构化数据它的表现就比较尴尬。虽然很多关系型数据库支持 BLOB 字段或 JSON 类型但实际性能通常不如对象存储和搜索引擎。图片文件放在数据库里浪费大量空间、拖累备份恢复速度、查出来还要转存到服务器完全得不偿失。正确做法是文件放对象存储数据库里只存文件路径和元数据。JSON 字段可以用但大规模全文检索和同义词扩展还是得交给 ES 这类搜索引擎来处理。所以关系型数据库通常只是系统的一部分不是全部。复杂的存储架构往往是关系型数据库管核心事务数据Redis 管缓存ES 管搜索对象存储管文件消息队列做缓冲。认清每个组件的边界才不会把数据库用成“万能锤”。4.5 分布式事务复杂度高单机关系型数据库可以把 ACID 事务做得滴水不漏可一旦数据量大到必须做分布式跨库事务的复杂度会立刻飙升。两个库之间的数据一致性已经不能靠一个数据库自己的事务日志来保证需要引入两阶段提交、TCC、消息最终一致性等分布式事务方案每一种都有明显的性能或一致性取舍。两阶段提交2PC的同步阻塞问题、协调者单点风险、网络分区时的不确定性这些都是在分库分表后要面对的难缠问题。很多团队为了避免分布式事务干脆在设计阶段就尽量让业务按某个维度“分片本地化”比如同一个用户在同一个库这样大多数操作仍然只在一个库内完成事务把跨库频率降到最低。这其实也解释了为什么这么多系统宁可选择单库多表、读写分离、上云数据库的托管产品也不轻易做激进的分布式改造。关系型数据库在分布式场景下能做到“最终一致”就已经不错想保持和单机一样的强一致需要的技术和人力成本相当可观。5. 适用场景和选型判断5.1 哪些业务场景必须上关系型数据库如果一个业务有强烈的“多步操作必须同时成功或同时失败”的需求比如订单、支付、库存、账户余额不用关系型数据库就很难保证正确性。去银行转账、去电商下单、在后台修改商品价格这些背后几乎必然有一张带事务的表在兢兢业业地工作。组织结构清晰、属性稳定的业务数据也更适合关系型数据库。比如企业 ERP、CRM、学校选课系统用户、商品、订单、课程这些实体的字段基本稳定不需要频繁动态扩展属性做成一张张规整的表后续查询和维护都方便。需要频繁做复杂统计汇总的场景也应该优先考虑关系型数据库。数据库内部的聚合函数和优化器经过了大量迭代比自己在应用层写循环要靠谱得多。固定报表、运营看板、财务对账用 SQL 完成要比用一堆代码反复读取再统计高效得多。5.2 哪些场景建议搭配 NoSQL海量日志、用户行为流、IoT 设备数据这类数据每天新增几亿条字段结构不统一历史数据极少更新查询也往往是按时间范围扫描。关系型数据库能撑但要付出很高的成本而且便利性不如专门为海量写入设计的 NoSQL。高并发访问下Redis 这类缓存是关系型数据库的最好搭档。把热点数据放进缓存能大幅降低数据库读压力像登录态、验证码、排行榜这类数据本来就只需要短时间有效放内存数据库里更合适。社交动态、评论树、个性化推荐这类需要灵活数据结构的场景文档数据库或图数据库会更好写。类似于全文搜索引擎Elasticsearch在复杂搜索、模糊匹配、中文分词上的能力也远强于关系型数据库里的LIKE %keyword%。没有哪个技术方案能包打天下选型不是比谁更时髦而是比谁更匹配业务。关系型数据库的定位是核心数据的可靠存储NoSQL 则擅长在特定场景下补足它的短板两者通常是配合关系而非替代关系。5.3 关系型和非关系型数据库的横向对比如果把这些主要差异列成一张表会直观很多对比维度关系型数据库非关系型数据库NoSQL数据模型表、行、列关系明确键值、文档、列族、图等Schema强约束先建表后写数据灵活字段可以不固定事务能力ACID 强事务多为最终一致性部分支持事务查询能力SQL 标准支持复杂 JOIN 和聚合按不同模型有各自查询方式扩展方式主要是垂直扩展水平扩展复杂天生倾向于水平扩展适用场景金融、ERP、订单、报表缓存、日志、搜索、社交关系等成熟度数十年的工程积累工具丰富各方向分化有些不够成熟这张表不是用来判断谁更好而是用来提醒你选型前先列一下业务对一致性、查询复杂度、数据量、并发量和开发效率的真实要求再决定哪个维度值得优先满足。一致性要求高、SQL 查询复杂偏向关系型数据量巨大、字段变化频繁偏向 NoSQL。5.4 选型心法根据一致性、扩展性、团队能力来判断我见过的很多选型翻车往往不是因为技术不行而是“拿着锤子看什么都像钉子”。前几年 NoSQL 火有人连订单数据都想往 MongoDB 里塞结果后续做对账、做报表、做复杂统计时哭爹喊娘后几年又有人迷信 NewSQL上了复杂的分布式数据库结果运维团队根本扛不住。我的建议是做选型前先问自己三个问题业务的核心数据能不能容忍最终一致性团队有没有能力维护分布式架构查询中会不会出现很复杂的多表关联如果答案是“不能容忍”“没有完全把握”“会”那关系型数据库往往是更稳的选择。哪怕是用最普通的 MySQL 单库先把业务跑通等量起来了再考虑缓存、分库分表、上云数据库这个路径是无数验证过的成熟路线。别为了“技术先进性”而牺牲系统的可维护性。软件工程的本质很多时候是把复杂问题通过合适的技术组合变简单而不是反过来给自己挖坑。聊一个有趣的现象像山东大学软件学院这类高校如今在课程里已经把非关系型数据库作为重要教学内容不再只讲 MySQL、Oracle。这正好说明整个行业已经形成共识——关系型数据库是地基非关系型数据库是延伸两者都要学。但无论新课程怎么开关系型数据库背后的表结构设计、事务思想、SQL 思维依然是所有数据库技术的根。6. 实战中常见的坑与排查方法6.1 慢 SQL先看执行计划慢 SQL 是最常见的数据库性能问题。业务变大了、数据量上去了以前几毫秒的查询某天突然跑到几百毫秒甚至几秒页面直接卡死。遇到这类问题第一件事不是无脑加缓存而是拿到那条 SQL用EXPLAIN或EXPLAIN ANALYZE看执行计划。执行计划里重点关注几个东西访问类型是不是ALL也就是全表扫描实际扫描了多少行数据有没有用到预期中的索引有没有出现临时表和文件排序。大多数慢查询都能在索引上找到答案——要么是漏建索引要么是查询写法导致索引失效要么是返回了不必要的列。把这些基础问题解决掉很多性能瓶颈根本不需要换数据库就能缓解。6.2 死锁事务顺序不一致惹的祸死锁的表现是事务之间互相等待对方持有的锁谁也无法继续数据库会检测到并回滚其中一个事务然后你再收到一个Deadlock found的报错。这种问题之所以难排查是因为它不是必然发生往往在高并发时随机浮现。最常见的引发原因是不同业务请求对多张表的加锁顺序不一致。比如事务 A 先更新订单再更新库存事务 B 先更新库存再更新订单两个事务并排跑时就有概率互相卡死。解决办法是约定全团队所有事务都按照同一套顺序加锁比如先操作订单表再去操作库存表从根上破坏循环等待另外还可以通过重试机制处理偶发的死锁回滚。6.3 大表深翻页LIMIT 用的地方有问题很多后端开发都有过这种体验列表页第一页秒开翻到第一百页就慢得像假死。问题根源通常是这条 SQLSELECT * FROM orders ORDER BY id LIMIT 9900, 20。数据库要先把前 9900 条全部读出来排好再丢弃掉只留下 20 条。翻得越深无效工作量越大。解决思路一般是换成分页方式。简单的场景可以直接根据游标传上一页的最后一条记录 ID加上WHERE id last_id ORDER BY id LIMIT 20就能直接跳过前面的大量偏移。更复杂一些的可以结合覆盖索引、分区表或外部搜索引擎。记住一点现代业务里“跳着翻几千页”的用户本来就极少为了这极少数场景拖垮整个查询不划算。6.4 连接数被打满连接池配置有门道系统流量稍一大应用突然报错“Too many connections”很多人第一反应是把数据库的最大连接数调大。但更常见的根因是应用层的连接池配置不合理或者某个地方忘了归还连接。Java 后端常用的 HikariCP、DruidPython 用的 SQLAlchemy 连接池都有最小连接数、最大连接数、最大空闲时间这些参数。如果一个应用的最大连接数设成 300再起 20 个服务实例数据库那边就同时要吃下 6000 个连接大多数数据库默认配置根本扛不住。连接池大小不是越大越好经验值通常是核心数乘 2 加一些余量连接真正稀缺的资源池子太大反而增加线程切换和资源占用成本。6.5 数据量上来以后的拆与不拆表数据到千万级、亿级以后索引越来越大写入越来越慢查询因为索引层级加深和内存放不下全部热数据性能出现明显下滑。这时候就该考虑“分”了。分库分表分为垂直拆分和水平拆分。垂直拆分是把宽表拆成多个表比如把用户基础信息和用户扩展信息分开水平拆分是把同一张表按某个分片键比如用户 ID分散到不同库表里。拆完以后应用层的 SQL 要带上分片键才能高效路由跨分片查询要实现聚合这又是一套复杂度。我的体会是不要一听“分库分表”就觉得高级。能不分就不分优先考虑升级硬件、优化 SQL、加缓存、读写分离。等到真分的时候也要设计好分片维度和扩容方案不然拆完以后想再合并就难了。7. 最后的体会写了这么多年数据库相关的需求我自己最大的感受是关系型数据库一点都不“过时”恰恰相反它是几乎所有业务系统的压舱石。无论外面讨论多少新存储、新架构订单、账单、用户、权限这类关键数据最终还是有个关系型数据库在稳稳兜底。如果你正在学校或刚入行别觉得同时学 MySQL 和 NoSQL 的内容太重复。把关系型数据库的表设计、事务原理、SQL 优化吃透再去理解非关系型数据库的取舍会顺畅得多。反过来要是连最基本的 SQL 和索引优化都还没玩明白就急着追 NewSQL 和分布式数据库的热度很容易在选型和排障时迷失重点。最近几年出去交流明显感觉到一个趋势大家不太再争论“关系型还是非关系型谁替代谁”而是更务实地思考“这个场景的数据形态是什么、一致性要求多高、访问模式怎么样”。关系型数据库和非关系型数据库的边界越来越清晰组合使用的架构也越来越多。但不管这套组合怎么变化关系型数据库那一套“先理解数据、再设计模型、最后用事务守护正确性”的思维方式永远是值得花时间打磨的基本功。最后分享一个实在的建议不管选什么数据库先用最小的成本把备份、监控、慢查询日志这三件事做起来这比选型本身更值钱。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →