尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
PolarDB-X向量检索实战:关系型数据库一体化混合查询
1. 为什么我会盯上“关系型数据库跑向量”这条路先交代一下背景。我这边的业务是做电商场景的商品语义搜索和个性化推荐结构化数据和向量数据天然混在一起商品有类目、价格、库存、上下架状态这些是典型的关系型数据同时我们又用Embedding模型把商品标题、卖点描述转成了高维向量用来做同款识别、“找相似”和模糊语义召回。最开始的做法跟大多数人一样业务库用MySQL向量库单独上一套Milvus或者ES插件。数据从MySQL同步到向量库中间还要维护一套ID映射查询的时候先查向量库拿到候选ID列表再回MySQL捞详情、做过滤、做排序。这套“拼装式”架构跑了小半年问题开始集中爆发数据一致性问题向量库同步有延迟商品下架了向量库里还留着召回结果全是死链。查询链路太长一次完整检索要跨两个系统网络开销和序列化开销高P95经常飙到几百毫秒以上。运维成本翻倍两套系统要分别做监控、备份、扩缩容出问题还要两头排查。所以当看到PolarDB-X这类分布式关系型数据库开始原生支持向量检索时我的第一反应是这可能是把“数据孤岛”问题从根上解决的机会。毕竟关系型数据库已经管好了事务、索引、权限、备份如果在同一套SQL引擎里直接跑向量索引那么“商品”的行数据和“商品向量”的检索就能放到同一个事务里强一致、单链路、一套运维这种诱惑对业务方来说太直接了。当然我也清楚一体化方案不是银弹向量检索的某些极端场景比如十亿级纯向量检索、需要极低延迟的大规模ANN搜索专用向量库依然有优势。但这篇文章的主题不是“谁替代谁”而是结合我自己做技术选型的完整过程聊清楚PolarDB-X向量检索怎么用、参数怎么调、什么时候选它、什么时候别选它。如果你正在纠结“要不要把向量检索并入关系型数据库”这篇文章应该能帮你省不少调研时间。2. 一体化方案的核心思路为什么“关系型向量”放在一起是可行的2.1 从架构演进的角度看一体化的必然性过去几年向量检索类需求暴涨很大程度是RAG和语义检索应用带起来的。于是业界出现了大量独立的向量数据库产品这套路跟当年“为了大数据专门上Hadoop”“为了缓存专门上Redis”很像——遇到新问题就上专用系统结果系统越堆越多链路越来越长最终复杂度失控。一体化方案的本质是把“多元数据”放回“同一套数据库”里。PolarDB-X本身就是兼容MySQL协议的分布式关系型数据库它对标的是单机MySQL在数据量、并发、扩展性上的上限问题也就是说它首先是给人“存关系型数据”用的。在其之上增加向量类型、向量索引和向量检索算子意味着你不再需要把数据拆成“结构化一半”和“向量一半”再放两个地方而是在一张表里既能存ProductID、CategoryID、Price又能存TitleEmbedding这个VECTOR类型的列。这个设计思路我觉得很聪明的地方在于关系型数据库已经有成熟的代价优化器、执行引擎和事务管理向量能力只是作为“一类新的数据类型一类新的索引方法一组新的算子”接入原有SQL生态。用户不需要学习新的API、新的查询语言还是写SQL只是多了VECTOR_DISTANCE()这样的函数和VECTOR INDEX这样的语法。对团队里原本就熟悉MySQL的开发者和DBA来说学习成本极低。2.2 一体化方案解决的核心问题一致性、写入实时性与运维极简为什么“两套系统”的痛点在一体化方案里能解决得从三个维度拆开看数据一致性。独立向量库方案里业务先写MySQL再通过同步任务写向量库本质是两份数据、两套生命周期。只要中间有同步逻辑就有窗口期和失败重试的问题。一体化方案里向量的写入和结构化数据的写入是同一个事务INSERT一条商品记录向量字段跟着一起提交要么都成功要么都失败不存在“商品已经上架但向量还没到位”的中间状态。这对电商场景尤其重要因为商品状态变化极其频繁。写入实时性。原来的同步链路通常是批量、异步的秒级甚至分钟级延迟。而一体化方案的写入就是数据库本身的写入路径事务提交之后查询立即可见。在商品秒杀、价格变动、库存归零这类实时性要求很高的场景里一体化方案能把“状态变化”和“召回避坑”的间隔压缩到极致。运维复杂度。这点对中小团队特别友好。一套数据库解决全部问题备份、监控、扩容、权限管理都只需要关注一套系统。不用再维护两个集群的数据同步任务不用反复检查两边数据是否对齐出问题时也不用跨团队扯皮。3. PolarDB-X向量检索核心能力拆解类型、索引与查询语法3.1 向量数据类型与存储方案PolarDB-X的向量能力落地在MySQL兼容协议之上所以在建表语法上非常自然。最核心的数据类型就是VECTOR。CREATE TABLE product ( id BIGINT PRIMARY KEY, category_id INT NOT NULL, title VARCHAR(256) NOT NULL, price DECIMAL(10,2) NOT NULL, status TINYINT NOT NULL DEFAULT 1, title_vector VECTOR(768) NOT NULL, KEY idx_category_price (category_id, price) ) ENGINE InnoDB;注意VECTOR(768)这里的维度必须跟你用的Embedding模型输出维度严格一致。比如你用OpenAI的text-embedding-3-small输出是1536维用BGE系列的bge-large-zh输出是1024维用一些中文电商领域微调的小模型常见的有256维、512维、768维。建表前务必确认好模型的向量维度一旦表建好了维度改不了只能重建表。浮点类型上我实际测下来PolarDB-X的VECTOR类型底层会做一定的压缩编码不是简单粗暴地每维存一个FLOAT。这里给个小建议业务上如果只是做候选召回不要求算相似度分数参与最终排序可以优先选择低精度存储能显著减少磁盘和内存占用。具体类型选择建议参考官方文档但核心记住一句话精度和存储是有直接兑换关系的先用低精度跑通流程真正确认精度不够了再升级而不是一上来就上最高精度。3.2 向量索引HNSW为主暴力检索兜底向量索引是向量检索的灵魂。关系型数据库做向量检索最朴素的办法是暴力扫描计算出查询向量跟全表向量的距离再排序取Top-N。这个方案的召回率是100%但性能随着数据量线性下降百万行级别就明显吃力了。PolarDB-X提供了更实用的HNSWHierarchical Navigable Small World索引。你可以把它理解成一种“多层跳表图结构”的索引它在内存里维护了一个分层的近邻图查询时从顶层开始逐层往下走每层只访问少量节点从而把检索时间复杂度从O(N)降到O(log N)级别。ALTER TABLE product ADD VECTOR INDEX idx_title_vector (title_vector) ALGORITHM HNSW;建索引时可以配置HNSW的关键参数M每个节点的最大连接数、efConstruction建索引时的搜索宽度、efSearch查询时的搜索宽度。这些参数我后面单独讲调优经验这里先记住一个原则HNSW是“近似”最近邻搜索不是精确搜索它用微小召回率损失换取数量级的速度提升绝大多数业务场景完全够用。3.3 向量检索的SQL语法让查询融入标准SQL这是PolarDB-X一体化方案最吸引我的地方——向量检索不是独立的一套API而是直接长在SQL里。最基础的相似度查询可以这样写SELECT id, title, price, VECTOR_DISTANCE(title_vector, :query_vector, COSINE) AS score FROM product WHERE status 1 ORDER BY score ASC LIMIT 10;VECTOR_DISTANCE()函数接受三个参数向量列、查询向量、距离度量方式。这里支持COSINE、L2、INNER_PRODUCT等常用度量。注意不同度量函数对ORDER BY的方向要求不一样COSINE和L2是距离越小越相似INNER_PRODUCT是值越大越相似或者说分数越高越好。排序方向搞反了召回结果会惨不忍睹。更强大的地方在于向量距离计算可以直接作为过滤条件组合结构化条件SELECT id, title, price, VECTOR_DISTANCE(title_vector, :query_vector, COSINE) AS score FROM product WHERE category_id 10 AND price BETWEEN 100 AND 500 AND status 1 AND VECTOR_DISTANCE(title_vector, :query_vector, COSINE) 0.3 ORDER BY score ASC LIMIT 20;这条SQL同时做了三件事用category_id和price做结构化过滤用向量距离做语义相似过滤用ORDER BY score做排序。在传统“MySQL向量库”架构里这条查询至少得拆成两步来写代码现在一条SQL搞定应用层代码量直接减半。4. 实操过程从建表到跑通一条混合检索4.1 写入性能的实测体会我拿真实业务数据做了压测。数据规模是100万条商品记录每条记录带一个768维的向量单条向量大小约3KB整张表原始数据大约3GB加上HNSW索引后的内存开销大约在6GB左右。用PolarDB-X分布式实例3个DN节点每个节点分配4C8G。批量写入方面实测单条INSERT大概在800到1000 TPS之间如果改成批量提交每条INSERT包含100行吞吐能推到接近2万行每秒。这里有个经验向量写入务必用批量提交单条插入的Commit开销会被向量编码和索引更新放大性能差一个数量级。HNSW索引构建建议采用“先写入后建索引”的策略。也就是说先把全量数据INSERT进去再执行ALTER TABLE ADD VECTOR INDEX。在100万行数据规模下HNSW索引构建实测耗时约8到12分钟取决于M和efConstruction的配置。别在数据还没导完的时候就开始建索引否则每次写入都在实时更新索引导入效率会非常难看。4.2 混合查询示例与执行计划解读这里我拿一个实际业务查询来演示用户搜索“黑色运动鞋”Embedding模型产出一个768维向量同时希望在类目“运动鞋”下价格在200到800之间只要上架商品按语义相似度返回前20条。对应的SQL如下SELECT id, title, price, score FROM ( SELECT id, title, price, VECTOR_DISTANCE(title_vector, :query_vector, COSINE) AS score FROM product WHERE category_id 1024 AND price BETWEEN 200 AND 800 AND status 1 ORDER BY VECTOR_DISTANCE(title_vector, :query_vector, COSINE) LIMIT 100 ) t ORDER BY score LIMIT 20;写个子查询的原因是为了先做结构化过滤缩小向量检索的候选集。PolarDB-X的优化器会自动识别VECTOR_DISTANCE和VECTOR INDEX但候选集越小检索性能越好。我实测对比过全表直接向量检索P95延迟在45毫秒左右先按category_id price过滤出约5万条候选再做向量检索P95延迟降到17毫秒。差距很明显。执行计划怎么看用EXPLAIN查看执行计划重点确认向量索引有没有被真正用到。正常情况下计划里会出现VectorIndexScan或类似的节点如果看到的是TableScanComputeDistance说明优化器没走索引这时候要检查SQL写法或者索引定义是否有问题。4.3 距离度量的选择逻辑和排序方向距离度量方式看似小事选错影响很大。我总结的选型逻辑度量方式语义适用场景ORDER BY方向COSINE计算夹角余弦归一化后等价于内积文本语义匹配、商品相似度最推荐默认使用ASC距离小相似度高L2欧氏距离绝对距离对向量模长敏感图像特征、规范化好的EmbeddingASCINNER_PRODUCT点积值越大越相似推荐系统、CTR预估场景分数本身有业务含义DESC实际业务里如果向量已经做了归一化处理比如很多Embedding模型输出的就是单位向量COSINE和INNER_PRODUCT在排序结果上是完全等价的只是分数的数值范围不同。但如果向量模长携带业务信息比如流行度被编码进向量模长那就不能用COSINE要用INNER_PRODUCT。这个细节需要你对自己用的Embedding模型足够了解别想当然。5. 方案的短板与边界条件5.1 什么情况下一体化方案会露怯尽管PolarDB-X做一体化思路很好但我踩过几次坑之后明确意识到它不适合所有场景。首先是超大规模纯向量检索场景。如果你的业务是十亿级别的指纹检索、以图搜图、或者大规模去重且结构化过滤条件很少那么专用向量数据库比如Milvus、Qdrant这类分布式向量库在索引分片、GPU加速、高并发吞吐上有更深的优化这毕竟是它们专注的领域。PolarDB-X的定位是“关系型数据库向量扩展”它的核心战场是“结构化和向量混在一起查询”的业务不是“极限向量搜索”。其次是内存开销的控制难度。HNSW索引需要常驻内存才能发挥检索性能维度越高、数据量越大内存占用就越夸张。768维向量100万条数据索引内存大约4到5GB如果是千万级那就是40到50GB内存只给索引用。在预算有限的情况下这比独立向量库用磁盘索引内存缓存的组合要“贵”不少。5.2 和独立向量库、ES插件的三方案对比为了帮你做决策我用一个对比表把三套主流方案列清楚对比维度PolarDB-X一体化方案独立向量数据库Milvus等MySQL/PostgreSQL向量插件数据一致性强一致同一事务需同步弱一致需同步弱一致查询链路单库单查询多系统拼装多系统拼装学习成本低MySQL语法即可中新API新概念低到中取决于插件成熟度结构化过滤能力强SQL原生支持弱通常依赖标量过滤但能力有限中能力受插件限制大规模纯向量检索中适合百万到千万级强支持十亿级较弱运维成本一套系统至少两套系统至少两套系统事务与回滚完整支持不支持或很弱完整支持从我自己的判断角度来说如果业务里向量检索只是“检索链路中的一个环节”并且你已经深度依赖MySQL生态那PolarDB-X的一体化思路是最省心的选择。如果你做的是以向量检索为核心的独立系统比如一个纯“AI搜索服务”那专用向量库可能更合适。核心判断标准就是一条你的数据里结构化条件和向量条件是不是天生绑定的如果绑定选一体化如果不绑定选专用向量库。6. 选型决策点5个必须提前想清楚的问题6.1 数据规模是否在可控范围内向量检索的甜蜜区在一体化方案里大概是百万到千万级。先算一笔账一个768维的FLOAT数组单条向量3KBHNSW索引的内存占用大约是原始向量大小的1.5到2倍。以此推算500万条数据大约需要原始数据15GB索引内存22GB这个量级在分布式实例上是可行的。但如果目标是5000万条以上就需要认真评估扩展成本了大概率要涉及专项优化甚至专属集群成本和配置复杂度都会明显上升。这里强烈建议先拿TOP-N检索的召回率做一个量化验收抽取1万条数据把HNSW结果和暴力扫描结果做比对算出召回率是否在99%以上。通常efSearch调到合理值后这个指标能做到但如果模型分布有问题这个测试会帮你提前发现问题而不是上线以后被业务吐槽。6.2 跨多个维度的“混合过滤排序”权重怎么设计一体化方案里最容易被忽略的是这层逻辑向量距离只是排序的一个维度业务规则还得叠加。比如一个商品要同时满足“库存正常、上架、品牌白名单、按综合分排序”这个综合分可能是“0.7×语义相关度 0.3×销量归一化值”且销量还是动态变化的。在纯SQL里你可以这样写SELECT id, title, price, 0.7 * (1 - VECTOR_DISTANCE(title_vector, :query_vector, COSINE)) 0.3 * normalized_sales AS final_score FROM product WHERE status 1 AND stock 0 ORDER BY final_score DESC LIMIT 50;关键在于混合排序的计算必须放到数据库里做才能在库内同时拿到两个数据源向量分数和销量字段。如果你的业务需要非常复杂的个性化排序模型已经超出了一条SQL能表达的范畴那就要预留“向量检索取回Top-200再做二次精排”的API接口。这个决策也要提前想清楚否则改架构的代价后面会很大。6.3 事务与向量写入的冲突怎么处理关系型数据库的强事务能力在向量场景里也是一把双刃剑。如果你在事务里大量写入向量比如每次交易同时更新向量InnoDB的MVCC机制和HNSW索引更新之间会有明显的磁盘和内存竞争。我的经验是把“纯写入向量”和“业务事务”尽量拆开。向量更新走批量作业比如每小时跑一次Embedding刷新而业务事务里只更新结构化字段。如果实时性要求高至少也要用批量INSERT ... ON DUPLICATE KEY UPDATE减少提交次数。6.4 SQL兼容性和团队技术栈的匹配度PolarDB-X兼容MySQL协议这一点在团队招聘和上手成本上非常加分。团队里只要有熟悉MySQL的DBA或后端开发基本不需要额外培训。对比之下很多专用向量数据库是自研API调试工具、监控体系都不成熟出了问题连日志都看不明白。选型时一定要考虑所在团队的既有技术栈部署一套全新技术体系的学习成本和维护成本往往比数据库本身的差价更高。6.5 升级、扩展和生态迁移的成本约束还有一个常被忽略的点从其他数据库迁移到PolarDB-X要关注分布式表的拆分键设计。向量检索表最好按照category_id这种容易关联业务的字段做分区因为混合查询通常需要“同一分片内完成结构化过滤向量计算”如果查询条件跨越多个分片会有数据聚合开销。选型阶段就要把分区键定好否则后面数据量上来再改分区策略代价可能是一次全量重建。7. 索引调优与常见坑实测三个月的心得记录7.1 HNSW参数到底怎么调我在生产环境里用的HNSW配置参考如下参数说明我的初始配置调优后配置效果M每个节点的最大连接数1632连接数越大图越密召回越准内存占用越高32是兼顾召回和内存的常用值efConstruction建索引时的搜索宽度100200建索引越宽图质量越高但构建时间翻倍efSearch查询时的搜索宽度50100查询宽度越大召回越好但延迟线性上涨实际调优心得在768维、100万行规模下把efSearch从50调到100召回率从96%提升到99.2%P95延迟从15毫秒涨到28毫秒。如果业务对延迟不算极端敏感efSearch100是性价比极高的配置。日常查询不建议超过200因为收益开始递减延迟却会明显失控。另外M和efConstruction都没必要在生产调整得太激进索引建立之后它们就固定下来了想要更好的召回率优先调efSearch这个值在查询时是动态生效的。7.2 索引构建慢、查询走了全表扫描这是最常见的踩坑点。我在联调阶段遇到过一次表里有100万行查询却走了全表扫描单次查询耗时500毫秒以上。排查思路很简单SHOW INDEX FROM product;确认向量索引是否建成。EXPLAIN SELECT ...查看执行计划有没有走VectorIndexScan节点。检查SQL里是否对向量列做了函数包裹。比如VECTOR_DISTANCE(normalize(title_vector), :query_vector, COSINE)这种写法一旦把向量列包进函数里索引就失效了优化器只能全表扫。教训向量列是索引列不要在SQL里对向量列做任何函数变换要在写入前就把归一化做好。7.3 召回结果里有“脏数据”怎么办这通常不是数据库的问题而是Embedding模型的问题。初期我遇到过两条完全不相干的商品比如“手机壳”和“香蕉”向量相似度却异常高。原因是我们用的Embedding模型在特定领域样本上覆盖不够向量空间没有把这两个类别分开。这类问题的排查手段是把异常的相似对捞出来做一个向量PCA降维可视化看看是不是模型本身的分布有问题。如果是要么换模型要么在查询SQL里强制增加结构化条件比如限定分类、品牌来兜底。向量相似度只是召回手段不要把它当成业务规则的替代品。正确姿势是“向量粗排业务规则精排”而不是“向量一锤定音”。7.4 高并发下延迟抖动明显压测发现在100 QPS以内P95稳定在20毫秒上下上到500 QPSP95翻倍到40毫秒多2000 QPS时P95接近100毫秒。主要瓶颈在HNSW索引的并发访问控制。这个阶段可以考虑增加只读副本分担查询流量。把efSearch从100降回50牺牲一点召回换延迟。对高热度查询做结果缓存比如热门搜索词前几页的Top-50结果可以极大缓解峰值压力。7.5 批量删除和更新场景要注意什么向量索引不支持高频的单条DELETE并实时压缩内部会形成“墓碑”逻辑删除累积太多会导致索引膨胀和查询性能下降。如果业务经常需要批量删除商品比如每天清理下架商品最好在低峰期执行一次索引重建ALTER TABLE ... DROP VECTOR INDEX后重新建索引把这个操作做成周期性任务。否则三个月不重建检索性能基本会掉一半。8. 写在最后的个人体会这套一体化方案我已经在测试环境和一个小规模生产项目上跑了三个多月总体感受是“方向对了但别把它神化”。对我这种既不想维护两套系统、又想让开发团队继续写SQL的人来说PolarDB-X把向量检索融入关系型数据库的做法确实解决了实际痛点一致性不再靠同步任务保障查询链路短了一半运维也省心了不少。结构化条件和向量条件的联合查询一条SQL就能表达清楚这在以前是不可想象的。但这不意味着你可以完全抛弃对向量检索原理的理解。恰恰相反正是因为向量能力被封装到了SQL里反而更容易让人忽略背后的索引代价、内存消耗和参数调优。在我见过的问题案例里绝大多数“向量检索慢”“召回差”都不是数据库本身的问题而是建模和参数配置的问题——向量维度选得太大、Embedding模型没经过领域适配、HNSW参数拍脑袋定、SQL写法让索引失效。这些坑跟数据库选型无关跟“你有多了解你自己的数据”有直接关系。最后分享一个小技巧无论你最后选什么方案都强烈建议先搭一个最小验证环境把“建表→导数据→建索引→混合查询→性能压测”这条链路完整跑一遍拿真实数据和真实查询做验证。选型文档写得再漂亮都不如一个真实的P95延迟数字来得可靠。我这个验证环境跑了两周就把原来“上独立向量库”的团队决策彻底推翻了。选型这件事永远是数据说话不是概念说话。
RELATED

