MySQL JSON数据索引优化:函数索引与生成列实战指南
1. 项目概述当JSON遇上索引在数据库的世界里JSON字段的引入曾一度让开发者又爱又恨。爱的是它那灵活到近乎“无模式”的数据存储能力恨的是查询性能常常成为瓶颈。想象一下你有一个用户配置表里面有个preferences字段存着用户的各种偏好设置比如主题颜色、通知开关、页面布局等全是JSON格式。当产品经理说“我们要找出所有开启了夜间模式的用户给他们推送一个新皮肤。” 你写了个WHERE查询结果发现全表扫描慢得让人想砸键盘。这就是我们今天要解决的问题如何给MySQL里的JSON数据加上索引让它跑得飞快。这不仅仅是加个索引那么简单。传统的B-Tree索引对规整的列友好但面对JSON这种层层嵌套、结构可能随时变化的“刺头”直接套用老办法是行不通的。MySQL从5.7版本开始原生支持JSON类型并提供了函数索引和生成列这两种“曲线救国”的方式来为JSON中的特定路径创建索引。理解这两种方法的原理、适用场景以及背后的权衡是高效使用JSON字段的关键。无论你是正在处理用户行为日志、产品属性集还是复杂的配置信息掌握给JSON加索引的技巧都能让你的应用性能提升一个档次。2. 核心思路与方案选型给JSON加索引核心思路是把JSON中我们关心的、经常用于查询条件的那个“值”提取出来变成一个可以被传统索引结构如B-Tree管理的规整列。MySQL主要提供了两种实现路径函数索引Functional Indexes和生成列Generated Columns。选择哪种取决于你的MySQL版本、对数据写入性能的要求以及对字段灵活性的考量。2.1 函数索引直达目标的快捷方式函数索引是MySQL 8.0.13版本引入的特性。它允许你直接为一个表达式的结果创建索引这个表达式通常就是用来提取JSON值的函数比如JSON_EXTRACT()或者其简写-、-。它的工作原理很直观当你创建索引时MySQL并不是存储原始JSON字符串而是存储你指定的函数例如JSON_EXTRACT(column, ‘$.path’)的计算结果。之后当你的查询条件使用了完全相同的函数表达式时优化器就能识别并利用这个索引。为什么选择它最大的优点是直接和简洁。你不需要修改表结构不需要增加额外的物理列。索引的定义完全基于你的查询需求是一种“按需创建”的索引。对于查询模式固定、且升级到了MySQL 8.0的场景这是首选方案。需要注意什么函数索引是“函数依赖”的。这意味着你的查询语句中的表达式必须和创建索引时的表达式完全一致MySQL优化器才能命中索引。JSON_EXTRACT(profile, ‘$.age’)和profile-’$.age’在逻辑上等价但在MySQL看来可能是不同的表达式后者可能无法使用为前者创建的索引。一致性是关键。2.2 生成列兼容性更好的稳定之选生成列是MySQL 5.7版本就支持的特性。你可以把它理解为表中的一个“虚拟”或“存储”列它的值由表中其他列通过一个表达式计算而来。我们可以创建一个生成列其表达式就是从JSON字段中提取值然后在这个生成列上创建普通的B-Tree索引。这里涉及到两种类型的生成列虚拟生成列VIRTUAL默认类型。列值不存储在磁盘上只在读取时根据表达式实时计算。节省存储空间但计算会带来额外的CPU开销。存储生成列STORED列值在数据插入或更新时计算并实际存储在磁盘上。消耗存储空间但读取速度快就像普通的物理列一样。为什么选择它最大的优势是兼容性好和灵活。从MySQL 5.7开始就可以使用覆盖更广。此外因为生成列就是一个普通的列你可以在上面创建任何类型的索引B-Tree FULLTEXT等也可以方便地在查询中直接引用它语义更清晰。对于需要兼容旧版本或者提取出的值会被非常频繁地查询和连接JOIN的场景存储生成列是一个更稳定的选择。需要注意什么选择虚拟列还是存储列是一个典型的“空间换时间”的权衡。存储列会增大表体积影响写入性能因为需要计算并存储虚拟列节省空间但影响读取性能。需要根据数据量、查询频率和更新频率来综合决策。2.3 方案对比与选型建议为了更清晰地做出选择我们可以从几个维度来对比特性维度函数索引 (MySQL 8.0)生成列 索引 (MySQL 5.7)核心原理为表达式结果创建索引创建虚拟/存储列再为其建索引表结构变更无需变更需要增加生成列存储开销仅索引本身虚拟列几乎无存储列额外存储数据写入性能影响较小仅维护索引虚拟列影响小存储列需计算并存储影响稍大查询兼容性要求查询表达式与索引定义严格一致查询可直接使用生成列名更灵活版本要求MySQL 8.0.13 及以上MySQL 5.7 及以上适用场景查询模式固定追求简洁已用MySQL 8.0需兼容旧版本提取字段需多处使用或参与连接个人选型心得在实际项目中我的选择策略通常是如果环境已是MySQL 8.0且查询条件单一明确优先使用函数索引。干净利落没有冗余列。如果需要兼容MySQL 5.7或者提取出的JSON属性会被频繁用于WHERE、ORDER BY、GROUP BY甚至JOIN条件我会选择使用STORED生成列。虽然增加了存储但它表现得就像一个真正的字段优化器更容易理解查询写法也更直观后续维护成本低。如果JSON路径提取非常复杂或计算成本高但查询频率极高STORED生成列用空间换时间是值得的。如果只是偶尔查询或者存储空间非常紧张可以考虑VIRTUAL生成列或者干脆不加索引依赖其他筛选条件。注意不要试图在原始的JSON列上直接创建普通索引如ALTER TABLE t ADD INDEX idx_json (json_column)这只会为整个JSON文档字符串创建索引对基于内部路径的查询几乎没有优化效果反而浪费空间。3. 实操详解两种索引的创建与使用理论说再多不如动手试一遍。我们假设有一个user_profile表其中profile字段是JSON类型存储了用户的详细信息。CREATE TABLE user_profile ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50), profile JSON, -- 存储JSON数据例如 {age: 25, address: {city: 北京}, preferences: {theme: dark}} created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );3.1 使用函数索引MySQL 8.0假设我们的高频查询是“找出所有年龄大于30岁的用户”。年龄信息存储在profile-’$.age’路径下。第一步创建函数索引我们为JSON_EXTRACT(profile, ‘$.age’)表达式的结果创建一个索引。这里推荐使用-运算符因为它提取的是去除引号的纯量值JSON_UNQUOTE(JSON_EXTRACT())的简写更符合数值比较的需求。-- 方法1使用 JSON_UNQUOTE(JSON_EXTRACT()) 的等价形式 - CREATE INDEX idx_profile_age ON user_profile ((profile-$.age)); -- 方法2显式使用 JSON_EXTRACT但注意后续查询需严格匹配 CREATE INDEX idx_profile_age_extract ON user_profile ((JSON_EXTRACT(profile, $.age)));第二步编写能命中索引的查询关键点在于查询条件中的表达式必须和索引定义中的表达式完全一致。-- 能命中 idx_profile_age 索引的写法 SELECT * FROM user_profile WHERE profile-$.age 30; -- 注意-返回的是字符串与数字比较时MySQL会做隐式转换但索引可能仍有效 -- 更优的写法使用 CAST 确保类型一致让优化器更容易选择索引 SELECT * FROM user_profile WHERE CAST(profile-$.age AS UNSIGNED) 30; -- 如果索引是方法2创建的则查询应为不推荐易出错 SELECT * FROM user_profile WHERE JSON_EXTRACT(profile, $.age) 30;第三步验证索引使用情况使用EXPLAIN命令查看查询执行计划。EXPLAIN SELECT * FROM user_profile WHERE CAST(profile-$.age AS UNSIGNED) 30;查看结果中的key列如果显示为idx_profile_age则说明索引命中成功。实操心得类型一致性至关重要-操作符返回的是TEXT类型。如果你要比较数值在条件中使用CAST进行显式类型转换不仅能避免隐式转换带来的性能损耗也能让优化器更确信地使用索引。表达式必须一字不差这是函数索引最“娇气”的地方。profile-’$.age’和JSON_UNQUOTE(profile-’$.age’)是等价的但如果你在查询中用了后者而索引是前者索引可能会失效。保持定义和查询的绝对一致是最安全的做法。3.2 使用生成列索引MySQL 5.7假设我们需要频繁根据用户所在城市profile-’$.address.city’进行查询和统计。第一步添加存储生成列我们添加一个city列其值来源于JSON字段。ALTER TABLE user_profile ADD COLUMN city VARCHAR(50) AS (profile-$.address.city) STORED; -- 使用 VIRTUAL 关键字则是虚拟列 -- ADD COLUMN city VARCHAR(50) AS (profile-$.address.city) VIRTUAL;第二步在生成列上创建普通索引现在city已经是一个标准的VARCHAR列了我们可以像对普通列一样创建索引。CREATE INDEX idx_user_city ON user_profile (city);第三步使用生成列进行查询查询时直接使用city列即可语法非常直观。-- 查询城市为‘北京’的用户 SELECT * FROM user_profile WHERE city 北京; -- 复杂的查询例如按城市分组统计用户数 SELECT city, COUNT(*) as user_count FROM user_profile GROUP BY city ORDER BY user_count DESC;使用EXPLAIN分析会发现查询直接使用了idx_user_city索引效率很高。实操心得选择STORED还是VIRTUAL对于city这种短文本且查询频繁的字段我通常选择STORED。因为磁盘空间在今天相对廉价而换取稳定且快速的查询性能是值得的。对于一些很长、很少被查询的JSON提取值可以考虑VIRTUAL。默认值问题如果JSON路径不存在例如某个用户的profile里没有address.city生成列的值会是NULL。这符合预期并且NULL值也可以被索引。修改JSON的影响如果你更新了profile字段那么对应的STORED生成列的值会自动重新计算并更新。这是一个原子操作但会有额外的性能开销。4. 高级场景与性能优化掌握了基础用法后我们来看看更复杂的情况和如何进一步提升性能。4.1 为JSON数组中的元素创建索引有时候JSON里包含的是数组。例如用户的标签tags: [“vip”, “early-adopter”, “tech”]。我们想快速找到带有“vip”标签的用户。函数索引方案MySQL 8.0MySQL提供了JSON_CONTAINS()函数来检查数组是否包含某个值。但直接为JSON_CONTAINS(tags, ‘“vip”’)创建函数索引其效用是有限的它更适用于检查数组是否包含特定值而非高效定位。更高效的做法是利用多值索引Multi-Valued Indexes这是MySQL 8.0.17为JSON数组引入的强大功能。它能为数组中的每一个元素都创建索引条目。-- 假设 profile 中有一个 tags 数组 CREATE INDEX idx_profile_tags ON user_profile ( (CAST(profile-$.tags AS CHAR(50) ARRAY)) ) USING BTREE; -- 查询时使用 MEMBER OF 或 JSON_OVERLAPS SELECT * FROM user_profile WHERE ‘vip’ MEMBER OF (profile-‘$.tags’); -- 或 SELECT * FROM user_profile WHERE JSON_OVERLAPS(profile-‘$.tags’, CAST(‘[“vip”]’ AS JSON));EXPLAIN会显示使用了idx_profile_tags索引。生成列方案MySQL 5.7对于旧版本实现类似功能比较麻烦。一种思路是将数组“展开”到另一张关系表中每行一个标签这更符合关系型数据库的设计范式。如果坚持用JSON可能需要全表扫描或依赖其他条件过滤。4.2 复合索引与索引覆盖当查询条件涉及多个JSON路径时可以考虑创建复合索引。使用生成列创建复合索引这是最直接的方式。例如我们经常按城市和年龄范围查询。-- 假设已有 city 生成列再创建一个 age 生成列 ALTER TABLE user_profile ADD COLUMN age INT UNSIGNED AS (CAST(profile-$.age AS UNSIGNED)) STORED; CREATE INDEX idx_city_age ON user_profile (city, age); -- 查询城市为‘上海’且年龄大于25的用户 SELECT username FROM user_profile WHERE city ‘上海’ AND age 25;如果索引idx_city_age包含了查询所需的所有列这里是city,age, 并且SELECT的username和id包含在二级索引叶子节点或通过主键回表性能会非常好。函数索引的复合索引在MySQL 8.0中也可以创建基于多个表达式的函数索引。CREATE INDEX idx_func_composite ON user_profile ( (profile-$.address.city), (CAST(profile-$.age AS UNSIGNED)) );索引覆盖扫描如果查询只需要返回被索引的列MySQL可以仅通过扫描索引就完成查询避免回表这称为覆盖索引。对于生成列上的索引这很容易实现。对于函数索引如果SELECT的列就是索引表达式本身也可能实现覆盖扫描。4.3 索引维护与空间考量索引大小JSON路径可能很长尤其是嵌套深的路径。为这样的路径创建函数索引或生成列特别是STORED索引键的长度可能很大。MySQL有索引键长度限制通常是3072字节。如果超限创建会失败。可以考虑使用SUBSTRING或只提取部分值作为索引。写入性能每增加一个索引尤其是STORED生成列上的索引都会降低INSERT、UPDATE、DELETE的速度因为需要维护更多的数据结构。需要评估读写比例。统计信息对于函数索引和生成列MySQL会收集其统计信息以帮助优化器。在数据分布发生重大变化后对基表执行ANALYZE TABLE命令更新统计信息有助于优化器做出正确的索引选择。5. 常见问题与排查技巧实录在实际使用中你肯定会遇到索引“看起来”建了却没用上的情况。下面是一些踩坑记录和排查方法。5.1 为什么我的索引没有生效这是最常见的问题。请按以下清单排查检查MySQL版本确认函数索引要求8.0.13生成列要求5.7。验证表达式一致性针对函数索引使用SHOW CREATE TABLE查看索引的精确定义确保你的查询条件中的表达式与之一模一样包括函数名、参数、空格。profile-’$.age’和profile-’$.age ‘多一个空格都可能被MySQL视为不同。检查数据类型-返回的是字符串。如果你在比较数字例如WHERE profile-’$.age’ 30MySQL需要将字符串转换为数字这可能导致索引失效。使用CAST进行显式转换。使用EXPLAIN分析这是最权威的手段。关注type列ref,range优于index和ALLkey列显示使用的索引名Extra列避免Using filesort,Using temporary。数据选择性如果某个年龄值比如age0占据了90%的数据那么查询age0时优化器可能认为全表扫描比用索引回表更划算。索引对高选择性的数据效果才好。函数导致索引失效在索引列上使用函数会使索引失效这对生成列也一样。例如如果你在city生成列上创建了索引但查询写成了WHERE UPPER(city) ‘BEIJING’索引就无法使用。5.2 如何为深层次嵌套的JSON路径建索引路径如$.a.b.c.d.e。方法没有区别直接在函数索引或生成列表达式中写出完整路径即可。但要注意索引键长度限制。如果路径名本身很长或者提取出的值很长可能超过限制。可以考虑是否真的需要这么深的路径作为索引或者只提取一部分例如用SUBSTRING(profile-’$.a.b.c.d.e’, 1, 100)。5.3 虚拟列VIRTUAL和存储列STORED在查询性能上的真实差异在简单查询中如果虚拟列的计算成本很低如提取一个顶层属性性能差异可能微乎其微因为现代CPU很快。但在以下场景差异会显现复杂表达式如果生成列的计算涉及复杂的JSON解析或字符串处理VIRTUAL列在每次查询时都要计算而STORED列只需计算一次。大数据量扫描当查询需要扫描大量行如全表扫描或索引扫描时VIRTUAL列的实时计算开销会累积明显比读取STORED列的存储值要慢。覆盖索引如果查询只需要虚拟列本身且该列上有索引MySQL有时可以直接从索引中读取计算好的值对于函数索引或快速计算此时性能可能接近。个人建议如果不确定且存储空间不是瓶颈优先使用STORED列。它的行为更可预测性能更稳定。可以在测试环境中用真实数据量进行基准测试用SELECT SQL_NO_CACHE …来对比查询时间。5.4 索引创建失败错误 3506 (HY000)在创建函数索引时你可能会遇到ERROR 3506 (HY000): In order to create a functional index, the functional key part must be wrapped in parentheses.这意味着你没有将表达式用括号括起来。正确的语法是-- 错误 CREATE INDEX idx_wrong ON t (profile-$.age); -- 正确 CREATE INDEX idx_correct ON t ( (profile-$.age) );双括号是必须的外层是CREATE INDEX的列列表括号内层是标识函数表达式的括号。给MySQL的JSON加索引从最初的束手无策到如今的游刃有余关键在于理解其“曲线救国”的本质将非结构化的数据点转化为关系型数据库擅长的结构化索引列。函数索引提供了语法糖般的便捷而生成列则展现了更好的兼容性和灵活性。在实际项目中我通常会结合表的数据量、查询模式、团队的技术栈和数据库版本来做选择。没有银弹只有最适合当前场景的权衡。最后记住任何索引都不是免费的在享受查询加速的同时也要时刻关注其对写入性能和存储成本的影响。在创建索引前后用EXPLAIN命令验证用真实负载测试是保证效果的不二法门。

