Shardingsphere5分库分表
分库分表垂直分库按业务拆。把不同的表放到不通的数据库中。水平分库同一张表拆成多个表放到不同的库中相同表结构的数据库就是水平分表。水平分表一张表拆数据行把一张表横着拆成多张一般与水平分库一起用。垂直分表把一张大表的列拆开。分片 总称分库 分片的一种拆数据库分表 分片的一种拆表水平分表不与水平分库一起用db_order ├── t_order_0 ├── t_order_1 ├── t_order_2 ├── t_order_3水平分库与水平分表一起用db_order_0 ├── t_order_0 ├── t_order_1 db_order_1 ├── t_order_0 ├── t_order_1垂直分库 水平分库 水平分表最典型db_user t_user 对t_order进行水平分库和分表 db_order_0 t_order db_order_1 t_order只水平分库db_order_0 t_order db_order_1 t_order分库分表的核心思想数据分散存储使得单一数据库/表的数据量变小来缓解单一数据库的性能问题从而达到提升数据库性能的目的。垂直分库以表为依据根据业务将不同表拆分到不同库中。每个库的表结构都不一样。每个库的数据也不一样。所有库的并集是全量数据。垂直分表以字段为依据根据字段属性将不同字段拆分到不同表中。每个表的结构都不一样。每个表的数据也不一样一般通过一列主键/外键关联。所有表的并集是全量数据。水平分库以字段为依据按照一定策略将一个库的数据拆分到多个库中。每个库的表结构都一样。每个库的数据都不一样。所有库的并集是全量数据。水平分表以字段为依据按照一定策略将一个表的数据拆分到多个表中。每个表的表结构都一样。每个表的数据都不一样。所有表的并集是全量数据。配置环境JDK8SpringBoot(2.3.9.RELEASE)ShardingSphere-jdbc(5.1.1)MySQL8(一个主库两个从库配置好主从复制)。Maven依赖dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.apache.shardingsphere/groupId artifactIdshardingsphere-jdbc-core-spring-boot-starter/artifactId version5.1.1/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.3.1/version /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope exclusions exclusion groupIdorg.junit.vintage/groupId artifactIdjunit-vintage-engine/artifactId /exclusion /exclusions /dependency /dependencies读写分离配置参考文档读写分离 :: ShardingSphereShardingSphere启动模式模式作用Memory规则存在JVM内存Standalone单机持久化Cluster注册中心模式负载均衡算法常用ROUND_ROBIN、RANDOM。spring: application: name: sharding-jdbc-dome profiles: active: dev shardingsphere: mode: type: Memory datasource: # 声明所有真实数据源的名称。 # # 这里定义了3个真实数据库连接 # master主库 # slave1第1个从库 # slave2第2个从库 # # names中的名称必须与下面的数据源配置名称一致。 # 名称不是固定的也可以写成 # write-db,read-db-1,read-db-2 names: master,slave1,slave2 # 主库真实数据源配置。 master: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33388/db_user username: root password: 123456 # 第1个从库真实数据源配置。 slave1: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33307/db_user username: root password: 123456 # 第2个从库真实数据源配置。 slave2: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33308/db_user username: root password: 123456 rules: # 读写分离规则。 # ShardingSphere只负责SQL路由不负责MySQL数据同步。 # master到slave1、slave2的数据同步仍由MySQL主从复制完成。 readwrite-splitting: >load-balancer-name: olg_weight load-balancers: olg_weight: type: WEIGHT props: slave1: 1.0 slave2: 2.0如果在同一个事务下有增删改也有查询只会查询主数据库而不是从数据库。Transactional Test void transactionTest(){ User user new User(); user.setUname(张三丰); userMapper.insert(user); ListUser users userMapper.selectList(null); System.out.println(users); }垂直分库水平分库水平分表 配置环境说明一个逻辑表t_order两个真实数据库server-order0 → MySQL数据库 db_orderserver-order1 → MySQL数据库 db_order每个数据库两个真实表t_order0t_order1最终形成2个库 × 2张表 4张真实订单表对应的配置如下t_order: actual-data-nodes: server-order$-{0..1}.t_order$-{0..1}分库规则database-strategy: standard: sharding-column: user_id sharding-algorithm-name: alg_mod配置说明根据user_id决定数据库算法偶数用户server-order0奇数用户server-order1alg_mod: type: MOD props: sharding-count: 2 # 针对sharding-column: user_id字段对2取模user_id计算数据库11%21server-order122%20server-order033%21server-order144%20server-order0分表规则table-strategy: standard: sharding-column: order_no sharding-algorithm-name: alg_hash_mod表示同一个数据库里面再根据order_no决定放到哪个表中。alg_hash_mod: type: HASH_MOD props: sharding-count: 2 # 针对sharding-column: user_id字段对2取模例如订单号hash(10001)%20 进入t_order0另一个hash(10002)%21 进入:t_order1。雪花IDid字段自动生成id字段要配合mybatis-plus的“TableId(type IdType.AUTO)”。t_order: key-generate-strategy: column:id key-generator-name:alg_snowflake完整配置文件spring: application: name: sharding-jdbc-dome profiles: active: dev shardingsphere: mode: type: Memory datasource: names: server-user,server-order0,server-order1 server-user: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33008/db_user?useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/Shanghai username: root password: 123456 server-order0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33016/db_order?useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/Shanghai username: root password: 123456 server-order1: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33017/db_order?useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/Shanghai username: root password: 123456 props: sql-show: true rules: sharding: tables: t_user: actual-data-nodes: server-user.t_user t_order: actual-data-nodes: server-order$-{0..1}.t_order$-{0..1} database-strategy: standard: sharding-column: user_id sharding-algorithm-name: alg_mod table-strategy: standard: sharding-column: order_no sharding-algorithm-name: alg_hash_mod key-generate-strategy: column: id key-generator-name: alg_snowflake sharding-algorithms: alg_inline_userId: type: INLINE props: algorithm-expression: server-order$-{user_id % 2} alg_mod: type: MOD props: sharding-count: 2 # 针对sharding-column: user_id字段对2取模 alg_hash_mod: type: HASH_MOD props: sharding-count: 2 # 针对sharding-column: user_id字段对2取模 key-generators: alg_snowflake: type: SNOWFLAKE读写分离环境说明一个主库master负责写两个从库slave1、slave2负责读查询自动分发到从库插入、更新、删除自动走主库注意如果是在一个事务中进行了增删改之后并执行了查询那么此时为了保证数据一致性此时会自动查询主库。配置读写分离规则rules: readwrite-splitting:创建一个逻辑数据源myds对应的是“master slave1 slave2”三个数据源。data-sources: myds:手动指定读写库myds: type: Static props: write-data-source-name: master read-data-source-names: slave1,slave2负载均衡配置load-balancers: alg_round: type: ROUND_ROBIN # 轮训或者按权重 olg_weight: type: WEIGHT props: slave1: 1.0 slave2: 2.0完整配置文件spring: application: name: sharding-jdbc-dome profiles: active: dev shardingsphere: mode: type: Memory datasource: names: master,slave1,slave2 master: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33388/db_user username: root password: 123456 slave1: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33307/db_user username: root password: 123456 slave2: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33308/db_user username: root password: 123456 rules: readwrite-splitting: >SpringBoot应用 | ShardingSphere-JDBC | --------------------------------- | | server-order0 server-order1 | | t_order0 t_order0 t_order1 t_order1 t_order_item0 t_order_item0 t_order_item1 t_order_item1ShardingSphere的绑定表支持多个表组成一组也支持配置多个绑定表组。使用前提多个表的分库分表规则必须完全一致。SQL联查绑定表关联时最好使用分片键例如order_no进行关联。SELECT o.order_no, SUM(i.price * i.count) AS amount FROM t_order o JOIN t_order_item i ON o.order_no i.order_no GROUP BY o.order_no;完整配置文件spring: application: name: sharding-jdbc-dome profiles: active: dev shardingsphere: mode: type: Memory datasource: names: server-user,server-order0,server-order1 server-user: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33008/db_user?useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/Shanghai username: root password: 123456 server-order0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33016/db_order?useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/Shanghai username: root password: 123456 server-order1: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33017/db_order?useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/Shanghai username: root password: 123456 props: sql-show: true rules: sharding: tables: t_user: actual-data-nodes: server-user.t_user t_order: actual-data-nodes: server-order$-{0..1}.t_order$-{0..1} database-strategy: standard: sharding-column: user_id sharding-algorithm-name: alg_mod table-strategy: standard: sharding-column: order_no sharding-algorithm-name: alg_hash_mod key-generate-strategy: column: id key-generator-name: alg_snowflake t_order_item: actual-data-nodes: server-order$-{0..1}.t_order_item$-{0..1} database-strategy: standard: sharding-column: user_id sharding-algorithm-name: alg_mod table-strategy: standard: sharding-column: order_no sharding-algorithm-name: alg_hash_mod key-generate-strategy: column: id key-generator-name: alg_snowflake sharding-algorithms: alg_inline_userId: type: INLINE props: algorithm-expression: server-order$-{user_id % 2} alg_mod: type: MOD props: sharding-count: 2 # 针对sharding-column: user_id字段对2取模 alg_hash_mod: type: HASH_MOD props: sharding-count: 2 # 针对sharding-column: user_id字段对2取模 key-generators: alg_snowflake: type: SNOWFLAKE # 绑定表指分片规则一致的一组分片表。 使用绑定表进行多表关联查询时必须使用分片键进行关联 # 否则会出现笛卡尔积关联或跨库关联从而影响查询效率。 binding-tables[0]: t_order,t_order_item # 去掉笛卡尔积的关联广播表指所有的分片数据源中都存在的表表结构及其数据在每个数据库中均完全一致。 适用于数据量不大且需要与海量数据的表进行关联查询的场景例如字典表商品分类表。订单状态表。广播具有以下特性1插入、更新操作会实时在所有节点上执行保持各个分片的数据一致性2查询操作只从一个节点获取3可以跟任何一个表进行 JOIN 操作环境说明需要提前在这3个数据库中创建结构完全相同的t_dict表逻辑表 t_dict 对应3张真实表server-user对应的db_user.t_dictserver-order0对应的db_order.t_dictserver-order1对应的db_order.t_dict核心配置逻辑表 t_dict 对应3张真实表t_dict: actual-data-nodes: server-order$-{0..1}.t_dict,server-user.t_dict broadcast-tables[0]: t_dict完整配置文件spring: application: name: sharding-jdbc-dome profiles: active: dev shardingsphere: mode: type: Memory datasource: names: server-user,server-order0,server-order1 server-user: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33008/db_user?useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/Shanghai username: root password: 123456 server-order0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33016/db_order?useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/Shanghai username: root password: 123456 server-order1: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:33017/db_order?useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/Shanghai username: root password: 123456 props: sql-show: true rules: sharding: tables: t_user: actual-data-nodes: server-user.t_user t_order: actual-data-nodes: server-order$-{0..1}.t_order$-{0..1} database-strategy: standard: sharding-column: user_id sharding-algorithm-name: alg_mod table-strategy: standard: sharding-column: order_no sharding-algorithm-name: alg_hash_mod key-generate-strategy: column: id key-generator-name: alg_snowflake t_order_item: actual-data-nodes: server-order$-{0..1}.t_order_item$-{0..1} database-strategy: standard: sharding-column: user_id sharding-algorithm-name: alg_mod table-strategy: standard: sharding-column: order_no sharding-algorithm-name: alg_hash_mod key-generate-strategy: column: id key-generator-name: alg_snowflake t_dict: actual-data-nodes: server-order$-{0..1}.t_dict,server-user.t_dict sharding-algorithms: alg_inline_userId: type: INLINE props: algorithm-expression: server-order$-{user_id % 2} alg_mod: type: MOD props: sharding-count: 2 # 针对sharding-column: user_id字段对2取模 alg_hash_mod: type: HASH_MOD props: sharding-count: 2 # 针对sharding-column: user_id字段对2取模 key-generators: alg_snowflake: type: SNOWFLAKE # 绑定表指分片规则一致的一组分片表。 使用绑定表进行多表关联查询时必须使用分片键进行关联 # 否则会出现笛卡尔积关联或跨库关联从而影响查询效率。 binding-tables[0]: t_order,t_order_item # 去掉笛卡尔积的关联 broadcast-tables[0]: t_dict

相关新闻

终极风扇控制指南:如何使用Fan Control打造安静高效的Windows电脑

终极风扇控制指南:如何使用Fan Control打造安静高效的Windows电脑

终极风扇控制指南:如何使用Fan Control打造安静高效的Windows电脑 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_…

2026/10/15 16:10:20 阅读更多 →
Python自动化读取Chrome历史记录:SQLite数据库解析与数据导出实战

Python自动化读取Chrome历史记录:SQLite数据库解析与数据导出实战

1. 项目缘起:一个被忽视的数据金矿 作为一名经常和浏览器打交道的开发者,我发现自己有个习惯:每次想找回之前浏览过的一个有用网页,总得在Chrome历史记录里翻半天,或者依赖模糊的记忆去搜索。Chrome自带的搜索功能虽然…

2026/10/15 16:57:56 阅读更多 →
CTF Web安全入门:从信息搜集到漏洞利用的实战解析

CTF Web安全入门:从信息搜集到漏洞利用的实战解析

1. 项目概述:一次完整的CTF Web题解复盘 去年秋天,我作为校内战队的一员,完整地参与了MoeCTF 2021的线上赛。作为一场面向新生的入门级赛事,它的Web题目设计得非常友好,覆盖了从基础到进阶的常见漏洞类型,是…

2026/10/15 17:50:31 阅读更多 →

最新新闻

STM32+MPU6050姿态解算源码详解:I2C通信与DMP固件实战

STM32+MPU6050姿态解算源码详解:I2C通信与DMP固件实战

简介:面向嵌入式入门与进阶开发者,一套基于STM32F103C8T6与MPU6050的Keil完整工程可直接编译下载使用。工程自带标准外设库源码与头文件,并配套完整示例与说明文档,覆盖I2C读取MPU6050原始数据、姿态解算、串口输出及定时器、ADC、…

2026/10/16 17:52:20 阅读更多 →
超低成本3D打印SCARA机械臂:从运动学到固件的完整落地指南

超低成本3D打印SCARA机械臂:从运动学到固件的完整落地指南

简介:一套超低成本、可通过3D打印实现的开源SCARA四轴机械臂项目完整资料,适合机器人爱好者、创客与嵌入式系统学习者,用于在没有昂贵模具和工业设备的前提下自制性能可靠的装配机器人。压缩包共72个文件,大小约27.09MB&#xff0…

2026/10/16 17:52:20 阅读更多 →
Qt调用海康威视SDK:从登录到实时预览的完整实践指南

Qt调用海康威视SDK:从登录到实时预览的完整实践指南

简介:面向Qt开发者与安防集成人员,这是一套基于Qt 5.8与海康威视官方SDK的摄像头登录与预览完整工程示例,完整演示了设备注册、预览初始化、图像回调、停止预览与注销等核心流程,可直接仿照应用于网络摄像头客户端项目。资源共68个…