相关推荐

电子元器件视觉质检系统:YOLO小目标检测与大模型语义决策融合

电子元器件视觉质检系统:YOLO小目标检测与大模型语义决策融合

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

📅 2026/9/11 11:28:47
麦克风采集链路的硬件、采样与编码三层技术解析

麦克风采集链路的硬件、采样与编码三层技术解析

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

📅 2026/9/11 11:28:47
高性能服务器必知:TCP/IP协议栈底层逻辑与内核调优实战

高性能服务器必知:TCP/IP协议栈底层逻辑与内核调优实战

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

📅 2026/9/11 11:28:47
MORE NEWS

更多资讯

📰

MODBUS RTU协议详解:从报文解析到CRC16校验与RS485调试实战

作为常年泡在工控调试现场的人,我对MODBUS协议算是再熟悉不过了。这个1979年由Modicon公司提出的串行通信协议,四十多年过去了,居然还是工业自动化领域最通用的“普通话”——PLC、触摸屏、变频器、温控表、伺服驱动器、智能电表,…

📰

树莓派Pico ADC深度解析:硬件限制、MicroPython陷阱与实时采集实战

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

📰

如何用 Instruments 与 FlameGraph 工具为 iOS/macOS 上的 Flutter 应用生成火焰图

如何用 Instruments 与 FlameGraph 工具为 iOS/macOS 上的 Flutter 应用生成火焰图 【免费下载链接】flutter Flutter makes it easy and fast to build beautiful apps for mobile and beyond 项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter 当你需…

📰

Nginx UDP事件处理框架源码深度拆解:从收包路径到高性能设计

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

📰

三节点Hadoop分布式集群搭建实战:从部署到踩坑全记录

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

📰

Vue+Spring Boot前后端分离实战:减肥网站开发与部署踩坑全记录

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

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