相关新闻

ThingsBoard告警规则实战:从状态机到复杂事件处理

ThingsBoard告警规则实战:从状态机到复杂事件处理

1. 项目概述:从“数据展示”到“主动预警”的跨越 如果你用过ThingsBoard,大概率会觉得它是个挺不错的物联网数据可视化平台。设备数据上来了,能看个曲线图,做个仪表盘,挺直观。但做项目久了你会发现,光“看…

2026/10/17 13:14:32 阅读更多 →
Ubuntu 22.04 安装 ROS2 Humble 完整指南:从零搭建机器人开发环境

Ubuntu 22.04 安装 ROS2 Humble 完整指南:从零搭建机器人开发环境

1. 项目概述:为什么要在Ubuntu 22.04上安装ROS2? 如果你正在接触机器人开发,或者对自动驾驶、无人机、机械臂这些领域感兴趣,那么ROS2这个名字你肯定不陌生。它不是一个操作系统,而是一个机器人操作系统框架&#xff0…

2026/10/17 13:14:51 阅读更多 →
MyBatis-Plus逻辑删除机制深度解析与四种绕过方案实践

MyBatis-Plus逻辑删除机制深度解析与四种绕过方案实践

1. 项目概述:为什么我们需要“绕过”逻辑删除?在基于Spring Boot和MyBatis-Plus(后文简称MP)的项目里,逻辑删除几乎是标配功能。它通过在数据库表里加一个deleted字段(比如is_deleted或del_flag&#xff09…

2026/10/17 13:14:32 阅读更多 →

最新新闻

黑通道功能安全协议:从原理到落地的完整指南

黑通道功能安全协议:从原理到落地的完整指南

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

2026/10/19 1:34:19 阅读更多 →
JavaWeb课设实战:Filter+Session权限控制与文件上传避坑指南

JavaWeb课设实战:Filter+Session权限控制与文件上传避坑指南

简介:这是一套基于JavaWeb技术栈开发的作业管理网站完整源码,面向计算机、通信、人工智能等专业的本科生及课程设计指导教师,用于支撑期末大作业、课程设计或毕业设计实践。系统采用JSPServletDruid连接池MySQL架构,涵盖用户登录、…

2026/10/19 1:34:19 阅读更多 →
助农小程序毕设技术选型:Java+MySQL+微信原生实战指南

助农小程序毕设技术选型:Java+MySQL+微信原生实战指南

简介:本资源是一套面向计算机专业本科生的毕业设计级微信小程序开发实战项目,聚焦助农扶贫场景,解决传统APP开发成本高、用户安装意愿低、存储占用大等痛点,适用于Java后端与小程序全栈学习者。压缩包共1205个文件,涵盖…

2026/10/19 1:34:19 阅读更多 →
Unity动态字体实战:用系统字体动态生成TMP SDF资产

Unity动态字体实战:用系统字体动态生成TMP SDF资产

简介:UnityNativeOSFont是一套面向Unity开发者的开源插件方案,核心解决TextMeshPro无法直接调用操作系统本地字体的问题。它通过C#脚本在运行时获取系统字体列表,并转换为TMP可用的动态字体资源,适合需要动态切换字体、本地化显示…

2026/10/19 1:34:19 阅读更多 →
嵌入式C指针入门到实践:寄存器映射、野指针与函数指针全解析

嵌入式C指针入门到实践:寄存器映射、野指针与函数指针全解析

1. 为什么要跟指针死磕:嵌入式里的那些绕不开的场景做嵌入式这行,早晚有一天你会被指针逼到墙角。我最早踩坑是在调试一块串口板卡的时候,外设寄存器手册里写着一堆偏移地址,代码里全是一长串强制类型转换的宏,不弄懂指…

2026/10/19 1:34:19 阅读更多 →
RAM盘与DISK盘真实性能对比测试方法

RAM盘与DISK盘真实性能对比测试方法

1. 项目概述:为什么一个“测速”动作值得花半天时间认真对待你有没有遇到过这样的情况:明明手里的固态硬盘标称读写速度是3500MB/s,但实际拷贝一个20GB的工程文件却要等三分钟?或者在做视频剪辑时,预览一帧要卡顿两秒&…

2026/10/19 1:33:18 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →