浏览知识库目录

MySQL

视图、JSON、生成列与服务端对象

使用视图、JSON、生成列、全文索引、触发器、存储程序与事件,并明确服务端逻辑的可见性和迁移成本,并在可重复的 StudyStore 实验中验证结果、失败边界与恢复方式。

视图、JSON、生成列与服务端对象

MySQL 能在服务端保存视图、生成列、触发器和存储程序,也提供 JSON 与全文能力。它们能靠近数据执行,但会增加隐藏行为、权限和迁移复杂度。选择前应问:约束是否必须在所有写入路径生效,逻辑是否需要独立版本与测试,调用方能否观察失败。


一、学习目标

  • 用视图封装稳定投影而非掩盖错误模型
  • 查询 JSON 并通过生成列建立索引
  • 理解 MySQL 9.7 JSON Duality 的定位
  • 评估全文索引与普通 LIKE 的边界
  • 谨慎使用触发器、存储程序和事件调度器

二、视图与安全边界

视图可提供稳定列集合:

CREATE VIEW paid_order_summary AS
SELECT id, customer_id, total_amount, paid_at
FROM orders
WHERE status = 'paid';

视图不保存普通查询结果,优化器会合并或物化。它可以配合权限隐藏列,但 SQL SECURITY 的定义者/调用者语义必须审查,避免高权限定义者视图扩大访问。复杂嵌套视图会让执行计划和依赖难以追踪。


三、JSON 与生成列

商品附加属性可存 JSON:

attributes JSON NOT NULL,
color VARCHAR(30)
  GENERATED ALWAYS AS (
    JSON_UNQUOTE(JSON_EXTRACT(attributes, '$.color'))
  ) STORED,
INDEX idx_products_color (color)

写入前用 CHECK 或应用验证期望结构。JSON 路径区分缺失、JSON null 和 SQL NULL。频繁连接、约束和排序的字段应提升为普通列,不能长期依赖任意 JSON 形状。


四、JSON Duality

MySQL 9.7 的 JSON 关系双重视图能力用于在关系表与 JSON 文档表示之间建立受定义映射。它不是把任意 JSON 自动变成良好关系模型,也不替代主外键、事务和权限设计。

本系列只介绍定位和只读实验:先由关系模型定义键和关系,再按官方 9.7 语法创建 duality view,验证文档往返和并发规则。由于 8.4 不具备相同能力,兼容路径继续使用普通视图与 JSON 函数。


五、全文索引

FULLTEXT 适合自然语言词项搜索,行为受解析器、停用词、最小词长和语言影响。它不是通用子串匹配,也不等于专业搜索引擎。

为商品名称和描述建立全文索引前,准备中文、英文、短词、停用词与更新测试,理解所选解析器。简单 SKU 前缀仍使用 B+Tree 范围,LIKE '%term%' 通常无法使用普通前缀索引。


六、触发器、存储程序与事件

触发器适合所有写入路径都必须执行且与同一事务紧密相关的简单派生或审计,但它会隐藏额外写入、锁和错误。一个表每类事件可有多个触发器时,更要记录顺序和依赖。

存储程序减少往返并封装服务端操作,却带来独立语言、部署与权限成本。事件调度器适合数据库内部定时任务,但高可用切换和重复执行必须设计。默认优先显式 SQL 与应用编排,只有明确收益才下沉。


七、从知识点到工程契约

本篇 SQL 最终要运行在长期存在的 schema、连接和事务中,而不是只在一个临时查询窗口里得到一次正确结果。先写清输入表与行数、会话设置、事务边界、允许的锁、期望结果和失败后的状态,再决定使用约束、查询、索引、存储对象还是运维命令。数据库行为同时受到版本、隔离级别、字符集、统计信息和并发会话影响,示例必须把这些前提显式化。

可以用以下顺序把知识点落到 StudyStore:

  1. 在全新数据库按迁移顺序建立最小 schema,保存 SHOW CREATE TABLE 与关键会话变量。
  2. 加入一个与“用层层视图掩盖错误关系模型和重复数据”相关的反例,记录错误码、SQLSTATE、事务是否仍可用以及数据是否改变。
  3. 为正常、空集、边界值、重复值和并发冲突准备确定性种子,不依赖手工残留数据。
  4. 对读查询检查结果集和 EXPLAIN ANALYZE;对写操作同时检查受影响行数、约束、提交与回滚。
  5. 最后才讨论性能优化。索引和参数调整必须有执行计划、等待事件或容量数据支持,并保留变更前基线。

审查数据库设计时至少回答四个问题:谁能写,哪条约束保护不变量,事务在哪一层结束,失败后如何恢复。MySQL 能保证声明范围内的事务和持久性,却不会替应用补上缺失约束、幂等键、备份演练或最小权限。只要这些问题没有明确答案,就不要把一次成功执行当成生产方案。

本篇最重要的能力是“用视图封装稳定投影而非掩盖错误模型”。能由主键、唯一键、外键、CHECK 或数据类型表达的规则,应优先落到数据库;需要跨聚合或外部系统判断的规则,再由应用和事务协调。不要用注释或约定替代可执行约束。


八、验证策略与复盘

验证分为 schema、数据、并发和恢复四层。schema 层检查定义与会话基线;数据层断言结果和约束;并发层至少用两个独立连接观察锁与隔离;恢复层在新实例重放迁移、备份与恢复。只看客户端显示“Query OK”不能证明结果正确,更不能证明在另一组数据和并发时仍正确。

建议保存下面的实验记录:

项目 需要记录的证据
版本 SELECT VERSION() 与镜像标签
会话 sql_mode、time_zone、事务隔离与字符集
输入 schema 版本、种子行数和参数值
输出 结果集、受影响行数、警告、错误码与 SQLSTATE
性能 执行计划、实际行数、耗时与等待
恢复 COMMIT/ROLLBACK 结果、备份校验和与恢复行数

每组脚本都应能在空数据库从头执行,并通过显式断言退出非零。涉及权限时分别用管理员和最小权限账户连接;涉及锁时设置有限等待,避免测试永久挂起;涉及复制时等待 GTID 状态而不是固定 sleep。清理只删除本次创建的临时容器、网络和数据库。

本篇可以用以下目标做验收:查询 JSON 并通过生成列建立索引;理解 MySQL 9.7 JSON Duality 的定位;评估全文索引与普通 LIKE 的边界。把每个目标转换为一条可重复 SQL、一个预期错误或一项恢复检查。若优化后结果正确但计划退化,应把执行计划也纳入回归证据。

发布前再从三个方向反向审查:把数据量放大两个数量级,判断扫描、锁和日志是否仍可控;让两个会话以最不利顺序并发,判断约束和事务是否仍保护不变量;让执行在任意一步失败,判断备份、回滚或幂等键能否恢复。只在十几行数据和单连接中成功的 SQL 仍只是功能草稿。

最后把脚本交给一个只知道镜像版本和入口命令的干净环境执行。脚本不得依赖图形客户端自动设置、个人默认数据库或先前会话变量;所有对象名、字符集、事务和预期错误都应明确。对仅用于说明、不可直接执行的片段要标注上下文,避免把省略条件的示意 SQL 当作完整迁移。

还要保存一份“结果为什么可信”的说明:约束证明哪些坏数据无法进入,事务证明哪些变化共同提交,执行计划证明访问了哪些行,权限测试证明哪些身份无法越界,恢复演练证明故障后能重新得到可用状态。这五类证据缺一时,都应在结论旁写明限制。数据库实验的价值不只是得到答案,而是让另一位操作者在不同机器、不同时间仍能重现同一判断。

若结论依赖当前数据分布或配置,应把适用范围写在 SQL 旁,并安排数据增长或版本升级后的复测条件;不要把一次测量永久固化为规则。


九、StudyStore 实验

创建支付订单视图、商品 JSON 属性及可索引生成列,比较 JSON 路径与普通列计划。增加一个最小审计触发器并记录隐式写入;按官方 9.7 语法做 JSON Duality 只读实验,同时标注 8.4 替代方案。

完成本节后,不要只保存代码或 SQL。请同时保存执行命令、关键输出和失败案例;学习笔记真正有价值的部分,是能够说明输入、状态变化、输出以及失败后的恢复方式。


十、常见错误

  • 用层层视图掩盖错误关系模型和重复数据
  • 把核心可约束字段长期塞入 JSON
  • 假定 JSON 缺失、JSON null 与 SQL NULL 相同
  • 把全文索引当任意子串或所有语言搜索方案
  • 在触发器中加入复杂网络式业务和难观察副作用

十一、练习与自测

  1. 为 JSON color 生成列建索引并比较计划。
  2. 验证视图 SQL SECURITY 两种模式的权限差异。
  3. 列出 JSON Duality 在 8.4 中的兼容替代设计。
  4. 创建审计触发器并确认回滚主事务时审计也回滚。

自测时应在干净的临时目录或临时数据库中重新执行,而不是依赖上一节遗留的状态。如果结果与预期不同,先记录实际输出,再缩小问题范围。


十二、官方资料

版本行为与二手文章不一致时,以本系列固定版本的官方文档、命令输出和可重复测试结果为准。

上一篇:锁、死锁与并发控制 下一篇:用户、角色、权限与安全