<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>星屿</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://blog.399521.xyz/</id>
  <link href="https://blog.399521.xyz/" rel="alternate"/>
  <link href="https://blog.399521.xyz/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, 星屿</rights>
  <subtitle>收藏日常与闪闪发光的瞬间</subtitle>
  <title>星屿日记</title>
  <updated>2026-06-30T07:02:36.945Z</updated>
  <entry>
    <author>
      <name>星屿</name>
    </author>
    <category term="数据库" scheme="https://blog.399521.xyz/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    <category term="MySQL" scheme="https://blog.399521.xyz/tags/MySQL/"/>
    <category term="SQL" scheme="https://blog.399521.xyz/tags/SQL/"/>
    <category term="数据库" scheme="https://blog.399521.xyz/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    <content>
      <![CDATA[<p>复习 MySQL 的时候，最容易烦的地方不是 SQL 有多难，而是很多概念长得太像了。</p><p><code>CHAR</code> 和 <code>VARCHAR</code> 像一对双胞胎，<code>WHERE</code> 和 <code>HAVING</code> 总在相邻位置出现，<code>DELETE</code> 和 <code>TRUNCATE</code> 都像是在删数据，结果脾气完全不一样。</p><p>所以这篇就不把它写成硬邦邦的清单了。我们把 MySQL 当成一间小小的数据房间，一格一格看清楚：哪些东西负责存放，哪些东西负责约束，哪些东西负责查询，哪些东西负责在关键时刻兜底。</p><hr><h2 id="一、先从数据类型开始"><a href="#一、先从数据类型开始" class="headerlink" title="一、先从数据类型开始"></a>一、先从数据类型开始</h2><p>数据库里的字段类型，其实就是在告诉 MySQL：这个格子里准备放什么东西。</p><h3 id="CHAR-和-VARCHAR"><a href="#CHAR-和-VARCHAR" class="headerlink" title="CHAR 和 VARCHAR"></a>CHAR 和 VARCHAR</h3><p><code>CHAR(n)</code> 是固定长度，像提前画好的格子。不管实际内容有多短，它都会按 <code>n</code> 个字符的位置来占空间，不够的地方用空格补上。</p><p><code>VARCHAR(n)</code> 是可变长度，像会伸缩的小盒子。实际写了多少，它就尽量按多少来存，只是额外用一点空间记录长度。</p><table><thead><tr><th>类型</th><th>长度</th><th>更适合的场景</th></tr></thead><tbody><tr><td><code>CHAR(n)</code></td><td>固定长度</td><td>编号、状态码这类长度稳定的数据</td></tr><tr><td><code>VARCHAR(n)</code></td><td>可变长度</td><td>姓名、标题、备注这类长度不固定的数据</td></tr></tbody></table><p>可以简单记成：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">CHAR 更固定，VARCHAR 更灵活。</span><br></pre></td></tr></table></figure><h3 id="AUTO-INCREMENT"><a href="#AUTO-INCREMENT" class="headerlink" title="AUTO_INCREMENT"></a>AUTO_INCREMENT</h3><p><code>AUTO_INCREMENT</code> 是自增属性，常用在主键 id 上：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">id <span class="type">INT</span> <span class="keyword">PRIMARY KEY</span> AUTO_INCREMENT</span><br></pre></td></tr></table></figure><p>它只适合整型字段，比如 <code>INT</code>、<code>BIGINT</code>。<code>VARCHAR</code>、<code>FLOAT</code> 这类字段就不要交给它啦。</p><p>如果手动插入了一个更大的 id，后面的自增值通常会从已有最大值继续往后走。所以手动改自增列时要小心，不然很容易和后续数据撞车。</p><h3 id="字符串类型"><a href="#字符串类型" class="headerlink" title="字符串类型"></a>字符串类型</h3><p>常见字符串类型有：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">CHAR</span><br><span class="line">VARCHAR</span><br><span class="line">TEXT</span><br></pre></td></tr></table></figure><p><code>NUMERIC</code> 不是字符串，它是数值类型，和 <code>DECIMAL</code> 更接近，适合放精确数字。</p><hr><h2 id="二、主键和外键：表之间的小规矩"><a href="#二、主键和外键：表之间的小规矩" class="headerlink" title="二、主键和外键：表之间的小规矩"></a>二、主键和外键：表之间的小规矩</h2><p>主键负责让一行数据有唯一身份。</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">PRIMARY KEY</span></span><br></pre></td></tr></table></figure><p>它有两个特点：</p><ul><li>不能重复。</li><li>不能是 <code>NULL</code>。</li></ul><p>一张表只能有一个主键，但这个主键可以由多列一起组成，也就是复合主键。</p><p>外键负责维护表和表之间的关系：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FOREIGN KEY</span> (dept_id) <span class="keyword">REFERENCES</span> department(id)</span><br></pre></td></tr></table></figure><p>它的意思是：当前表里的 <code>dept_id</code>，应该能在 <code>department</code> 表的 <code>id</code> 中找到对应记录。</p><p>外键这里有几个容易混的小点：</p><table><thead><tr><th>说法</th><th>实际情况</th></tr></thead><tbody><tr><td>一张表只能有一个外键</td><td>不对，一张表可以有多个外键</td></tr><tr><td>外键值一定不能为 <code>NULL</code></td><td>不一定，除非字段本身设置了 <code>NOT NULL</code></td></tr><tr><td>外键值不能重复</td><td>不对，多个子表记录可以指向同一个父表记录</td></tr><tr><td>外键用来维护引用关系</td><td>对，它主要保护关联数据的一致性</td></tr></tbody></table><p>主键像身份证，外键像通讯录里的联系人编号。一个负责“我是谁”，一个负责“我和谁有关”。</p><hr><h2 id="三、查询语句：SQL-最常用的那条路"><a href="#三、查询语句：SQL-最常用的那条路" class="headerlink" title="三、查询语句：SQL 最常用的那条路"></a>三、查询语句：SQL 最常用的那条路</h2><p>一条比较完整的查询通常长这样：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> 列名, 聚合函数(列名) <span class="keyword">AS</span> 别名</span><br><span class="line"><span class="keyword">FROM</span> 表名</span><br><span class="line"><span class="keyword">WHERE</span> 行级过滤条件</span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span> 分组列</span><br><span class="line"><span class="keyword">HAVING</span> 聚合结果过滤条件</span><br><span class="line"><span class="keyword">ORDER</span> <span class="keyword">BY</span> 排序列 <span class="keyword">DESC</span>;</span><br></pre></td></tr></table></figure><p>别急着背，先看它的顺序感：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">先从表里拿数据</span><br><span class="line">再用 WHERE 筛掉不需要的行</span><br><span class="line">然后 GROUP BY 分组</span><br><span class="line">再用 HAVING 筛分组结果</span><br><span class="line">最后 ORDER BY 排序</span><br></pre></td></tr></table></figure><h3 id="WHERE-和-HAVING"><a href="#WHERE-和-HAVING" class="headerlink" title="WHERE 和 HAVING"></a>WHERE 和 HAVING</h3><p><code>WHERE</code> 是分组前过滤行，<code>HAVING</code> 是分组后过滤结果。</p><table><thead><tr><th>对比</th><th><code>WHERE</code></th><th><code>HAVING</code></th></tr></thead><tbody><tr><td>过滤时机</td><td>分组前</td><td>分组后</td></tr><tr><td>能不能直接写聚合函数</td><td>通常不能</td><td>可以</td></tr><tr><td>常见搭配</td><td>普通条件</td><td><code>GROUP BY</code> 后的统计条件</td></tr></tbody></table><p>比如，想先筛出有效订单，再统计每个用户的订单数：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> user_id, <span class="built_in">COUNT</span>(<span class="operator">*</span>) <span class="keyword">AS</span> order_count</span><br><span class="line"><span class="keyword">FROM</span> orders</span><br><span class="line"><span class="keyword">WHERE</span> status <span class="operator">=</span> <span class="string">&#x27;paid&#x27;</span></span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span> user_id</span><br><span class="line"><span class="keyword">HAVING</span> <span class="built_in">COUNT</span>(<span class="operator">*</span>) <span class="operator">&gt;=</span> <span class="number">3</span>;</span><br></pre></td></tr></table></figure><p><code>WHERE status = &#39;paid&#39;</code> 先筛订单，<code>HAVING COUNT(*) &gt;= 3</code> 再筛统计后的用户。</p><h3 id="ORDER-BY"><a href="#ORDER-BY" class="headerlink" title="ORDER BY"></a>ORDER BY</h3><p>排序这里记住两个词：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ASC  升序，从小到大，默认可以省略</span><br><span class="line">DESC 降序，从大到小</span><br></pre></td></tr></table></figure><h3 id="SELECT-和-SELECT-ALL"><a href="#SELECT-和-SELECT-ALL" class="headerlink" title="SELECT * 和 SELECT ALL"></a>SELECT * 和 SELECT ALL</h3><p>平时写：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> table_name;</span><br></pre></td></tr></table></figure><p>就已经表示查询所有列。</p><p><code>ALL</code> 是 <code>SELECT</code> 的默认行为，表示保留重复行。完整写法可以是：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> <span class="keyword">ALL</span> <span class="operator">*</span> <span class="keyword">FROM</span> table_name;</span><br></pre></td></tr></table></figure><p>但实际写 SQL 时，直接用 <code>SELECT *</code> 就够了，清楚又省事。</p><h3 id="JOIN-连接"><a href="#JOIN-连接" class="headerlink" title="JOIN 连接"></a>JOIN 连接</h3><p>连接查询就是把两张表按某个条件拼起来。</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> e.name, d.name <span class="keyword">AS</span> dept_name</span><br><span class="line"><span class="keyword">FROM</span> employee e</span><br><span class="line"><span class="keyword">INNER</span> <span class="keyword">JOIN</span> department d <span class="keyword">ON</span> e.dept_id <span class="operator">=</span> d.id;</span><br></pre></td></tr></table></figure><p><code>INNER JOIN</code> 只保留两边都匹配上的记录。</p><p><code>LEFT JOIN</code> 会保留左表全部记录，如果右表没有匹配，右表字段就显示为 <code>NULL</code>。</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> e.name, d.name <span class="keyword">AS</span> dept_name</span><br><span class="line"><span class="keyword">FROM</span> employee e</span><br><span class="line"><span class="keyword">LEFT</span> <span class="keyword">JOIN</span> department d <span class="keyword">ON</span> e.dept_id <span class="operator">=</span> d.id;</span><br></pre></td></tr></table></figure><p>小口诀：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">INNER 看交集，LEFT 保左边。</span><br></pre></td></tr></table></figure><h3 id="子查询不只住在-WHERE-里"><a href="#子查询不只住在-WHERE-里" class="headerlink" title="子查询不只住在 WHERE 里"></a>子查询不只住在 WHERE 里</h3><p>子查询可以出现在很多地方，比如：</p><ul><li><code>SELECT</code> 后面，作为查询列。</li><li><code>FROM</code> 后面，作为临时表。</li><li><code>WHERE</code> 后面，作为过滤条件。</li><li><code>HAVING</code> 后面，作为分组后的条件。</li></ul><p>例如：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> user_id, total_amount</span><br><span class="line"><span class="keyword">FROM</span> orders</span><br><span class="line"><span class="keyword">WHERE</span> total_amount <span class="operator">&gt;</span> (</span><br><span class="line">  <span class="keyword">SELECT</span> <span class="built_in">AVG</span>(total_amount) <span class="keyword">FROM</span> orders</span><br><span class="line">);</span><br></pre></td></tr></table></figure><p>这里的子查询就是先算平均值，再拿外层订单金额去比较。</p><h3 id="LIKE-和索引"><a href="#LIKE-和索引" class="headerlink" title="LIKE 和索引"></a>LIKE 和索引</h3><p><code>LIKE</code> 做模糊匹配时，百分号的位置很重要：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">LIKE</span> <span class="string">&#x27;abc%&#x27;</span></span><br></pre></td></tr></table></figure><p>这种前缀匹配通常可以利用 B-Tree 索引。</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">LIKE</span> <span class="string">&#x27;%abc&#x27;</span></span><br></pre></td></tr></table></figure><p>这种一开头就是 <code>%</code> 的写法，MySQL 很难从索引开头定位，只能更辛苦地扫数据。</p><h3 id="INSERT-可以省略字段名吗"><a href="#INSERT-可以省略字段名吗" class="headerlink" title="INSERT 可以省略字段名吗"></a>INSERT 可以省略字段名吗</h3><p>可以，但不太推荐。</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">INSERT INTO</span> employee</span><br><span class="line"><span class="keyword">VALUES</span> (<span class="number">1</span>, <span class="string">&#x27;NAME_PLACEHOLDER&#x27;</span>, <span class="string">&#x27;DEPT_PLACEHOLDER&#x27;</span>, <span class="number">8000</span>, <span class="string">&#x27;2026-01-10&#x27;</span>);</span><br></pre></td></tr></table></figure><p>只有当值的数量和顺序完全符合表结构时，它才不会出错。更稳的写法是把字段名写出来：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">INSERT INTO</span> employee (id, name, dept_name, salary, hire_date)</span><br><span class="line"><span class="keyword">VALUES</span> (<span class="number">1</span>, <span class="string">&#x27;NAME_PLACEHOLDER&#x27;</span>, <span class="string">&#x27;DEPT_PLACEHOLDER&#x27;</span>, <span class="number">8000</span>, <span class="string">&#x27;2026-01-10&#x27;</span>);</span><br></pre></td></tr></table></figure><p>多写一点点，少踩很多坑，划算。</p><hr><h2 id="四、事务：要么一起成功，要么一起撤回"><a href="#四、事务：要么一起成功，要么一起撤回" class="headerlink" title="四、事务：要么一起成功，要么一起撤回"></a>四、事务：要么一起成功，要么一起撤回</h2><p>事务适合处理那些必须一起完成的操作，比如转账、库存扣减、订单创建。</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">START</span> TRANSACTION;</span><br><span class="line"></span><br><span class="line"><span class="keyword">UPDATE</span> account</span><br><span class="line"><span class="keyword">SET</span> balance <span class="operator">=</span> balance <span class="operator">-</span> <span class="number">100</span></span><br><span class="line"><span class="keyword">WHERE</span> id <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">UPDATE</span> account</span><br><span class="line"><span class="keyword">SET</span> balance <span class="operator">=</span> balance <span class="operator">+</span> <span class="number">100</span></span><br><span class="line"><span class="keyword">WHERE</span> id <span class="operator">=</span> <span class="number">2</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">COMMIT</span>;</span><br></pre></td></tr></table></figure><p>如果中途出错，就用：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ROLLBACK</span>;</span><br></pre></td></tr></table></figure><p>事务最核心的感觉就是：别让数据停在半路。</p><h3 id="ACID"><a href="#ACID" class="headerlink" title="ACID"></a>ACID</h3><table><thead><tr><th>特性</th><th>英文</th><th>意思</th></tr></thead><tbody><tr><td>原子性</td><td>Atomicity</td><td>要么全部成功，要么全部回滚</td></tr><tr><td>一致性</td><td>Consistency</td><td>事务前后都要保持合法状态</td></tr><tr><td>隔离性</td><td>Isolation</td><td>并发事务之间尽量互不打扰</td></tr><tr><td>持久性</td><td>Durability</td><td>提交后的数据要可靠保存</td></tr></tbody></table><p>可以把 <code>COMMIT</code> 理解成“盖章确认”，一旦提交成功，数据就正式生效了。</p><h3 id="DELETE-和-TRUNCATE"><a href="#DELETE-和-TRUNCATE" class="headerlink" title="DELETE 和 TRUNCATE"></a>DELETE 和 TRUNCATE</h3><p>它们都能清数据，但性格不一样：</p><table><thead><tr><th>对比</th><th><code>DELETE</code></th><th><code>TRUNCATE</code></th></tr></thead><tbody><tr><td>类型</td><td>DML</td><td>DDL</td></tr><tr><td>删除方式</td><td>可以带 <code>WHERE</code>，逐行删除</td><td>直接清空整张表</td></tr><tr><td>事务里能否回滚</td><td>可以</td><td>MySQL 中通常会隐式提交，不能靠事务回滚</td></tr><tr><td>速度</td><td>相对慢</td><td>通常更快</td></tr></tbody></table><p>如果只是删一部分数据，用 <code>DELETE</code>。</p><p>如果确定整张表都不要了，再考虑 <code>TRUNCATE</code>。这个操作要谨慎，别手滑。</p><hr><h2 id="五、视图：给复杂查询套一层温柔外壳"><a href="#五、视图：给复杂查询套一层温柔外壳" class="headerlink" title="五、视图：给复杂查询套一层温柔外壳"></a>五、视图：给复杂查询套一层温柔外壳</h2><p>视图是虚拟表。</p><p>它本身不真正存一份完整数据，而是把一段查询保存起来。每次查视图时，MySQL 会根据底层表动态生成结果。</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">VIEW</span> active_employee <span class="keyword">AS</span></span><br><span class="line"><span class="keyword">SELECT</span> id, name, dept_id</span><br><span class="line"><span class="keyword">FROM</span> employee</span><br><span class="line"><span class="keyword">WHERE</span> status <span class="operator">=</span> <span class="string">&#x27;active&#x27;</span>;</span><br></pre></td></tr></table></figure><p>之后就可以像查表一样查它：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> active_employee;</span><br></pre></td></tr></table></figure><p>视图的好处有两个：</p><ul><li>把复杂查询封装起来，使用时更轻松。</li><li>隐藏不想暴露的字段，比如薪资、手机号等敏感字段。</li></ul><p>不过也要注意：有些可更新视图被修改时，会影响到底层基础表。删除视图本身不会删除基础表数据，但通过可更新视图执行 <code>UPDATE</code>、<code>DELETE</code> 时，就不是“只改了一个影子”那么简单了。</p><p>常用语法：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">VIEW</span> view_name <span class="keyword">AS</span></span><br><span class="line"><span class="keyword">SELECT</span> column_name <span class="keyword">FROM</span> table_name <span class="keyword">WHERE</span> <span class="keyword">condition</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">VIEW</span> view_name <span class="keyword">AS</span></span><br><span class="line"><span class="keyword">SELECT</span> column_name <span class="keyword">FROM</span> table_name <span class="keyword">WHERE</span> new_condition;</span><br><span class="line"></span><br><span class="line"><span class="keyword">DROP</span> <span class="keyword">VIEW</span> view_name;</span><br></pre></td></tr></table></figure><p>带有复杂聚合、<code>GROUP BY</code>、<code>DISTINCT</code> 的视图，通常不能直接更新。它们更适合查询，不适合拿来改数据。</p><hr><h2 id="六、存储过程和存储函数"><a href="#六、存储过程和存储函数" class="headerlink" title="六、存储过程和存储函数"></a>六、存储过程和存储函数</h2><p>存储过程和存储函数都可以把一段 SQL 逻辑封装起来，但它们的使用方式不同。</p><table><thead><tr><th>对比</th><th>存储过程 <code>PROCEDURE</code></th><th>存储函数 <code>FUNCTION</code></th></tr></thead><tbody><tr><td>返回值</td><td>可以没有返回值，也可以用 <code>OUT</code> 参数传出</td><td>必须声明返回类型，并且有 <code>RETURN</code></td></tr><tr><td>调用方式</td><td>用 <code>CALL</code></td><td>可以放在 SQL 表达式里</td></tr><tr><td>参数</td><td>支持 <code>IN</code>、<code>OUT</code>、<code>INOUT</code></td><td>通常只用输入参数</td></tr><tr><td>事务控制</td><td>可以包含事务控制语句</td><td>不适合写 <code>COMMIT</code>、<code>ROLLBACK</code></td></tr></tbody></table><p>存储过程的常见结构：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">DELIMITER <span class="operator">/</span><span class="operator">/</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">PROCEDURE</span> proc_name(</span><br><span class="line">  <span class="keyword">IN</span> p_id <span class="type">INT</span>,</span><br><span class="line">  <span class="keyword">OUT</span> p_result <span class="type">VARCHAR</span>(<span class="number">50</span>)</span><br><span class="line">)</span><br><span class="line"><span class="keyword">BEGIN</span></span><br><span class="line">  <span class="keyword">DECLARE</span> v_count <span class="type">INT</span> <span class="keyword">DEFAULT</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">SELECT</span> <span class="built_in">COUNT</span>(<span class="operator">*</span>) <span class="keyword">INTO</span> v_count</span><br><span class="line">  <span class="keyword">FROM</span> employee</span><br><span class="line">  <span class="keyword">WHERE</span> id <span class="operator">=</span> p_id;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">SET</span> p_result <span class="operator">=</span> IF(v_count <span class="operator">&gt;</span> <span class="number">0</span>, <span class="string">&#x27;exists&#x27;</span>, <span class="string">&#x27;missing&#x27;</span>);</span><br><span class="line"><span class="keyword">END</span> <span class="operator">/</span><span class="operator">/</span></span><br><span class="line"></span><br><span class="line">DELIMITER ;</span><br></pre></td></tr></table></figure><p>调用它：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CALL</span> proc_name(<span class="number">1</span>, <span class="variable">@result</span>);</span><br><span class="line"><span class="keyword">SELECT</span> <span class="variable">@result</span>;</span><br></pre></td></tr></table></figure><p><code>DELIMITER</code> 是为了临时修改语句结束符。因为过程体里面有很多分号，如果不换结束符，MySQL 会提前以为定义结束了。</p><hr><h2 id="七、触发器：数据变化时自动响一下"><a href="#七、触发器：数据变化时自动响一下" class="headerlink" title="七、触发器：数据变化时自动响一下"></a>七、触发器：数据变化时自动响一下</h2><p>触发器会在 <code>INSERT</code>、<code>UPDATE</code>、<code>DELETE</code> 发生时自动执行。</p><p>它不能用 <code>CALL</code> 手动调用，也不会因为普通 <code>SELECT</code> 被触发。</p><p>触发时机有两种：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">BEFORE  操作之前</span><br><span class="line">AFTER   操作之后</span><br></pre></td></tr></table></figure><p>触发器里经常会看到 <code>OLD</code> 和 <code>NEW</code>：</p><table><thead><tr><th>关键字</th><th>意思</th><th>常用场景</th></tr></thead><tbody><tr><td><code>OLD.column_name</code></td><td>操作前的旧值</td><td><code>DELETE</code>、<code>UPDATE</code></td></tr><tr><td><code>NEW.column_name</code></td><td>操作后的新值</td><td><code>INSERT</code>、<code>UPDATE</code></td></tr></tbody></table><p>比如删除员工记录前，顺手删除关联考勤记录：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">DELIMITER <span class="operator">/</span><span class="operator">/</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TRIGGER</span> trg_delete_employee_attendance</span><br><span class="line">  BEFORE <span class="keyword">DELETE</span> <span class="keyword">ON</span> employee</span><br><span class="line">  <span class="keyword">FOR</span> <span class="keyword">EACH</span> <span class="type">ROW</span></span><br><span class="line"><span class="keyword">BEGIN</span></span><br><span class="line">  <span class="keyword">DELETE</span> <span class="keyword">FROM</span> attendance</span><br><span class="line">  <span class="keyword">WHERE</span> emp_id <span class="operator">=</span> OLD.id;</span><br><span class="line"><span class="keyword">END</span> <span class="operator">/</span><span class="operator">/</span></span><br><span class="line"></span><br><span class="line">DELIMITER ;</span><br></pre></td></tr></table></figure><p>这里用的是 <code>OLD.id</code>，因为正在删除的那一行，删除后就不存在了，要在删除前拿到它的旧值。</p><p>触发器很好用，但不要滥用。逻辑藏得太深，以后排查问题会比较累。能用清楚的业务代码解决时，就别把所有东西都塞进触发器里。</p><hr><h2 id="八、大小写问题：跨系统时别太自信"><a href="#八、大小写问题：跨系统时别太自信" class="headerlink" title="八、大小写问题：跨系统时别太自信"></a>八、大小写问题：跨系统时别太自信</h2><p>MySQL 的库名、表名是否区分大小写，和操作系统以及配置有关。</p><p>在 Windows 上，默认通常不区分大小写；在 Linux 上，通常区分大小写。</p><p>最稳的习惯是：表名、字段名统一用小写和下划线。</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">user_order</span><br><span class="line">order_item</span><br><span class="line">created_at</span><br></pre></td></tr></table></figure><p>别写一会儿 <code>UserOrder</code>，一会儿 <code>userorder</code>。自己看着累，数据库也可能看着迷糊。</p><hr><h2 id="九、容易记混的小卡片"><a href="#九、容易记混的小卡片" class="headerlink" title="九、容易记混的小卡片"></a>九、容易记混的小卡片</h2><table><thead><tr><th>小问题</th><th>记法</th></tr></thead><tbody><tr><td><code>CHAR(10)</code> 和 <code>VARCHAR(10)</code> 一样占空间吗</td><td>不一样，<code>CHAR</code> 固定，<code>VARCHAR</code> 按需</td></tr><tr><td><code>DELETE</code> 和 <code>TRUNCATE</code> 都能回滚吗</td><td>不一样，<code>TRUNCATE</code> 在 MySQL 中通常会隐式提交</td></tr><tr><td>一张表只能有一个外键吗</td><td>不是，可以有多个</td></tr><tr><td>视图会独立存储完整数据吗</td><td>不会，它是虚拟表</td></tr><tr><td><code>GROUP BY</code> 必须配聚合函数吗</td><td>不必须，单独用时有点像分组去重</td></tr><tr><td><code>FUNCTION</code> 必须有返回值吗</td><td>必须</td></tr><tr><td><code>PROCEDURE</code> 必须有返回值吗</td><td>不必须</td></tr><tr><td><code>LEFT JOIN</code> 会保留哪边</td><td>左表全部保留</td></tr><tr><td><code>LIKE &#39;%abc&#39;</code> 容易用上普通 B-Tree 索引吗</td><td>不容易，因为开头就是通配符</td></tr><tr><td>子查询只能写在 <code>WHERE</code> 里吗</td><td>不是，很多位置都可以</td></tr><tr><td><code>DESC</code> 是升序吗</td><td>不是，<code>DESC</code> 是降序</td></tr><tr><td><code>AUTO_INCREMENT</code> 能给字符串用吗</td><td>不适合，它用于整型自增</td></tr><tr><td>触发器需要手动调用吗</td><td>不需要，它会自动触发</td></tr></tbody></table><hr><h2 id="十、写综合-SQL-时，可以按这个顺序走"><a href="#十、写综合-SQL-时，可以按这个顺序走" class="headerlink" title="十、写综合 SQL 时，可以按这个顺序走"></a>十、写综合 SQL 时，可以按这个顺序走</h2><p>如果要从零写一套比较完整的数据库逻辑，可以先按这个路线来：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 1. 建库</span></span><br><span class="line"><span class="keyword">CREATE</span> DATABASE IF <span class="keyword">NOT</span> <span class="keyword">EXISTS</span> db_name</span><br><span class="line">  <span class="keyword">CHARACTER SET</span> utf8mb4 <span class="keyword">COLLATE</span> utf8mb4_unicode_ci;</span><br><span class="line"></span><br><span class="line">USE db_name;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 2. 建主表</span></span><br><span class="line"><span class="keyword">CREATE TABLE</span> table_a (</span><br><span class="line">  id <span class="type">INT</span> <span class="keyword">PRIMARY KEY</span> AUTO_INCREMENT,</span><br><span class="line">  name <span class="type">VARCHAR</span>(<span class="number">50</span>) <span class="keyword">NOT NULL</span></span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 3. 建关联表</span></span><br><span class="line"><span class="keyword">CREATE TABLE</span> table_b (</span><br><span class="line">  id <span class="type">INT</span> <span class="keyword">PRIMARY KEY</span> AUTO_INCREMENT,</span><br><span class="line">  a_id <span class="type">INT</span> <span class="keyword">NOT NULL</span>,</span><br><span class="line">  created_at DATETIME <span class="keyword">DEFAULT</span> <span class="built_in">CURRENT_TIMESTAMP</span>,</span><br><span class="line">  <span class="keyword">FOREIGN KEY</span> (a_id) <span class="keyword">REFERENCES</span> table_a(id)</span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 4. 插入数据</span></span><br><span class="line"><span class="keyword">INSERT INTO</span> table_a (name)</span><br><span class="line"><span class="keyword">VALUES</span> (<span class="string">&#x27;NAME_PLACEHOLDER&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 5. 多表查询</span></span><br><span class="line"><span class="keyword">SELECT</span> a.name, b.created_at</span><br><span class="line"><span class="keyword">FROM</span> table_a a</span><br><span class="line"><span class="keyword">JOIN</span> table_b b <span class="keyword">ON</span> a.id <span class="operator">=</span> b.a_id;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 6. 分组统计</span></span><br><span class="line"><span class="keyword">SELECT</span> a_id, <span class="built_in">COUNT</span>(<span class="operator">*</span>) <span class="keyword">AS</span> total_count</span><br><span class="line"><span class="keyword">FROM</span> table_b</span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span> a_id</span><br><span class="line"><span class="keyword">HAVING</span> <span class="built_in">COUNT</span>(<span class="operator">*</span>) <span class="operator">&gt;=</span> <span class="number">1</span>;</span><br></pre></td></tr></table></figure><p>存储过程和触发器可以等主表、关联表、查询逻辑都稳定后再加。先把普通 SQL 写清楚，再封装，思路会顺很多。</p><hr><h2 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h2><p>MySQL 看起来零件很多，但其实它们各有各的位置。</p><p>字段类型负责“放什么”，主键外键负责“怎么关联”，查询语句负责“怎么拿出来”，事务负责“出事时怎么撤回”，视图、存储过程和触发器则负责把常用逻辑包装得更顺手。</p><p>不用一口气把所有概念背成一堵墙。先记住每个东西的性格，再慢慢把它们放回 SQL 里。</p><p>一步一步来，数据库这间小房间就会越来越亮啦。✨</p>]]>
    </content>
    <id>https://blog.399521.xyz/2026/06/30/mysql-gentle-notes/</id>
    <link href="https://blog.399521.xyz/2026/06/30/mysql-gentle-notes/"/>
    <published>2026-06-30T07:02:00.000Z</published>
    <summary>
      <![CDATA[<p>复习 MySQL 的时候，最容易烦的地方不是 SQL 有多难，而是很多概念长得太像了。</p>
<p><code>CHAR</code> 和 <code>VARCHAR</code> 像一对双胞胎，<code>WHERE</code> 和 <code>HAVING</cod]]>
    </summary>
    <title>把 MySQL 的小机关慢慢理顺</title>
    <updated>2026-06-30T07:02:36.945Z</updated>
  </entry>
  <entry>
    <author>
      <name>星屿</name>
    </author>
    <category term="数据可视化" scheme="https://blog.399521.xyz/categories/%E6%95%B0%E6%8D%AE%E5%8F%AF%E8%A7%86%E5%8C%96/"/>
    <category term="ECharts" scheme="https://blog.399521.xyz/tags/ECharts/"/>
    <category term="考试速记" scheme="https://blog.399521.xyz/tags/%E8%80%83%E8%AF%95%E9%80%9F%E8%AE%B0/"/>
    <content>
      <![CDATA[<p>备考数据可视化的那段时间，不知道为什么总喜欢在很晚的时候看文档。</p><p>窗外安静，屏幕亮着，翻着翻着就忽然觉得——ECharts 这个东西，好像不太一样。</p><p>它不像平时写 Java 或者 Python，不是在命令计算机”先做这个，再做那个”。更像是在填一张小表格。你把标题放进 <code>title</code>，把坐标轴放进 <code>xAxis</code>，把数据放进 <code>series</code>，然后图就出来了。很乖，不问多余的问题。</p><p>后来想通了：ECharts 不需要死背。先把骨架记住，再根据图表类型换零件就好。外套不一样，人还是那个人。</p><hr><h2 id="一、通用骨架"><a href="#一、通用骨架" class="headerlink" title="一、通用骨架"></a>一、通用骨架</h2><p>大部分图表都长这样：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> option = &#123;</span><br><span class="line">    <span class="attr">title</span>: &#123; <span class="attr">text</span>: <span class="string">&#x27;图表标题&#x27;</span> &#125;,</span><br><span class="line">    <span class="attr">tooltip</span>: &#123;&#125;,</span><br><span class="line">    <span class="attr">legend</span>: &#123; <span class="attr">data</span>: [<span class="string">&#x27;系列名称&#x27;</span>] &#125;,</span><br><span class="line">    <span class="attr">xAxis</span>: &#123; <span class="attr">type</span>: <span class="string">&#x27;category&#x27;</span>, <span class="attr">data</span>: [<span class="string">&#x27;A&#x27;</span>, <span class="string">&#x27;B&#x27;</span>, <span class="string">&#x27;C&#x27;</span>] &#125;,</span><br><span class="line">    <span class="attr">yAxis</span>: &#123; <span class="attr">type</span>: <span class="string">&#x27;value&#x27;</span> &#125;,</span><br><span class="line">    <span class="attr">series</span>: [&#123;</span><br><span class="line">        <span class="attr">name</span>: <span class="string">&#x27;系列名称&#x27;</span>,</span><br><span class="line">        <span class="attr">type</span>: <span class="string">&#x27;bar&#x27;</span>,</span><br><span class="line">        <span class="attr">data</span>: [<span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>]</span><br><span class="line">    &#125;]</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>需要记住的字段只有六个：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">title    <span class="comment">// 标题</span></span><br><span class="line">tooltip  <span class="comment">// 悬停提示</span></span><br><span class="line">legend   <span class="comment">// 图例</span></span><br><span class="line">xAxis    <span class="comment">// x 轴</span></span><br><span class="line">yAxis    <span class="comment">// y 轴</span></span><br><span class="line">series   <span class="comment">// 图表主体</span></span><br></pre></td></tr></table></figure><p>其中 <code>series</code> 是整张图的心脏。图是柱状图、折线图、饼图，还是散点图，就看 <code>type</code> 写什么。换一个词，图表就换了一副模样。</p><hr><h2 id="二、柱状图和折线图"><a href="#二、柱状图和折线图" class="headerlink" title="二、柱状图和折线图"></a>二、柱状图和折线图</h2><p>这两个最省心，就像填空题。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">xAxis</span>: &#123;</span><br><span class="line">    <span class="attr">type</span>: <span class="string">&#x27;category&#x27;</span>,</span><br><span class="line">    <span class="attr">data</span>: [<span class="string">&#x27;一月&#x27;</span>, <span class="string">&#x27;二月&#x27;</span>, <span class="string">&#x27;三月&#x27;</span>]</span><br><span class="line">&#125;,</span><br><span class="line"><span class="attr">yAxis</span>: &#123;</span><br><span class="line">    <span class="attr">type</span>: <span class="string">&#x27;value&#x27;</span></span><br><span class="line">&#125;,</span><br><span class="line"><span class="attr">series</span>: [&#123;</span><br><span class="line">    <span class="attr">type</span>: <span class="string">&#x27;bar&#x27;</span>,</span><br><span class="line">    <span class="attr">data</span>: [<span class="number">120</span>, <span class="number">200</span>, <span class="number">150</span>]</span><br><span class="line">&#125;]</span><br></pre></td></tr></table></figure><p><code>category</code> 和 <code>value</code> 的区别，记这一句话就够：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">category 是分类，自己写 data（月份、城市、科目这种）</span><br><span class="line">value 是数值，ECharts 自己算刻度，不用写</span><br></pre></td></tr></table></figure><p>如果想把柱状图和折线图叠在一起，在 <code>series</code> 里多放一个对象就行：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">series</span>: [</span><br><span class="line">    &#123; <span class="attr">name</span>: <span class="string">&#x27;销量&#x27;</span>, <span class="attr">type</span>: <span class="string">&#x27;bar&#x27;</span>,  <span class="attr">data</span>: [<span class="number">120</span>, <span class="number">200</span>, <span class="number">150</span>] &#125;,</span><br><span class="line">    &#123; <span class="attr">name</span>: <span class="string">&#x27;增长&#x27;</span>, <span class="attr">type</span>: <span class="string">&#x27;line&#x27;</span>, <span class="attr">data</span>: [<span class="number">100</span>, <span class="number">160</span>, <span class="number">130</span>] &#125;</span><br><span class="line">]</span><br></pre></td></tr></table></figure><p>一个 <code>{}</code> 一组图，想叠几个放几个。</p><hr><h2 id="三、两个-Y-轴"><a href="#三、两个-Y-轴" class="headerlink" title="三、两个 Y 轴"></a>三、两个 Y 轴</h2><p>有时候两组数据的单位不一样，放在同一把尺子上会很奇怪。这时候可以写两个 Y 轴：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">yAxis</span>: [</span><br><span class="line">    &#123; <span class="attr">type</span>: <span class="string">&#x27;value&#x27;</span>, <span class="attr">name</span>: <span class="string">&#x27;销量&#x27;</span> &#125;,</span><br><span class="line">    &#123; <span class="attr">type</span>: <span class="string">&#x27;value&#x27;</span>, <span class="attr">name</span>: <span class="string">&#x27;增长率&#x27;</span> &#125;</span><br><span class="line">],</span><br><span class="line"><span class="attr">series</span>: [</span><br><span class="line">    &#123; <span class="attr">name</span>: <span class="string">&#x27;销量&#x27;</span>, <span class="attr">type</span>: <span class="string">&#x27;bar&#x27;</span>, <span class="attr">data</span>: [<span class="number">120</span>, <span class="number">200</span>, <span class="number">150</span>] &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="attr">name</span>: <span class="string">&#x27;增长率&#x27;</span>,</span><br><span class="line">        <span class="attr">type</span>: <span class="string">&#x27;line&#x27;</span>,</span><br><span class="line">        <span class="attr">yAxisIndex</span>: <span class="number">1</span>,</span><br><span class="line">        <span class="attr">data</span>: [<span class="number">10</span>, <span class="number">20</span>, <span class="number">15</span>]</span><br><span class="line">    &#125;</span><br><span class="line">]</span><br></pre></td></tr></table></figure><p>重点是 <code>yAxisIndex: 1</code>——数组从 0 开始，所以 <code>1</code> 指的是第二个 Y 轴。</p><p>单位一样的话就别写两个了。能简单就简单。</p><hr><h2 id="四、tooltip，那个小纸条"><a href="#四、tooltip，那个小纸条" class="headerlink" title="四、tooltip，那个小纸条"></a>四、tooltip，那个小纸条</h2><p><code>tooltip</code> 是鼠标悬停时弹出来的提示框。不写它图也能跑，但写了读图会舒服很多。</p><p>最懒的写法：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">tooltip</span>: &#123;&#125;</span><br></pre></td></tr></table></figure><p>有坐标轴的图（柱状图、折线图）常用 <code>trigger: &#39;axis&#39;</code>，鼠标移到某个 x 轴位置，显示整列数据：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">tooltip</span>: &#123; <span class="attr">trigger</span>: <span class="string">&#x27;axis&#x27;</span> &#125;</span><br></pre></td></tr></table></figure><p>没有坐标轴的图（饼图、漏斗图）用 <code>trigger: &#39;item&#39;</code>，鼠标移到哪个块，显示哪个块：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">tooltip</span>: &#123;</span><br><span class="line">    <span class="attr">trigger</span>: <span class="string">&#x27;item&#x27;</span>,</span><br><span class="line">    <span class="attr">formatter</span>: <span class="string">&#x27;&#123;b&#125;: &#123;c&#125;%&#x27;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><code>{b}</code> 是名字，<code>{c}</code> 是数值。记住这两个字母就够了。</p><hr><h2 id="五、散点图"><a href="#五、散点图" class="headerlink" title="五、散点图"></a>五、散点图</h2><p>散点图有点特别——坐标不写在 <code>xAxis</code> 里，而是直接藏在每个数据点里：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">data</span>: [</span><br><span class="line">    [<span class="number">10</span>, <span class="number">20</span>],</span><br><span class="line">    [<span class="number">15</span>, <span class="number">35</span>],</span><br><span class="line">    [<span class="number">8</span>,  <span class="number">18</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure><p>每一个小数组是一个点：<code>[x值, y值]</code>。</p><p>完整写法：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> option = &#123;</span><br><span class="line">    <span class="attr">title</span>: &#123; <span class="attr">text</span>: <span class="string">&#x27;散点图&#x27;</span> &#125;,</span><br><span class="line">    <span class="attr">tooltip</span>: &#123;&#125;,</span><br><span class="line">    <span class="attr">xAxis</span>: &#123; <span class="attr">type</span>: <span class="string">&#x27;value&#x27;</span> &#125;,</span><br><span class="line">    <span class="attr">yAxis</span>: &#123; <span class="attr">type</span>: <span class="string">&#x27;value&#x27;</span> &#125;,</span><br><span class="line">    <span class="attr">series</span>: [&#123;</span><br><span class="line">        <span class="attr">type</span>: <span class="string">&#x27;scatter&#x27;</span>,</span><br><span class="line">        <span class="attr">data</span>: [[<span class="number">10</span>, <span class="number">20</span>], [<span class="number">15</span>, <span class="number">35</span>], [<span class="number">8</span>, <span class="number">18</span>]]</span><br><span class="line">    &#125;]</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>注意 <code>xAxis</code> 和 <code>yAxis</code> 的 <code>type</code> 都是 <code>&#39;value&#39;</code>，不需要 <code>data</code>。</p><hr><h2 id="六、雷达图"><a href="#六、雷达图" class="headerlink" title="六、雷达图"></a>六、雷达图</h2><p>雷达图有自己的一套，不走 <code>xAxis / yAxis</code>，多了一个字段叫 <code>radar</code>：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> option = &#123;</span><br><span class="line">    <span class="attr">title</span>: &#123; <span class="attr">text</span>: <span class="string">&#x27;雷达图&#x27;</span> &#125;,</span><br><span class="line">    <span class="attr">tooltip</span>: &#123;&#125;,</span><br><span class="line">    <span class="attr">radar</span>: &#123;</span><br><span class="line">        <span class="attr">indicator</span>: [</span><br><span class="line">            &#123; <span class="attr">name</span>: <span class="string">&#x27;学习&#x27;</span>, <span class="attr">max</span>: <span class="number">100</span> &#125;,</span><br><span class="line">            &#123; <span class="attr">name</span>: <span class="string">&#x27;体育&#x27;</span>, <span class="attr">max</span>: <span class="number">100</span> &#125;,</span><br><span class="line">            &#123; <span class="attr">name</span>: <span class="string">&#x27;社交&#x27;</span>, <span class="attr">max</span>: <span class="number">100</span> &#125;,</span><br><span class="line">            &#123; <span class="attr">name</span>: <span class="string">&#x27;实践&#x27;</span>, <span class="attr">max</span>: <span class="number">100</span> &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">series</span>: [&#123;</span><br><span class="line">        <span class="attr">type</span>: <span class="string">&#x27;radar&#x27;</span>,</span><br><span class="line">        <span class="attr">data</span>: [&#123;</span><br><span class="line">            <span class="attr">name</span>: <span class="string">&#x27;样本A&#x27;</span>,</span><br><span class="line">            <span class="attr">value</span>: [<span class="number">80</span>, <span class="number">70</span>, <span class="number">90</span>, <span class="number">60</span>]</span><br><span class="line">        &#125;]</span><br><span class="line">    &#125;]</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p><code>indicator</code> 定义有几根轴，<code>value</code> 填对应的数值，两边一一对应，数量要一样多。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">radar.indicator 定义轴</span><br><span class="line">series.data.value 填数值</span><br></pre></td></tr></table></figure><hr><h2 id="七、漏斗图"><a href="#七、漏斗图" class="headerlink" title="七、漏斗图"></a>七、漏斗图</h2><p>漏斗图也不需要坐标轴，数据从大到小排列，形状自然就出来了：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> option = &#123;</span><br><span class="line">    <span class="attr">title</span>: &#123; <span class="attr">text</span>: <span class="string">&#x27;漏斗图&#x27;</span> &#125;,</span><br><span class="line">    <span class="attr">tooltip</span>: &#123; <span class="attr">trigger</span>: <span class="string">&#x27;item&#x27;</span>, <span class="attr">formatter</span>: <span class="string">&#x27;&#123;b&#125;: &#123;c&#125;%&#x27;</span> &#125;,</span><br><span class="line">    <span class="attr">series</span>: [&#123;</span><br><span class="line">        <span class="attr">type</span>: <span class="string">&#x27;funnel&#x27;</span>,</span><br><span class="line">        <span class="attr">data</span>: [</span><br><span class="line">            &#123; <span class="attr">value</span>: <span class="number">100</span>, <span class="attr">name</span>: <span class="string">&#x27;访问&#x27;</span> &#125;,</span><br><span class="line">            &#123; <span class="attr">value</span>: <span class="number">80</span>,  <span class="attr">name</span>: <span class="string">&#x27;浏览&#x27;</span> &#125;,</span><br><span class="line">            &#123; <span class="attr">value</span>: <span class="number">60</span>,  <span class="attr">name</span>: <span class="string">&#x27;咨询&#x27;</span> &#125;,</span><br><span class="line">            &#123; <span class="attr">value</span>: <span class="number">40</span>,  <span class="attr">name</span>: <span class="string">&#x27;下单&#x27;</span> &#125;,</span><br><span class="line">            &#123; <span class="attr">value</span>: <span class="number">20</span>,  <span class="attr">name</span>: <span class="string">&#x27;支付&#x27;</span> &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;]</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>适合表示”从多到少”的过程。越到后面越窄，像一只很认真在过滤东西的小漏斗。</p><hr><h2 id="八、树图"><a href="#八、树图" class="headerlink" title="八、树图"></a>八、树图</h2><p>树图的数据是嵌套结构：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    <span class="attr">name</span>: <span class="string">&#x27;根节点&#x27;</span>,</span><br><span class="line">    <span class="attr">children</span>: [</span><br><span class="line">        &#123; <span class="attr">name</span>: <span class="string">&#x27;子节点1&#x27;</span> &#125;,</span><br><span class="line">        &#123; <span class="attr">name</span>: <span class="string">&#x27;子节点2&#x27;</span> &#125;</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>有一个坑：如果数据放在 JSON 文件里，不能直接用 <code>&lt;script&gt;</code> 引入，因为 <code>&lt;script&gt;</code> 只认 JS 文件。要用 <code>fetch</code>：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">fetch</span>(<span class="string">&#x27;data.json&#x27;</span>)</span><br><span class="line">    .<span class="title function_">then</span>(<span class="function"><span class="params">res</span> =&gt;</span> res.<span class="title function_">json</span>())</span><br><span class="line">    .<span class="title function_">then</span>(<span class="function"><span class="params">data</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">var</span> option = &#123;</span><br><span class="line">            <span class="attr">title</span>: &#123; <span class="attr">text</span>: <span class="string">&#x27;树图&#x27;</span> &#125;,</span><br><span class="line">            <span class="attr">tooltip</span>: &#123; <span class="attr">trigger</span>: <span class="string">&#x27;item&#x27;</span> &#125;,</span><br><span class="line">            <span class="attr">series</span>: [&#123;</span><br><span class="line">                <span class="attr">type</span>: <span class="string">&#x27;tree&#x27;</span>,</span><br><span class="line">                <span class="attr">data</span>: [data]   <span class="comment">// 注意是 [data]，不是 data</span></span><br><span class="line">            &#125;]</span><br><span class="line">        &#125;;</span><br><span class="line">        myChart.<span class="title function_">setOption</span>(option);</span><br><span class="line">    &#125;);</span><br></pre></td></tr></table></figure><p><code>data: [data]</code> 这里要包一层数组——因为 <code>series.data</code> 要数组，但树图的根节点是对象，所以手动套一层中括号。</p><p>如果节点太多挤在一起，加这两个字段会舒展很多：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">orient</span>: <span class="string">&#x27;LR&#x27;</span>,        <span class="comment">// 从左到右展开</span></span><br><span class="line"><span class="attr">initialTreeDepth</span>: <span class="number">2</span>  <span class="comment">// 先展开两层</span></span><br></pre></td></tr></table></figure><hr><h2 id="九、关系图"><a href="#九、关系图" class="headerlink" title="九、关系图"></a>九、关系图</h2><p>关系图看起来字段多，但核心只有两个：<code>data</code> 写节点，<code>links</code> 写连线。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">series</span>: [&#123;</span><br><span class="line">    <span class="attr">type</span>: <span class="string">&#x27;graph&#x27;</span>,</span><br><span class="line">    <span class="attr">layout</span>: <span class="string">&#x27;force&#x27;</span>,</span><br><span class="line">    <span class="attr">roam</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">label</span>: &#123; <span class="attr">show</span>: <span class="literal">true</span> &#125;,</span><br><span class="line">    <span class="attr">edgeLabel</span>: &#123; <span class="attr">show</span>: <span class="literal">true</span>, <span class="attr">formatter</span>: <span class="string">&#x27;&#123;c&#125;&#x27;</span> &#125;,</span><br><span class="line">    <span class="attr">data</span>: [</span><br><span class="line">        &#123; <span class="attr">name</span>: <span class="string">&#x27;节点A&#x27;</span>, <span class="attr">symbolSize</span>: <span class="number">30</span> &#125;,</span><br><span class="line">        &#123; <span class="attr">name</span>: <span class="string">&#x27;节点B&#x27;</span>, <span class="attr">symbolSize</span>: <span class="number">30</span> &#125;,</span><br><span class="line">        &#123; <span class="attr">name</span>: <span class="string">&#x27;节点C&#x27;</span>, <span class="attr">symbolSize</span>: <span class="number">30</span> &#125;</span><br><span class="line">    ],</span><br><span class="line">    <span class="attr">links</span>: [</span><br><span class="line">        &#123; <span class="attr">source</span>: <span class="string">&#x27;节点A&#x27;</span>, <span class="attr">target</span>: <span class="string">&#x27;节点B&#x27;</span>, <span class="attr">value</span>: <span class="string">&#x27;关系1&#x27;</span> &#125;,</span><br><span class="line">        &#123; <span class="attr">source</span>: <span class="string">&#x27;节点A&#x27;</span>, <span class="attr">target</span>: <span class="string">&#x27;节点C&#x27;</span>, <span class="attr">value</span>: <span class="string">&#x27;关系2&#x27;</span> &#125;,</span><br><span class="line">        &#123; <span class="attr">source</span>: <span class="string">&#x27;节点B&#x27;</span>, <span class="attr">target</span>: <span class="string">&#x27;节点C&#x27;</span>, <span class="attr">value</span>: <span class="string">&#x27;关系3&#x27;</span> &#125;</span><br><span class="line">    ]</span><br><span class="line">&#125;]</span><br></pre></td></tr></table></figure><p><code>source</code> 是起点，<code>target</code> 是终点，<code>value</code> 是线上显示的文字。<code>edgeLabel.formatter: &#39;{c}&#39;</code> 里的 <code>{c}</code> 就是这个 <code>value</code>。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">data 写点，links 连线</span><br><span class="line">source 找 target，value 写关系</span><br></pre></td></tr></table></figure><hr><h2 id="十、地图"><a href="#十、地图" class="headerlink" title="十、地图"></a>十、地图</h2><p>地图这里要分清两件事：</p><p>第一件事，<strong>地图轮廓文件</strong>还是用 <code>&lt;script&gt;</code> 引入 JS 文件：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;map/province/guangxi.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>这一步相当于先把”广西这张地图纸”拿出来。</p><p>第二件事，<strong>地图上要显示的数据</strong>，可以直接写数组，也可以用 <code>fetch</code> 读取 JSON 文件。</p><p>如果给的是普通数据数组，就这样放进 <code>series.data</code>：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">series</span>: [&#123;</span><br><span class="line">    <span class="attr">type</span>: <span class="string">&#x27;map&#x27;</span>,</span><br><span class="line">    <span class="attr">map</span>: <span class="string">&#x27;广西&#x27;</span>,</span><br><span class="line">    <span class="attr">roam</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">label</span>: &#123; <span class="attr">show</span>: <span class="literal">true</span> &#125;,</span><br><span class="line">    <span class="attr">data</span>: data</span><br><span class="line">&#125;]</span><br></pre></td></tr></table></figure><p>如果数据放在 <code>guangxi_map.json</code> 里，就用 <code>fetch</code> 读取：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">fetch</span>(<span class="string">&#x27;guangxi_map.json&#x27;</span>)</span><br><span class="line">    .<span class="title function_">then</span>(<span class="function"><span class="params">res</span> =&gt;</span> res.<span class="title function_">json</span>())</span><br><span class="line">    .<span class="title function_">then</span>(<span class="function"><span class="params">data</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">var</span> option = &#123;</span><br><span class="line">            <span class="attr">series</span>: [&#123;</span><br><span class="line">                <span class="attr">type</span>: <span class="string">&#x27;map&#x27;</span>,</span><br><span class="line">                <span class="attr">map</span>: <span class="string">&#x27;广西&#x27;</span>,</span><br><span class="line">                <span class="attr">data</span>: data</span><br><span class="line">            &#125;]</span><br><span class="line">        &#125;;</span><br><span class="line"></span><br><span class="line">        myChart.<span class="title function_">setOption</span>(option);</span><br><span class="line">    &#125;);</span><br></pre></td></tr></table></figure><p>如果要按数值深浅显示颜色，加 <code>visualMap</code>：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">visualMap</span>: &#123; <span class="attr">min</span>: <span class="number">100</span>, <span class="attr">max</span>: <span class="number">900</span> &#125;</span><br></pre></td></tr></table></figure><p>如果想在地图上叠加散点或航线，用 <code>geo</code> + <code>coordinateSystem: &#39;geo&#39;</code>：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">geo</span>: &#123; <span class="attr">map</span>: <span class="string">&#x27;广西&#x27;</span>, <span class="attr">roam</span>: <span class="literal">true</span> &#125;</span><br><span class="line"><span class="comment">// series 里加上：</span></span><br><span class="line"><span class="attr">coordinateSystem</span>: <span class="string">&#x27;geo&#x27;</span></span><br></pre></td></tr></table></figure><hr><h2 id="十一、toolbox：导出效果图的小按钮"><a href="#十一、toolbox：导出效果图的小按钮" class="headerlink" title="十一、toolbox：导出效果图的小按钮"></a>十一、toolbox：导出效果图的小按钮</h2><p>提交时，除了提交代码，还要提交效果图。</p><p>效果图可以用 ECharts 自带的 <code>toolbox</code> 导出，所以提交代码时要保留 <code>toolbox</code> 配置，不要删掉它哦。</p><p>最常用的是这个：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">toolbox</span>: &#123;</span><br><span class="line">    <span class="attr">show</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">feature</span>: &#123;</span><br><span class="line">        <span class="attr">saveAsImage</span>: &#123;&#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>放进 <code>option</code> 里就是：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> option = &#123;</span><br><span class="line">    <span class="attr">title</span>: &#123; <span class="attr">text</span>: <span class="string">&#x27;柱状图&#x27;</span> &#125;,</span><br><span class="line">    <span class="attr">tooltip</span>: &#123;&#125;,</span><br><span class="line">    <span class="attr">toolbox</span>: &#123;</span><br><span class="line">        <span class="attr">show</span>: <span class="literal">true</span>,</span><br><span class="line">        <span class="attr">feature</span>: &#123;</span><br><span class="line">            <span class="attr">saveAsImage</span>: &#123;&#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">xAxis</span>: &#123;</span><br><span class="line">        <span class="attr">type</span>: <span class="string">&#x27;category&#x27;</span>,</span><br><span class="line">        <span class="attr">data</span>: [<span class="string">&#x27;一月&#x27;</span>, <span class="string">&#x27;二月&#x27;</span>, <span class="string">&#x27;三月&#x27;</span>]</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">yAxis</span>: &#123;</span><br><span class="line">        <span class="attr">type</span>: <span class="string">&#x27;value&#x27;</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">series</span>: [&#123;</span><br><span class="line">        <span class="attr">type</span>: <span class="string">&#x27;bar&#x27;</span>,</span><br><span class="line">        <span class="attr">data</span>: [<span class="number">120</span>, <span class="number">200</span>, <span class="number">150</span>]</span><br><span class="line">    &#125;]</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>页面右上角会出现一个保存图片的小按钮，点一下就能导出效果图。</p><p>简易记忆版：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">toolbox</span>: &#123; <span class="attr">feature</span>: &#123; <span class="attr">saveAsImage</span>: &#123;&#125; &#125; &#125;</span><br></pre></td></tr></table></figure><hr><h2 id="最后，一张小卡片"><a href="#最后，一张小卡片" class="headerlink" title="最后，一张小卡片"></a>最后，一张小卡片</h2><p>考试前可以只背这一个骨架：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">option = &#123;</span><br><span class="line">    <span class="attr">title</span>:   &#123;&#125;,</span><br><span class="line">    <span class="attr">tooltip</span>: &#123;&#125;,</span><br><span class="line">    <span class="attr">legend</span>:  &#123;&#125;,</span><br><span class="line">    <span class="attr">xAxis</span>:   &#123;&#125;,</span><br><span class="line">    <span class="attr">yAxis</span>:   &#123;&#125;,</span><br><span class="line">    <span class="attr">series</span>:  [&#123; <span class="attr">type</span>: <span class="string">&#x27;类型&#x27;</span>, <span class="attr">data</span>: [] &#125;]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>再记住哪些图走的是”特殊通道”：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">饼图 / 漏斗图  →  不要 xAxis、yAxis</span><br><span class="line">雷达图         →  多一个 radar</span><br><span class="line">树图           →  data: [data]，JSON 用 fetch 读</span><br><span class="line">关系图         →  data 写节点，links 写连线</span><br><span class="line">地图           →  map 指定地图名，fetch 读数据</span><br><span class="line">toolbox        →  saveAsImage 导出效果图</span><br><span class="line">散点图         →  data 写 [[x, y], [x, y]]</span><br></pre></td></tr></table></figure><hr><p>其实 ECharts 没有那么多需要死记的东西。</p><p>它就是一只小抽屉，每个字段都有自己的位置。标题进 <code>title</code>，提示进 <code>tooltip</code>，数据进 <code>series</code>。一开始看会觉得字段很多，但放久了会发现，它们都很安分，不会乱跑。</p><p>考试的时候别慌。先把骨架写出来，判断图表类型，再把数据放进正确的位置。</p><p>一步一步来，图就亮起来了。</p>]]>
    </content>
    <id>https://blog.399521.xyz/2026/06/24/echarts-exam-notes/</id>
    <link href="https://blog.399521.xyz/2026/06/24/echarts-exam-notes/"/>
    <published>2026-06-23T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>备考数据可视化的那段时间，不知道为什么总喜欢在很晚的时候看文档。</p>
<p>窗外安静，屏幕亮着，翻着翻着就忽然觉得——ECharts 这个东西，好像不太一样。</p>
<p>它不像平时写 Java 或者 Python，不是在命令计算机”先做这个，再做那个”。更像是在填一]]>
    </summary>
    <title>把 ECharts 当成一张温柔的配置表</title>
    <updated>2026-06-25T04:31:07.929Z</updated>
  </entry>
  <entry>
    <author>
      <name>星屿</name>
    </author>
    <category term="日常" scheme="https://blog.399521.xyz/categories/%E6%97%A5%E5%B8%B8/"/>
    <category term="随笔" scheme="https://blog.399521.xyz/tags/%E9%9A%8F%E7%AC%94/"/>
    <category term="初见" scheme="https://blog.399521.xyz/tags/%E5%88%9D%E8%A7%81/"/>
    <content>
      <![CDATA[<p>傍晚的云被染成了浅浅的粉色，风从窗边经过，把今天最后一点燥热也带走了。</p><p>我忽然觉得，应该找一个地方，把那些容易被忘记的小事好好收起来。</p><p>可能是一首循环了很多遍的歌，一张偶然拍到的晚霞，也可能只是某个瞬间突然冒出来的奇怪念头。它们看起来并不重要，却悄悄组成了生活闪闪发亮的部分。</p><h2 id="欢迎来到星屿"><a href="#欢迎来到星屿" class="headerlink" title="欢迎来到星屿"></a>欢迎来到星屿</h2><p>这里不会有宏大的开场，只有一些轻飘飘的日常、喜欢的作品，以及偶尔认真写下的心情。</p><p>如果你也刚好路过，就坐一会儿吧。</p><p>愿我们都能在平凡的日子里，捡到属于自己的小星星。✨</p>]]>
    </content>
    <id>https://blog.399521.xyz/2026/06/23/hello-world/</id>
    <link href="https://blog.399521.xyz/2026/06/23/hello-world/"/>
    <published>2026-06-22T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>傍晚的云被染成了浅浅的粉色，风从窗边经过，把今天最后一点燥热也带走了。</p>
<p>我忽然觉得，应该找一个地方，把那些容易被忘记的小事好好收起来。</p>
<p>可能是一首循环了很多遍的歌，一张偶然拍到的晚霞，也可能只是某个瞬间突然冒出来的奇怪念头。它们看起来并不重要，却]]>
    </summary>
    <title>在星光落下之前</title>
    <updated>2026-06-24T15:00:10.737Z</updated>
  </entry>
</feed>