2026/10/16 17:52:20 阅读更多 →
图像亮度变换函数详解:从像素映射到伽马校正与对比度拉伸

图像亮度变换函数详解:从像素映射到伽马校正与对比度拉伸

做图像处理的同学应该都有这种经历:拿到一张偏暗的照片,第一反应就是调亮度、调对比度。但在工程上,这种“调”并不是简单地乘一个系数,而是通过亮度变换函数对像素灰度值做逐点映射。所谓亮度变换函数,本质上就是把输…

2026/10/16 17:52:20 阅读更多 →
128×128灰度图也能93%准确率:基于CNN的垃圾分类识别实战

128×128灰度图也能93%准确率:基于CNN的垃圾分类识别实战

简介:一份面向垃圾分类场景的深度学习算法研究论文资料,内容围绕生活垃圾分类图像识别展开。文档从城市化带来的垃圾处理需求切入,系统说明了为何源头分类重要,以及如何借助带标记的垃圾图像数据训练分类模型。作者将原始图像降维…

2026/10/16 17:52:20 阅读更多 →
Roblox技能系统设计:数据驱动与加权随机生成器实战

Roblox技能系统设计:数据驱动与加权随机生成器实战

在 Roblox 上做咒术回战题材的技能系统时,很多人会卡在一个相似的地方:想还原“乙骨”那种“下一招用什么完全无法预测”的战斗体验,结果只在客户端写了一个 math.random(1, 5) ,然后随机切换技能图标。等真正跑起来才发现&…

2026/10/16 17:51:19 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →