<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Untitled Publication]]></title><description><![CDATA[Untitled Publication]]></description><link>https://hn.icodeq.com</link><generator>RSS for Node</generator><lastBuildDate>Fri, 24 Apr 2026 15:56:49 GMT</lastBuildDate><atom:link href="https://hn.icodeq.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[MySQL | 实操：表的内连接]]></title><description><![CDATA[数据操作语言：表连接查询（二）
内连接查询联系1

查询底薪超过公司平均底薪的员工信息？

# 查询底薪超过公司平均底薪的员工信息？
SELECT e2.empno,e2.ename,e2.sal
FROM t_emp e1 JOIN t_emp e2 WHERE e2.sal>=AVG(e1.sal);

SELECT e.empno,e.ename,e.sal
FROM t_emp e JOIN 
(SELECT AVG(sal) avg FROM t_emp) t
ON e.sal>=t....]]></description><link>https://hn.icodeq.com/mysql-or-shi-cao-biao-de-nei-lian-jie</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-shi-cao-biao-de-nei-lian-jie</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Mon, 16 May 2022 01:33:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445780255/VLN7_S0vr.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>数据操作语言：表连接查询（二）</p>
<h4 id="heading-1">内连接查询联系1</h4>
<ul>
<li>查询底薪超过公司平均底薪的员工信息？</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-comment"># 查询底薪超过公司平均底薪的员工信息？</span>
<span class="hljs-keyword">SELECT</span> e2.empno,e2.ename,e2.sal
<span class="hljs-keyword">FROM</span> t_emp e1 <span class="hljs-keyword">JOIN</span> t_emp e2 <span class="hljs-keyword">WHERE</span> e2.sal&gt;=<span class="hljs-keyword">AVG</span>(e1.sal);

<span class="hljs-keyword">SELECT</span> e.empno,e.ename,e.sal
<span class="hljs-keyword">FROM</span> t_emp e <span class="hljs-keyword">JOIN</span> 
(<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">AVG</span>(sal) <span class="hljs-keyword">avg</span> <span class="hljs-keyword">FROM</span> t_emp) t
<span class="hljs-keyword">ON</span> e.sal&gt;=t.avg;
</code></pre>
<ul>
<li>查询 <code>RESEARCH</code> 部门的 人数、最高底薪、最低底薪、平均底薪、平均工龄？</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-comment"># 查询 `RESEARCH` 部门的 人数、最高底薪、最低底薪、平均底薪、平均工龄？</span>
<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">COUNT</span>(*),<span class="hljs-keyword">MAX</span>(e.sal),<span class="hljs-keyword">MIN</span>(e.sal),<span class="hljs-keyword">AVG</span>(e.sal),
<span class="hljs-keyword">AVG</span>(<span class="hljs-keyword">DATEDIFF</span>(<span class="hljs-keyword">NOW</span>(),e.hiredate)/<span class="hljs-number">365</span>)
<span class="hljs-keyword">FROM</span> t_emp e <span class="hljs-keyword">JOIN</span> t_dept d <span class="hljs-keyword">ON</span> e.deptno=d.deptno
<span class="hljs-keyword">WHERE</span> d.dname=<span class="hljs-string">"RESEARCH"</span>;

<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">FLOOR</span>(<span class="hljs-number">28.9</span>);

<span class="hljs-comment"># 查询 `RESEARCH` 部门的 人数、最高底薪、最低底薪、平均底薪、平均工龄？</span>
<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">COUNT</span>(*),<span class="hljs-keyword">MAX</span>(e.sal),<span class="hljs-keyword">MIN</span>(e.sal),<span class="hljs-keyword">AVG</span>(e.sal),
<span class="hljs-keyword">FLOOR</span>(<span class="hljs-keyword">AVG</span>(<span class="hljs-keyword">DATEDIFF</span>(<span class="hljs-keyword">NOW</span>(),e.hiredate)/<span class="hljs-number">365</span>))
<span class="hljs-keyword">FROM</span> t_emp e <span class="hljs-keyword">JOIN</span> t_dept d <span class="hljs-keyword">ON</span> e.deptno=d.deptno
<span class="hljs-keyword">WHERE</span> d.dname=<span class="hljs-string">"RESEARCH"</span>;

<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">FLOOR</span>(<span class="hljs-number">28.9</span>);
<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">CEIL</span>(<span class="hljs-number">1.1</span>);
</code></pre>
<h4 id="heading-2">内连接查询联系2</h4>
<ul>
<li>查询每种职业的 <code>最高工资</code>、<code>最低工资</code>、<code>平均工资</code>、<code>最高工资等级</code> 和 <code>最低工资等级</code> ？</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-comment"># 查询每种职业的 `最高工资`、`最低工资`、`平均工资`、`最高工资等级` 和 `最低工资等级` ？</span>

<span class="hljs-keyword">SELECT</span>
e.job,
<span class="hljs-keyword">MAX</span>(e.sal+<span class="hljs-keyword">IFNULL</span>(e.comm,<span class="hljs-number">0</span>)),
<span class="hljs-keyword">MIN</span>(e.sal+<span class="hljs-keyword">IFNULL</span>(e.comm,<span class="hljs-number">0</span>)),
<span class="hljs-keyword">AVG</span>(e.sal+<span class="hljs-keyword">IFNULL</span>(e.comm,<span class="hljs-number">0</span>)),
<span class="hljs-keyword">MAX</span>(s.grade),
<span class="hljs-keyword">MIN</span>(s.grade)
<span class="hljs-keyword">FROM</span> t_emp E <span class="hljs-keyword">JOIN</span> t_salgrade s
<span class="hljs-keyword">on</span> (e.sal+<span class="hljs-keyword">IFNULL</span>(e.comm,<span class="hljs-number">0</span>)) <span class="hljs-keyword">BETWEEN</span> s.losal <span class="hljs-keyword">AND</span> s.hisal
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> e.job
</code></pre>
<ul>
<li>查询每个底薪超过部门平均底薪的员工信息</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-comment"># 查询每个底薪超过部门平均底薪的员工信息</span>
<span class="hljs-keyword">SELECT</span> e.empno,e.ename,e.sal
<span class="hljs-keyword">FROM</span> t_emp e <span class="hljs-keyword">JOIN</span> 
(<span class="hljs-keyword">SELECT</span> deptno,<span class="hljs-keyword">AVG</span>(sal) <span class="hljs-keyword">AS</span> <span class="hljs-keyword">avg</span> <span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno) t
<span class="hljs-keyword">ON</span> e.deptno=t.deptno <span class="hljs-keyword">AND</span> e.sal&gt;=t.avg;
</code></pre>
]]></content:encoded></item><item><title><![CDATA[MySQL | 表的内连接]]></title><description><![CDATA[数据操作语言：表连接查询（一）
从多张表中提取数据

从多张表提取数据，必须指定关联的条件。如果不定义关联条件就会出现无条件连接，两张表的数据会交叉连接，产生 笛卡尔积。


规定了连接条件的表连接语句，就不会出现笛卡尔积。



# 查询每名员工的部门信息
SELECT e.empno,e.ename,d.dname
FROM t_emp e JOIN t_dept d ON e.deptno=d.deptno;

表连接的分类

表连接分为两种：内连接 和 外连接
内连接是结果集中只保留符合...]]></description><link>https://hn.icodeq.com/mysql-or-biao-de-nei-lian-jie</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-biao-de-nei-lian-jie</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Mon, 16 May 2022 00:46:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445841256/iPU-aBebm.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>数据操作语言：表连接查询（一）</p>
<h3 id="heading-5luo5asa5byg6kgo5lit5oq5yw5pww5o2u">从多张表中提取数据</h3>
<ul>
<li><p>从多张表提取数据，必须指定关联的条件。如果不定义关联条件就会出现无条件连接，两张表的数据会交叉连接，产生 <code>笛卡尔积</code>。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445835860/kv3Z1paCN.jpeg" alt="1" /></p>
</li>
<li><p>规定了连接条件的表连接语句，就不会出现笛卡尔积。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445837010/Xn-0dn_Pr.jpeg" alt="2" /></p>
</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-comment"># 查询每名员工的部门信息</span>
<span class="hljs-keyword">SELECT</span> e.empno,e.ename,d.dname
<span class="hljs-keyword">FROM</span> t_emp e <span class="hljs-keyword">JOIN</span> t_dept d <span class="hljs-keyword">ON</span> e.deptno=d.deptno;
</code></pre>
<h3 id="heading-6kgo6le5o6l55qe5yig57g7">表连接的分类</h3>
<ul>
<li>表连接分为两种：内连接 和 外连接</li>
<li>内连接是结果集中只保留符合连接条件的记录</li>
<li>外连接是不管符不符合连接条件，记录都要保留在<code>结果集</code>中</li>
</ul>
<h3 id="heading-5yaf6le5o6l55qe566a5lul">内连接的简介</h3>
<ul>
<li><p>内连接是最常见的一种表连接，用于查询多张关系表符合连接条件的记录。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445838858/PXVAeYJyr.jpeg" alt="3" /></p>
</li>
</ul>
<h3 id="heading-5yaf6le5o6l55qe5asa56en6kt5rov5b2i5byp">内连接的多种语法形式</h3>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> ...... <span class="hljs-keyword">FROM</span> 表<span class="hljs-number">1</span> <span class="hljs-keyword">JOIN</span> 表<span class="hljs-number">2</span> <span class="hljs-keyword">ON</span> 连接条件;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> ...... <span class="hljs-keyword">FROM</span> 表<span class="hljs-number">1</span> <span class="hljs-keyword">JOIN</span> 表<span class="hljs-number">2</span> <span class="hljs-keyword">WHERE</span> 连接条件;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> ...... <span class="hljs-keyword">FROM</span> 表<span class="hljs-number">1</span>, 表<span class="hljs-number">2</span> <span class="hljs-keyword">WHERE</span> 连接条件;
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445839955/WGLhR4FON.jpeg" alt="4" /></p>
<pre><code class="lang-SQL"><span class="hljs-comment"># 查询每名员工的部门信息</span>
<span class="hljs-keyword">SELECT</span> e.empno,e.ename,d.dname
<span class="hljs-keyword">FROM</span> t_emp e <span class="hljs-keyword">JOIN</span> t_dept d <span class="hljs-keyword">ON</span> e.deptno=d.deptno;

<span class="hljs-keyword">SELECT</span> e.empno,e.ename,d.dname
<span class="hljs-keyword">FROM</span> t_emp e <span class="hljs-keyword">JOIN</span> t_dept d <span class="hljs-keyword">WHERE</span> e.deptno=d.deptno;

<span class="hljs-keyword">SELECT</span> e.empno,e.ename,d.dname
<span class="hljs-keyword">FROM</span> t_emp e , t_dept d <span class="hljs-keyword">WHERE</span> e.deptno=d.deptno;
</code></pre>
<h4 id="heading-1">内连接练习1</h4>
<ul>
<li>查询每个员工的 工号、姓名、部门名称、底薪、职位、工资等级？</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-comment"># 查询每个员工的 工号、姓名、部门名称、底薪、职位、工资等级？</span>
<span class="hljs-keyword">SELECT</span> e.empno,e.ename,d.dname,e.sal,e.job,s.grade
<span class="hljs-keyword">FROM</span> t_emp e <span class="hljs-keyword">JOIN</span> t_dept d <span class="hljs-keyword">ON</span> e.deptno=d.deptno
<span class="hljs-keyword">JOIN</span> t_salgrade s <span class="hljs-keyword">ON</span> e.sal <span class="hljs-keyword">BETWEEN</span> s.losal <span class="hljs-keyword">AND</span> s.hisal;
</code></pre>
<ul>
<li>内连接的数据表不一定必须有同名字段，只要字段之间符合逻辑关系就可以</li>
</ul>
<h4 id="heading-2">内连接练习2</h4>
<ul>
<li>查询与 <code>SCOTT</code> 相同部门的员工都有谁？</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-comment"># 查询与 SCOTT 相同部门的员工都有谁？</span>
<span class="hljs-keyword">SELECT</span> ename
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> deptno=(<span class="hljs-keyword">SELECT</span> deptno <span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">WHERE</span> ename=<span class="hljs-string">"SCOTT"</span>)
<span class="hljs-keyword">AND</span> ename!=<span class="hljs-string">"SCOTT"</span>;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-comment"># 查询与 SCOTT 相同部门的员工都有谁？</span>

<span class="hljs-keyword">SELECT</span> e2.ename
<span class="hljs-keyword">FROM</span> t_emp e1 <span class="hljs-keyword">JOIN</span> t_emp e2 <span class="hljs-keyword">ON</span> e1.deptno=e2.deptno
<span class="hljs-keyword">WHERE</span> e1.ename=<span class="hljs-string">"SCOTT"</span> <span class="hljs-keyword">AND</span> e2.ename!=<span class="hljs-string">"SCOTT"</span>;
</code></pre>
<ul>
<li>相同的数据表也可以做表连接</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[MySQL | Having子句的使用]]></title><description><![CDATA[数据操作语言：HAVING 子句
分组查询遇到的困难？

查询部门平均底薪超过2000元的部门编号

错误示范
SELECT deptno FROM t_emp
WHERE AVG(sal) >=2000 -- 错在这里出现了聚合函数
GROUP BY deptno;

引入 HAVING 子句
SELECT deptno
FROM t_emp
GROUP BY deptno HAVING AVG(sal)>=2000;

HAVING 子句的用途

查询每个部门中，1982 年以后入职的员工超...]]></description><link>https://hn.icodeq.com/mysql-or-having-zi-ju-de-shi-yong</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-having-zi-ju-de-shi-yong</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Wed, 27 Apr 2022 02:47:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445706542/CE1bt8rsF.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>数据操作语言：HAVING 子句</p>
<h4 id="heading-5yig57ue5pl6ki6ygh5yiw55qe5zuw6zq77yf">分组查询遇到的困难？</h4>
<ul>
<li>查询部门平均底薪超过2000元的部门编号</li>
</ul>
<pre><code class="lang-SQL">错误示范
<span class="hljs-keyword">SELECT</span> deptno <span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">AVG</span>(sal) &gt;=<span class="hljs-number">2000</span> <span class="hljs-comment">-- 错在这里出现了聚合函数</span>
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno;
</code></pre>
<pre><code class="lang-SQL">引入 HAVING 子句
<span class="hljs-keyword">SELECT</span> deptno
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno <span class="hljs-keyword">HAVING</span> <span class="hljs-keyword">AVG</span>(sal)&gt;=<span class="hljs-number">2000</span>;
</code></pre>
<h4 id="heading-having">HAVING 子句的用途</h4>
<ul>
<li>查询每个部门中，1982 年以后入职的员工超过 2 个人的部门编号。</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> deptno <span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> hiredate&gt;=<span class="hljs-string">"1982-01-01"</span>
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno <span class="hljs-keyword">HAVING</span> <span class="hljs-keyword">COUNT</span>(*) &gt;= <span class="hljs-number">2</span>
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> deptno <span class="hljs-keyword">ASC</span>;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-comment"># 查询每个部门中，1982年以后入职的员工超过2个人的部门编号</span>
<span class="hljs-keyword">SELECT</span> deptno
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> hiredate&gt;=<span class="hljs-string">"1982-01-01"</span>
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno <span class="hljs-keyword">HAVING</span> <span class="hljs-keyword">COUNT</span>(*)&gt;=<span class="hljs-number">2</span>;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-comment"># 查询每个部门中，1982年以后入职的员工超过2个人的部门编号</span>
<span class="hljs-keyword">SELECT</span> deptno
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> hiredate&gt;=<span class="hljs-string">"1982-01-01"</span>
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno <span class="hljs-keyword">HAVING</span> <span class="hljs-keyword">COUNT</span>(*)&gt;=<span class="hljs-number">2</span> <span class="hljs-keyword">AND</span> <span class="hljs-keyword">AVG</span>(sal)&gt;=<span class="hljs-number">2000</span>;
</code></pre>
<pre><code class="lang-SQL">错误示范
<span class="hljs-comment"># 查询每个部门中，1982年以后入职的员工超过2个人的部门编号</span>
<span class="hljs-keyword">SELECT</span> deptno
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> hiredate&gt;=<span class="hljs-string">"1982-01-01"</span>
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno <span class="hljs-keyword">HAVING</span> <span class="hljs-keyword">COUNT</span>(*)&gt;=<span class="hljs-number">2</span> <span class="hljs-keyword">AND</span> sal&gt;=<span class="hljs-keyword">AVG</span>(sal);
</code></pre>
<h4 id="heading-having">HAVING 子句的特殊用法</h4>
<ul>
<li>按照数字 <code>1</code> 分组，<code>MySQL</code> 会依据 <code>SELECT</code> 子句中的列进行分组，<code>HAVING</code> 子句也可以正常使用</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> deptno,<span class="hljs-keyword">COUNT</span>(*) <span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> <span class="hljs-number">1</span>;

<span class="hljs-keyword">SELECT</span> deptno,<span class="hljs-keyword">COUNT</span>(*) <span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> <span class="hljs-number">1</span> <span class="hljs-keyword">HAVING</span> deptno <span class="hljs-keyword">IN</span>(<span class="hljs-number">10</span>,<span class="hljs-number">20</span>);
<span class="hljs-comment">-- 不建议这么写，浪费资源</span>
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> deptno,<span class="hljs-keyword">COUNT</span>(*) 
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> deptno <span class="hljs-keyword">IN</span>(<span class="hljs-number">10</span>,<span class="hljs-number">20</span>)
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> <span class="hljs-number">1</span>;
<span class="hljs-comment">-- 推荐这么写</span>
</code></pre>
]]></content:encoded></item><item><title><![CDATA[MySQL | 分组查询的应用]]></title><description><![CDATA[数据操作语言：分组查询
为什么要分组？

默认情况下汇总函数是对全表范围内的数据做统计
GROUP BY 子句的作用是通过一定的规则将一个数据集划分成若干个小的区域，然后针对每个小区域分别进行数据汇总处理

SELECT deptno,AVG(sal) FROM t_emp
GROUP BY deptno;

SELECT deptno,ROUND(AVG(sal)) FROM t_emp
GROUP BY deptno;
-- ROUND 取整

逐级分组

数据库支持多列分组条件，执行的时候...]]></description><link>https://hn.icodeq.com/mysql-or-fen-zu-cha-xun-de-ying-yong</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-fen-zu-cha-xun-de-ying-yong</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Wed, 27 Apr 2022 01:07:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445751189/L5NdyRP9t.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>数据操作语言：分组查询</p>
<h4 id="heading-5li65lua5lmi6kab5yig57ue77yf">为什么要分组？</h4>
<ul>
<li>默认情况下汇总函数是对全表范围内的数据做统计</li>
<li><code>GROUP BY</code> 子句的作用是通过一定的规则将一个数据集划分成若干个小的区域，然后针对每个小区域分别进行数据汇总处理</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> deptno,<span class="hljs-keyword">AVG</span>(sal) <span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> deptno,<span class="hljs-keyword">ROUND</span>(<span class="hljs-keyword">AVG</span>(sal)) <span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno;
<span class="hljs-comment">-- ROUND 取整</span>
</code></pre>
<h4 id="heading-6ycq57qn5yig57ue">逐级分组</h4>
<ul>
<li>数据库支持多列分组条件，执行的时候逐级分组。</li>
<li>查询每个部分里，每种职位的人员数量和平均底薪</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> deptno,job,<span class="hljs-keyword">COUNT</span>(*),<span class="hljs-keyword">AVG</span>(sal)
<span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno,job
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> deptno;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> deptno,job,<span class="hljs-keyword">COUNT</span>(*),<span class="hljs-keyword">AVG</span>(sal) 
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno,job
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> deptno
</code></pre>
<h4 id="heading-select">对 SELECT 子句的要求</h4>
<ul>
<li>查询语句中如果含有 <code>GROUP BY</code> 子句，那么 <code>SELECT</code> 子句中的内容就必须要遵守规定：<ul>
<li><code>SELECT</code> 子句中可以包含聚合函数，或者 <code>GROUP BY</code> 子句的分组列，其余内容君不可出现在 <code>SELECT</code> 子句中。</li>
</ul>
</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> deptno,<span class="hljs-keyword">COUNT</span>(*),<span class="hljs-keyword">AVG</span>(sal)
<span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> dept_no,<span class="hljs-keyword">COUNT</span>(*),<span class="hljs-keyword">AVG</span>(sal),sal
<span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno;
<span class="hljs-comment">-- XXXXXXXXXXXXXX</span>
</code></pre>
<h5 id="heading-5pl55yl6kee5yiz5qch6aqm">查看规则校验</h5>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> @@GLOBAL.sql_mode;
<span class="hljs-keyword">SELECT</span> @@SESSION.sql_mode;
</code></pre>
<h4 id="heading-5a55yig57ue57ut5p6c6zug5yan5qyh5yga5rgh5oc76k6h566x">对分组结果集再次做汇总计算</h4>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span>
    deptno,<span class="hljs-keyword">COUNT</span>(*),<span class="hljs-keyword">AVG</span>(sal),<span class="hljs-keyword">MAX</span>(sal),<span class="hljs-keyword">MIN</span>(sal)
<span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno <span class="hljs-keyword">WITH</span> <span class="hljs-keyword">ROLLUP</span>
<span class="hljs-comment">-- WITH ROLLUP 汇总</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445749846/nVudXRehc.jpeg" alt="01" /></p>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> deptno,<span class="hljs-keyword">AVG</span>(sal),<span class="hljs-keyword">SUM</span>(sal),<span class="hljs-keyword">MAX</span>(sal),<span class="hljs-keyword">MIN</span>(sal),<span class="hljs-keyword">count</span>(*)
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno <span class="hljs-keyword">WITH</span> <span class="hljs-keyword">ROLLUP</span>
</code></pre>
<h4 id="heading-groupconcat">GROUP_CONCAT 函数</h4>
<ul>
<li><p><code>GROUP_CONCAT</code> 函数可以把分组查询中的某个字段拼接成一个字符串</p>
</li>
<li><p>查询每个部门内底薪超过2000元的人数和员工命令</p>
</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> deptno,<span class="hljs-keyword">GROUP_CONCAT</span>(ename),<span class="hljs-keyword">COUNT</span>(*)
<span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">WHERE</span> sal&gt;=<span class="hljs-number">2000</span>
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> deptno,<span class="hljs-keyword">COUNT</span>(*),<span class="hljs-keyword">GROUP_CONCAT</span>(ename)
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> sal&gt;=<span class="hljs-number">2000</span>
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> deptno;
</code></pre>
<h4 id="heading-5zce56en5a2q5yl55qe5omn6kgm6ag65bqp">各种子句的执行顺序</h4>
<ul>
<li>查询语句中，<code>GROUP BY</code> 子句应该被 第几个执行？</li>
</ul>
<p><code>FROM</code> -&gt; <code>WHERE</code> -&gt; <code>GROUP BY</code> -&gt; <code>SELECT</code> -&gt; <code>ORDER BY</code> -&gt; <code>LIMIT</code></p>
]]></content:encoded></item><item><title><![CDATA[MySQL | 聚合函数的使用]]></title><description><![CDATA[数据操作语言：聚合函数
什么是聚合函数

聚合函数在数据的查询分析中，应用十分广泛。聚合函数可以对 数据求和、求 最大值 和 最小值 、求 平均值 等等。
求公司员工的评价月收入是多少？

SELECT AVG(sal+IFNULL(comm,0)) FROM t_emp;

SELECT AVG(sal+IFNULL(comm,0)) AS avg
FROM t_emp;

SUM 函数

SUM 函数用于求和，只能用户数字类型，字符类型的统计结果为 0 ，日期类型统计结果是毫秒数相加

SE...]]></description><link>https://hn.icodeq.com/mysql-or-ju-he-han-shu-de-shi-yong</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-ju-he-han-shu-de-shi-yong</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Tue, 26 Apr 2022 22:48:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445830534/ZBcuP7nsw.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>数据操作语言：聚合函数</p>
<h4 id="heading-5lua5lmi5piv6iga5zci5ye95pww">什么是聚合函数</h4>
<ul>
<li>聚合函数在数据的查询分析中，应用十分广泛。聚合函数可以对 <code>数据求和</code>、求 <code>最大值</code> 和 <code>最小值</code> 、求 <code>平均值</code> 等等。</li>
<li>求公司员工的评价月收入是多少？</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">AVG</span>(sal+<span class="hljs-keyword">IFNULL</span>(comm,<span class="hljs-number">0</span>)) <span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">AVG</span>(sal+<span class="hljs-keyword">IFNULL</span>(comm,<span class="hljs-number">0</span>)) <span class="hljs-keyword">AS</span> <span class="hljs-keyword">avg</span>
<span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<h4 id="heading-sum">SUM 函数</h4>
<ul>
<li><code>SUM</code> 函数用于求和，只能用户数字类型，字符类型的统计结果为 0 ，日期类型统计结果是毫秒数相加</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">SUM</span>(ename) <span class="hljs-keyword">FROM</span> t_emp;

<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">SUM</span>(sal) <span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> deptno <span class="hljs-keyword">IN</span> (<span class="hljs-number">10</span>,<span class="hljs-number">20</span>);
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">SUM</span>(sal)
<span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">WHERE</span> deptno <span class="hljs-keyword">IN</span>(<span class="hljs-number">10</span>,<span class="hljs-number">20</span>);
</code></pre>
<h4 id="heading-max">MAX 函数</h4>
<ul>
<li><code>MAX</code> 函数用于获得非空值的最大值。</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">MAX</span>(comm) <span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<ul>
<li>问题1：查询10和20部门中，月收入最高的员工？</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">MAX</span>(sal+<span class="hljs-keyword">IFNULL</span>(comm,<span class="hljs-number">0</span>)) <span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> deptno <span class="hljs-keyword">IN</span>(<span class="hljs-number">10</span>,<span class="hljs-number">20</span>)
</code></pre>
<ul>
<li>问题2：查询员工名字最长的是几个字符？</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">MAX</span>(<span class="hljs-keyword">LENGTH</span>(ename)) <span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<h4 id="heading-min">MIN 函数</h4>
<ul>
<li><code>MIN</code> 函数用于获得非空值的最小值。</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">MIN</span>(empno) <span class="hljs-keyword">FROM</span> t_emp;
<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">MIN</span>(hiredate) <span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<h4 id="heading-avg">AVG 函数</h4>
<ul>
<li><code>AVG</code> 函数用于获得非空值的平均值，非数字数据统计结果为 0</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">AVG</span>(sal+<span class="hljs-keyword">IFNULL</span>(comm,<span class="hljs-number">0</span>)) <span class="hljs-keyword">FROM</span> t_emp;

<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">AVG</span>(ename) <span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<h4 id="heading-count">COUNT 函数</h4>
<ul>
<li><code>COUNT(*)</code> 用于获得包含空值的记录数，<code>COUNT(列名)</code> 用于获得包含非空值的记录数。</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">COUNT</span>(*) <span class="hljs-keyword">FROM</span> t_emp;

<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">COUNT</span>(comm) <span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> 
    <span class="hljs-keyword">COUNT</span>(*), <span class="hljs-keyword">COUNT</span>(comm)
<span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<ul>
<li>查询 10 和 20 部门中，底薪超过 2000 元并且工龄超过 15 年的员工人数？</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">COUNT</span>(*) <span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> deptno <span class="hljs-keyword">IN</span>(<span class="hljs-number">10</span>,<span class="hljs-number">20</span>) <span class="hljs-keyword">AND</span> sal&gt;= <span class="hljs-number">2000</span>
<span class="hljs-keyword">AND</span> <span class="hljs-keyword">DATEDIFF</span>(<span class="hljs-keyword">NOW</span>(), hiredate)/<span class="hljs-number">365</span>&gt;=<span class="hljs-number">15</span>;
</code></pre>
<ul>
<li>查询 1985 年以后入职的员工，底薪超过公司平均底薪的员工数量？</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">COUNT</span>(*) <span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> hiredate&gt;=<span class="hljs-string">"1985-01-01"</span>
<span class="hljs-keyword">AND</span> sal&gt;<span class="hljs-keyword">AVG</span>(sal); <span class="hljs-comment">-- XXXXXXXX</span>
<span class="hljs-comment">-- 聚合函数永远不能出现在 WHERE 子句里面</span>
</code></pre>
]]></content:encoded></item><item><title><![CDATA[MySQL | 条件查询的语句（二）]]></title><description><![CDATA[数据操作语言：条件查询（二）
逻辑运算符




序号表达式意义例子



1AND与关系age > 18 AND sex = "男"

2OR或关系empno = 8000 OR deptno = 20

3NOT非关系NOT deptno =20

4XOR异或关系age > 18 XOR sex = "男"


SELECT
    ename,deptno
FROM t_emp
WHERE NOT deptno IN(10,20);
WHERE NOT deptno IN(10,20) ...]]></description><link>https://hn.icodeq.com/mysql-or-tiao-jian-cha-xun-de-yu-ju-er</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-tiao-jian-cha-xun-de-yu-ju-er</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Mon, 25 Apr 2022 23:34:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445824318/oh50sgFWf.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>数据操作语言：条件查询（二）</p>
<h4 id="heading-6yc76l6r6lq566x56ym">逻辑运算符</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>序号</td><td>表达式</td><td>意义</td><td>例子</td></tr>
</thead>
<tbody>
<tr>
<td>1</td><td>AND</td><td>与关系</td><td><code>age &gt; 18 AND sex = "男"</code></td></tr>
<tr>
<td>2</td><td>OR</td><td>或关系</td><td><code>empno = 8000 OR deptno = 20</code></td></tr>
<tr>
<td>3</td><td>NOT</td><td>非关系</td><td><code>NOT deptno =20</code></td></tr>
<tr>
<td>4</td><td>XOR</td><td>异或关系</td><td><code>age &gt; 18 XOR sex = "男"</code></td></tr>
</tbody>
</table>
</div><pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span>
    ename,deptno
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">NOT</span> deptno <span class="hljs-keyword">IN</span>(<span class="hljs-number">10</span>,<span class="hljs-number">20</span>);
WHERE NOT deptno IN(10,20) XOR sal&gt;=2000;
</code></pre>
<h4 id="heading-5lqm6lb5yi25oyj5l2n6lq566x">二进制按位运算</h4>
<ul>
<li>二进制位运算的实质是将参与运算的两个操作数，按对应的二进制数逐位进行逻辑运算。</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-number">3</span> &amp; <span class="hljs-number">7</span>;
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445822042/vBRw0ZB4V.png" alt="08" /></p>
<h5 id="heading-5oyj5l2n6lq566x56ym">按位运算符</h5>
<div class="hn-table">
<table>
<thead>
<tr>
<td>序号</td><td>表达式</td><td>意义</td><td>例子</td></tr>
</thead>
<tbody>
<tr>
<td>1</td><td>&amp;</td><td>位与关系</td><td><code>3 &amp; 7</code></td></tr>
<tr>
<td>2</td><td>\</td><td></td><td>位或关系</td><td>`3</td><td>7`</td></tr>
<tr>
<td>3</td><td>~</td><td>位取反</td><td><code>`~10</code></td></tr>
<tr>
<td>4</td><td>^</td><td>位异或</td><td><code>3 ^ 7</code></td></tr>
<tr>
<td>5</td><td>&lt;&lt;</td><td>左移</td><td><code>10 &lt;&lt; 1</code></td></tr>
<tr>
<td>6</td><td>&gt;&gt;</td><td>右移</td><td><code>10 &gt;&gt; 1</code></td></tr>
</tbody>
</table>
</div><p>WHERE 子句的注意事项</p>
<ul>
<li>WHERE 子句中，条件执行的顺序是从左到右的。所以我们应该把索引条件，或者筛选掉记录最多的条件写在最左侧</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445823111/LHzzSd3lz.jpeg" alt="10" /></p>
<ul>
<li>子句优先级<ul>
<li>索引条件最左边，再是筛选最多的，最后是普通条件</li>
</ul>
</li>
</ul>
<h4 id="heading-5zce56en5a2q5yl55qe5omn6kgm6ag65bqp">各种子句的执行顺序</h4>
<ul>
<li>条件查询中，WHERE 子句应该是第几个执行？</li>
</ul>
<p>​    <code>FROM -&gt; WHERE -&gt; SELECT -&gt; ORDER BY -&gt; LIMIT</code></p>
]]></content:encoded></item><item><title><![CDATA[MySQL | 条件查询的语句（一）]]></title><description><![CDATA[数据操作语言：条件查询（一）
条件查询

很多时候，用户感兴趣的并不是逻辑表里的全部记录，
而只是他们当中能够满足某一种或某几种条件的记录。这类条件要用 WHERE 子句来实现数据的筛选


SELECT ...... FROM ..... WHERE 条件 [AND | OR] 条件 ...... ;


SELECT empno,ename,sal
FROM t_emp
WHERE deptno=10 AND sal>=2000;
WHERE (deptno=10 OR deptno=20)...]]></description><link>https://hn.icodeq.com/mysql-or-tiao-jian-cha-xun-de-yu-ju-yi</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-tiao-jian-cha-xun-de-yu-ju-yi</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Mon, 25 Apr 2022 22:13:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445816443/LtngUFs4g.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4 id="heading-5pww5o2u5pon5l2c6kt6kia77ya5p2h5lu25pl6ki77yi5lia77yj">数据操作语言：条件查询（一）</h4>
<h4 id="heading-5p2h5lu25pl6ki">条件查询</h4>
<ul>
<li><p>很多时候，用户感兴趣的并不是逻辑表里的全部记录，</p>
<p>而只是他们当中能够满足某一种或某几种条件的记录。这类条件要用 <code>WHERE</code> 子句来实现数据的筛选</p>
</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> ...... <span class="hljs-keyword">FROM</span> ..... <span class="hljs-keyword">WHERE</span> 条件 [<span class="hljs-keyword">AND</span> | <span class="hljs-keyword">OR</span>] 条件 ...... ;
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445815207/rOvfdAaOI.jpeg" alt="07" /></p>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> empno,ename,sal
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> deptno=<span class="hljs-number">10</span> <span class="hljs-keyword">AND</span> sal&gt;=<span class="hljs-number">2000</span>;
WHERE (deptno=10 OR deptno=20)AND sal&gt;=2000;
</code></pre>
<h4 id="heading-5zub57g76lq566x56ym">四类运算符</h4>
<ul>
<li><code>WHERE</code> 语句中的条件运算会用到以下四种运算符：</li>
</ul>
<div class="hn-table">
<table>
<thead>
<tr>
<td>序号</td><td>运算符</td></tr>
</thead>
<tbody>
<tr>
<td>1</td><td>数学运算符</td></tr>
<tr>
<td>2</td><td>比较运算符</td></tr>
<tr>
<td>3</td><td>逻辑运算符</td></tr>
<tr>
<td>4</td><td>按位运算符</td></tr>
</tbody>
</table>
</div><h4 id="heading-566x5pww6lq566x56ym">算数运算符</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>序号</td><td>表达式</td><td>意义</td><td>例子</td></tr>
</thead>
<tbody>
<tr>
<td>1</td><td>+</td><td>加法</td><td>1 + 2 + 3</td></tr>
<tr>
<td>2</td><td>-</td><td>减法</td><td>1 - 2 - 3</td></tr>
<tr>
<td>3</td><td>*</td><td>乘法</td><td>5 * 35</td></tr>
<tr>
<td>4</td><td>/</td><td>除法</td><td>231 / 15</td></tr>
<tr>
<td>5</td><td>%</td><td>求模</td><td>10 % 3</td></tr>
</tbody>
</table>
</div><blockquote>
<p>查询 10 部门里面 年收入超过 15K 美金，并且工龄超过二十年 的员工信息</p>
</blockquote>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> empno,ename,sal,hiredate
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> deptno=<span class="hljs-number">10</span> <span class="hljs-keyword">AND</span> (sal+<span class="hljs-keyword">IFNULL</span>(comm,<span class="hljs-number">0</span>))*<span class="hljs-number">12</span>&gt;=<span class="hljs-number">15000</span>;
AND DATEDIFF(NOW(),hiredata)/265&gt;=20;

<span class="hljs-comment">-- 获取当前日期</span>
<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">NOW</span>()
<span class="hljs-comment">-- 引入一个新函数 IFNLL 若第一个参数为 NULL 则返回第二个参数</span>
<span class="hljs-keyword">SELECT</span> <span class="hljs-number">10</span>+<span class="hljs-keyword">IFNULL</span>(<span class="hljs-literal">null</span>,<span class="hljs-number">0</span>);
</code></pre>
<h4 id="heading-5qu6l6d6lq566x56ym77yi5lia77yj">比较运算符（一）</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>序号</td><td>表达式</td><td>意义</td><td>例子</td></tr>
</thead>
<tbody>
<tr>
<td>1</td><td>&gt;</td><td>大于</td><td><code>age &gt; 18</code></td></tr>
<tr>
<td>2</td><td>&gt;=</td><td>大于等于</td><td><code>age &gt;= 18</code></td></tr>
<tr>
<td>3</td><td>&lt;</td><td>小于</td><td><code>sal &lt; 3000</code></td></tr>
<tr>
<td>4</td><td>&lt;=</td><td>小于等于</td><td><code>sal &lt;= 3000</code></td></tr>
<tr>
<td>5</td><td>=</td><td>等于</td><td><code>deptno = 10</code></td></tr>
<tr>
<td>6</td><td>!=</td><td>不等于</td><td><code>deptno != 30</code></td></tr>
<tr>
<td>7</td><td>IN</td><td>包含</td><td><code>deptno IN(10,30,40)</code></td></tr>
</tbody>
</table>
</div><blockquote>
<p>查询 10,20,30 部门里面，在 1985 年以前入职的员工并且不是 <code>saselmen</code> 员工的信息</p>
</blockquote>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> 
    empno,ename,sal,deptno,hiredate
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">WHERE</span> deptno <span class="hljs-keyword">IN</span>(<span class="hljs-number">10</span>,<span class="hljs-number">20</span>,<span class="hljs-number">30</span>) <span class="hljs-keyword">AND</span> job!=<span class="hljs-string">"SALESMAN"</span>
<span class="hljs-keyword">AND</span> hiredate&lt;<span class="hljs-string">"1985-01-01"</span>;
</code></pre>
<h4 id="heading-5qu6l6d6lq566x56ym77yi5lqm77yj">比较运算符（二）</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>序号</td><td>表达式</td><td>意义</td><td>例子</td></tr>
</thead>
<tbody>
<tr>
<td>8</td><td>IS NULL</td><td>为空</td><td><code>comm IS NULL</code></td></tr>
<tr>
<td>9</td><td>IS NOT NULL</td><td>不为空</td><td><code>comm IS NOT NULL</code></td></tr>
<tr>
<td>10</td><td>BETWEEN AND</td><td>范围</td><td><code>sal BETWEEN 2000 AND 3000</code></td></tr>
<tr>
<td>11</td><td>LIKE</td><td>模糊查询</td><td><code>ename LIKE "A%"</code></td></tr>
<tr>
<td>12</td><td>REGEXP</td><td>正则表达式</td><td><code>ename REGEXP "[a-zA-Z]{4}"</code></td></tr>
</tbody>
</table>
</div><pre><code class="lang-sqlite">SELECT 
ename,comm,sal
FROM t_emp WHERE comm IS NOT NULL
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> 
    ename,comm,sal
<span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">WHERE</span> comm <span class="hljs-keyword">IS</span> <span class="hljs-literal">NULL</span>
<span class="hljs-keyword">AND</span> sal <span class="hljs-keyword">BETWEEN</span> <span class="hljs-number">2000</span> <span class="hljs-keyword">AND</span> <span class="hljs-number">3000</span>;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> 
    ename,comm,sal
<span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">WHERE</span> comm <span class="hljs-keyword">IS</span> <span class="hljs-literal">NULL</span>
<span class="hljs-keyword">AND</span> sal <span class="hljs-keyword">BETWEEN</span> <span class="hljs-number">2000</span> <span class="hljs-keyword">AND</span> <span class="hljs-number">3000</span>
<span class="hljs-keyword">AND</span> ename <span class="hljs-keyword">LIKE</span> <span class="hljs-string">"%A%"</span>;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> 
    ename,comm,sal
<span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">WHERE</span> comm <span class="hljs-keyword">IS</span> <span class="hljs-literal">NULL</span>
<span class="hljs-keyword">AND</span> sal <span class="hljs-keyword">BETWEEN</span> <span class="hljs-number">2000</span> <span class="hljs-keyword">AND</span> <span class="hljs-number">3000</span>
<span class="hljs-keyword">AND</span> ename <span class="hljs-keyword">LIKE</span> <span class="hljs-string">"_LAKE"</span>;
<span class="hljs-comment">-- _ 运算符</span>
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> 
    ename,comm,sal
<span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">WHERE</span> comm <span class="hljs-keyword">IS</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>
<span class="hljs-keyword">AND</span> sal <span class="hljs-keyword">BETWEEN</span> <span class="hljs-number">1000</span> <span class="hljs-keyword">AND</span> <span class="hljs-number">3000</span>
<span class="hljs-keyword">AND</span> ename REGEXP <span class="hljs-string">"^[\\u4e00-\\u9fa5]{2,4}$"</span>;
<span class="hljs-comment">-- 两到四个字符的中文</span>
</code></pre>
]]></content:encoded></item><item><title><![CDATA[MySQL | 如何去除结果集中的重复记录]]></title><description><![CDATA[数据操作语言：去除重复记录
结果集中的重复记录

假如我们要查询员工表有多少种职业，写出来的 SQL 语句如下：


去除重复记录

如果我们需要去除重复的数据，可以使用 DISTINCT 关键字来实现

SELECT DISTINCT 字段 FROM ......;


SELECT job FROM t_emp;
SELECT DISTINCT job FROM t_emp;

注意事项

使用 DISTINCT 的 SELECT 子句中只能查询一列数据，如果查询多列，去除重复记录就会失效。...]]></description><link>https://hn.icodeq.com/mysql-or-ru-he-qu-chu-jie-guo-ji-zhong-de-zhong-fu-ji-lu</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-ru-he-qu-chu-jie-guo-ji-zhong-de-zhong-fu-ji-lu</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Mon, 25 Apr 2022 21:59:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445766816/a-1J1hzi0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4 id="heading-5pww5o2u5pon5l2c6kt6kia77ya5y676zmk6yen5asn6k6w5b2v">数据操作语言：去除重复记录</h4>
<h4 id="heading-57ut5p6c6zug5lit55qe6yen5asn6k6w5b2v">结果集中的重复记录</h4>
<ul>
<li>假如我们要查询员工表有多少种职业，写出来的 <code>SQL</code> 语句如下：</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445761866/xul7NWiTg.jpeg" alt="3" /></p>
<h4 id="heading-5y676zmk6yen5asn6k6w5b2v">去除重复记录</h4>
<ul>
<li>如果我们需要去除重复的数据，可以使用 <code>DISTINCT</code> 关键字来实现</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">DISTINCT</span> 字段 <span class="hljs-keyword">FROM</span> ......;
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445762954/BOoqtErlv.jpeg" alt="3" /></p>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> job <span class="hljs-keyword">FROM</span> t_emp;
<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">DISTINCT</span> job <span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<h4 id="heading-5roo5osp5lql6ag5">注意事项</h4>
<ul>
<li>使用 <code>DISTINCT</code> 的 <code>SELECT</code> 子句中只能查询一列数据，如果查询多列，去除重复记录就会失效。</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445764107/LA7uuOA_z.jpeg" alt="3" /></p>
<ul>
<li><code>DISTINCT</code> 关键字只能在 <code>SELECT</code> 子句中使用一次</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445765706/leq85N2Lf.jpeg" alt="6" /></p>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">DISTINCT</span> job <span class="hljs-keyword">FROM</span> t_emp;
<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">DISTINCT</span> job,ename <span class="hljs-keyword">FROM</span> t_emp;
<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">DISTINCT</span> job,<span class="hljs-keyword">DISTINCT</span> ename <span class="hljs-keyword">FROM</span> t_emp;
<span class="hljs-keyword">SELECT</span> job,<span class="hljs-keyword">DISTINCT</span> ename <span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
]]></content:encoded></item><item><title><![CDATA[MySQL | 如何对查询结果集进行排序]]></title><description><![CDATA[数据操作语言：结果集排序

如果没有设置，查询语句不会对结果集进行排序。也就是说，如果想让结果集按照某种顺序排列，就必须使用 ORDER BY 子句。

SELECT ...... FROM ...... ORDER BY 列名 [ASC | DESC];

SELECT ename,sal FROM t_emp ORDER BY sal;

SELECT empno,ename,sal,deptno FROM t_emp ORDER BY sal DESC;

排序关键字

ASC 代表升序（...]]></description><link>https://hn.icodeq.com/mysql-or-ru-he-dui-cha-xun-jie-guo-ji-jin-xing-pai-xu</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-ru-he-dui-cha-xun-jie-guo-ji-jin-xing-pai-xu</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Mon, 25 Apr 2022 21:19:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445773896/Y56xOtmkv.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4 id="heading-5pww5o2u5pon5l2c6kt6kia77ya57ut5p6c6zug5o6s5bqp">数据操作语言：结果集排序</h4>
<ul>
<li>如果没有设置，查询语句不会对结果集进行排序。也就是说，如果想让结果集按照某种顺序排列，就必须使用 <code>ORDER BY</code> 子句。</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> ...... <span class="hljs-keyword">FROM</span> ...... <span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> 列名 [<span class="hljs-keyword">ASC</span> | <span class="hljs-keyword">DESC</span>];
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> ename,sal <span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> sal;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> empno,ename,sal,deptno <span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> sal <span class="hljs-keyword">DESC</span>;
</code></pre>
<h4 id="heading-5o6s5bqp5ywz6zsu5a2x">排序关键字</h4>
<ul>
<li><code>ASC</code> 代表升序（默认），<code>DESC</code> 代表降序</li>
<li>如果排序列是数字类型，数据库就按照数字大小排序，如果是日期类型就按日期大小排序，如果是字符串就按照字符集序号排序。</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> ename,sal <span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> hiredate <span class="hljs-keyword">DESC</span>;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> empno,ename,hiredate,deptno <span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> ename <span class="hljs-keyword">ASC</span>;
<span class="hljs-keyword">SELECT</span> empno,ename,hiredate,deptno <span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> hiredate <span class="hljs-keyword">DESC</span>;
</code></pre>
<h4 id="heading-5o6s5bqp5a2x5q615yaf5a6555u45zcm55qe5oof5ya1">排序字段内容相同的情况</h4>
<ul>
<li><p>默认情况下，如果两条数据排序字段内容相同，那么排序会是什么样子？</p>
</li>
<li><p>我们可以使用 <code>ORDER BY</code> 规定首要排序条件和次要排序条件。</p>
<p>数据库会先按照首要排序条件排序，如果遇到首要排序内容相同的记录，那么就会启用次要排序条件接着排序。</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445772733/xG3SdK9bm.jpeg" alt="2" /></p>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> empno,ename,sal,hiredate <span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> sal <span class="hljs-keyword">DESC</span>,hiredate <span class="hljs-keyword">ASC</span>;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> 
    empno,ename,deptno,sal
<span class="hljs-keyword">FROM</span> t_emp
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> deptno,sal <span class="hljs-keyword">DESC</span>;
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> 
    empno,ename,sal
<span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> sal <span class="hljs-keyword">DESC</span> <span class="hljs-keyword">LIMIT</span> <span class="hljs-number">0</span>,<span class="hljs-number">5</span>;
</code></pre>
<h4 id="heading-5o6s5bqpicsg5yig6ag1">排序 + 分页</h4>
<ul>
<li><p><code>ORDER BY</code> 子句书写的时候放在 <code>LIMIT</code> 子句的前面</p>
<p><code>FROM</code> -&gt; <code>SELECT</code> -&gt; <code>ORDER BY</code> -&gt; <code>LIMIT</code></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[MySQL | 数据库的基本查询]]></title><description><![CDATA[数据操作语言：普通查询
记录查询

最基本的查询语句是由 SELECT 和 FROM 关键字组成的

SELECT * FORM t_emp;
SELECT empnpo, ename, sal FROM t_emp;


SELECT 语句屏蔽了物理层的操作。用户不必关心数据的真实存储，交由数据库高效的查找数据

USE demo;
SELECT * FROM t_emp;
SELECT empno,ename,sal FROM t_emp;

使用列命名

通常情况下，SELECT 子句中使...]]></description><link>https://hn.icodeq.com/mysql-or-shu-ju-ku-de-ji-ben-cha-xun</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-shu-ju-ku-de-ji-ben-cha-xun</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Mon, 25 Apr 2022 19:56:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445787022/rx_RDsrM8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-5pww5o2u5pon5l2c6kt6kia77ya5pmu6yca5pl6ki">数据操作语言：普通查询</h3>
<h4 id="heading-6k6w5b2v5pl6ki">记录查询</h4>
<ul>
<li>最基本的查询语句是由 <code>SELECT</code> 和 <code>FROM</code> 关键字组成的</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FORM</span> t_emp;
<span class="hljs-keyword">SELECT</span> empnpo, ename, sal <span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<ul>
<li><code>SELECT</code> 语句屏蔽了物理层的操作。用户不必关心数据的真实存储，交由数据库高效的查找数据</li>
</ul>
<pre><code class="lang-sql"><span class="hljs-keyword">USE</span> demo;
<span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> t_emp;
<span class="hljs-keyword">SELECT</span> empno,ename,sal <span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<h4 id="heading-5l255so5yix5zg95zcn">使用列命名</h4>
<ul>
<li>通常情况下，<code>SELECT</code> 子句中使用了表达式，那么这列的名字就默认为表达式，因此需要一种对列名重命名的机制。</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">SELECT</span>
    empno,
    sal*<span class="hljs-number">12</span> <span class="hljs-keyword">AS</span> <span class="hljs-string">"income"</span>
<span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> empno,sal*<span class="hljs-number">12</span> <span class="hljs-keyword">AS</span> <span class="hljs-string">"icome"</span> <span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<h4 id="heading-5pl6ki6kt5yl55qe5a2q5yl5omn6kgm6ag65bqp">查询语句的子句执行顺序</h4>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span>
    empno,
    sal*<span class="hljs-number">12</span> <span class="hljs-keyword">AS</span> <span class="hljs-string">"income"</span>
<span class="hljs-keyword">FROM</span> t_emp;
</code></pre>
<ol>
<li>语法分析与优化<ul>
<li>读取 <code>SQL</code> 语句</li>
</ul>
</li>
<li><code>FORM</code><ul>
<li>选择数据来源</li>
</ul>
</li>
<li><code>SELECT</code><ul>
<li>选择输出内容</li>
</ul>
</li>
</ol>
<h4 id="heading-5pww5o2u5yig6ag1">数据分页</h4>
<ul>
<li>比如我们查看朋友圈，只会加载少量部分信息，不用一次性加载全部朋友圈，那样只会浪费 <code>CPU</code> 时间、内存和网络带宽</li>
<li>如果结果集的记录很多，则可以使用 <code>LIMIT</code> 关键字限定结果集数量。</li>
</ul>
<pre><code class="lang-SQL"> <span class="hljs-keyword">SELECT</span> ...... <span class="hljs-keyword">FROM</span> ... <span class="hljs-keyword">LIMIT</span> 起始位置, 偏移量;
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445785872/DS8WxQyBf.jpeg" alt="1" /></p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> empno, ename <span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">LIMIT</span> <span class="hljs-number">10</span>, <span class="hljs-number">5</span>;
</code></pre>
<h4 id="heading-5pww5o2u5yig6ag155qe566a5yaz55so5rov">数据分页的简写用法</h4>
<ul>
<li>如果 <code>LIMIT</code> 子句只有一个参数，它表示的是偏移量，起始值默认为 0</li>
</ul>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> empno, ename <span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">LIMIT</span> <span class="hljs-number">10</span>;
<span class="hljs-keyword">SELECT</span> empno, ename <span class="hljs-keyword">FROM</span> t_emp <span class="hljs-keyword">LIMIT</span> <span class="hljs-number">0</span>,<span class="hljs-number">10</span>;
</code></pre>
<p><code>FROM</code> -&gt; <code>SELECT</code> -&gt; <code>LIMIT</code></p>
]]></content:encoded></item><item><title><![CDATA[笔记 | 使用 Uptime Kuma 监控网站并推送微信]]></title><description><![CDATA[前言
提到监控，大家想到的大概是 UptimeRobot ，个人免费 50 个站点，而且监控页面也很炫酷
但是有个缺点就是似乎定制域名的功能要付费？
试过把站点扒下来，但是好像有 CORS 的跨域问题（（（（
最近几天，朋友那里发现了一款替代品，这页面感觉比 UptimeRobot 还炫酷 *

https://github.com/louislam/uptime-kuma

成品：Zkeq の 监控云台 (icodeq.com)
见图 👀

后台也十分好看 ~

详情页面

并且还实现了微信...]]></description><link>https://hn.icodeq.com/bi-ji-or-shi-yong-uptime-kuma-jian-kong-wang-zhan-bing-tui-song-wei-xin</link><guid isPermaLink="true">https://hn.icodeq.com/bi-ji-or-shi-yong-uptime-kuma-jian-kong-wang-zhan-bing-tui-song-wei-xin</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Sun, 24 Apr 2022 00:30:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446900429/W2_PXBBt9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-5ymn6kia">前言</h2>
<p>提到监控，大家想到的大概是 <a target="_blank" href="https://uptimerobot.com/">UptimeRobot</a> ，个人免费 50 个站点，而且监控页面也很炫酷</p>
<p>但是有个缺点就是似乎定制域名的功能要付费？</p>
<p>试过把站点扒下来，但是好像有 <code>CORS</code> 的跨域问题（（（（</p>
<p>最近几天，朋友那里发现了一款替代品，这页面感觉比 <a target="_blank" href="https://uptimerobot.com/">UptimeRobot</a> 还炫酷 *</p>
<ul>
<li>https://github.com/louislam/uptime-kuma</li>
</ul>
<p>成品：<a target="_blank" href="https://uptime.icodeq.com">Zkeq の 监控云台 (icodeq.com)</a></p>
<p>见图 👀</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446892447/SYcWpqSHG.png" alt="1" /></p>
<h3 id="heading-5zco5yw5lmf5y2b5yig5aw955ylih4">后台也十分好看 ~</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446893736/qyJ7-DvlX.png" alt="2" /></p>
<h3 id="heading-6km5oof6ag16z2i">详情页面</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446894890/2hZcWFLew.png" alt="3" /></p>
<h3 id="heading-5bm25liu6ly5a6e546w5lqg5b6u5lh5o6o6ycb55qe5yqf6io9">并且还实现了微信推送的功能</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446896412/z82wQ1ysG.jpeg" alt="4" /></p>
<h2 id="heading-5a6e546w5q2l6aqk">实现步骤</h2>
<h3 id="heading-5pct5bu66yoo5yig">搭建部分</h3>
<p>项目地址</p>
<ul>
<li>https://github.com/louislam/uptime-kuma</li>
</ul>
<p>&gt;</p>
<blockquote>
<p><code>Replit</code> 推荐部署仓库：https://github.com/valetzx/uptimekumaonreplit</p>
</blockquote>
<p>直接跟教程搭建即可，重点讲一下怎么把推送发到 【正常微信】。</p>
<p>内置一个企业微信通道，但是正常人谁用那玩意啊））））</p>
<p>这里用到的一个项目是方糖的开源版（因为我穷，学生嘛，理解一下））</p>
<ul>
<li><p>https://github.com/easychen/wecomchan</p>
<p>easychen/wecomchan: 通过企业微信向微信推送消息的配置文档、直推函数和可自行搭建的在线服务代码。可以看成Server酱的开源替代方案之一。</p>
</li>
</ul>
<p>其实这个项目里面的 <code>README.md</code> 写的已经很清楚了，甚至连用法都有......</p>
<pre><code class="lang-python">PYTHON版:

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_to_wecom</span>(<span class="hljs-params">text,wecom_cid,wecom_aid,wecom_secret,wecom_touid=<span class="hljs-string">'@all'</span></span>):</span>
        <span class="hljs-keyword">return</span> response
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_to_wecom_image</span>(<span class="hljs-params">base64_content,wecom_cid,wecom_aid,wecom_secret,wecom_touid=<span class="hljs-string">'@all'</span></span>):</span>
        <span class="hljs-keyword">return</span> response
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_to_wecom_markdown</span>(<span class="hljs-params">text,wecom_cid,wecom_aid,wecom_secret,wecom_touid=<span class="hljs-string">'@all'</span></span>):</span>
        <span class="hljs-keyword">return</span> response
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>

使用实例：

ret = send_to_wecom(<span class="hljs-string">"推送测试\r\n测试换行"</span>, <span class="hljs-string">"企业ID③"</span>, <span class="hljs-string">"应用ID①"</span>, <span class="hljs-string">"应用secret②"</span>);
print(ret)
ret = send_to_wecom(<span class="hljs-string">'&lt;a href="https://www.github.com/"&gt;文本中支持超链接&lt;/a&gt;'</span>, <span class="hljs-string">"企业ID③"</span>, <span class="hljs-string">"应用ID①"</span>, <span class="hljs-string">"应用secret②"</span>);
print(ret)
ret = send_to_wecom_image(<span class="hljs-string">"此处填写图片Base64"</span>, <span class="hljs-string">"企业ID③"</span>, <span class="hljs-string">"应用ID①"</span>, <span class="hljs-string">"应用secret②"</span>);
print(ret)
ret = send_to_wecom_markdown(<span class="hljs-string">"**Markdown 内容**"</span>, <span class="hljs-string">"企业ID③"</span>, <span class="hljs-string">"应用ID①"</span>, <span class="hljs-string">"应用secret②"</span>);
print(ret)
</code></pre>
<p>那么感觉也没啥讲的，直接讲怎么搭建实现吧。</p>
<h3 id="heading-6aaw5ywi5y675oyj5pwz56il">首先去按教程</h3>
<ul>
<li>https://github.com/easychen/wecomchan#企业微信应用消息配置说明</li>
</ul>
<p>配置好自己的企业微信，那么我们可以拿到这么几个字段</p>
<pre><code class="lang-python">wecom_cid = <span class="hljs-string">"wwXXXXXXXXXXXXXXX"</span>
wecom_aid = <span class="hljs-string">"1000XXX"</span>
wecom_secret = <span class="hljs-string">"XXXXXXXXXXXX-XXXXXXXXXXX-XXXXXXXXXXXXXXXX"</span>
</code></pre>
<p>就这三个字段就够了</p>
<h3 id="heading-fastapi">然后去写一下 FastAPI 的配置</h3>
<ul>
<li><p>这个经过我加工了一下....支持了 redis 缓存，需要 <code>Redis</code> 环境</p>
</li>
<li><p><code>loguru</code> 记录日志</p>
</li>
<li><p><code>subprocess</code> 用于启动 <code>Redis</code></p>
</li>
<li><p><code>FastAPI</code> 主要框架</p>
</li>
<li><p><code>uvicorn</code> Fast API 启动器</p>
</li>
<li><p>）不过，我推荐使用 <code>Replit</code> 直接部署，把以下文件直接复制粘贴进去，点 <code>RUN</code> 就行了（）（不行的话来评论区</p>
</li>
</ul>
<p><code>.\main.py</code></p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> base64
<span class="hljs-keyword">import</span> json
<span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">import</span> uvicorn
<span class="hljs-keyword">import</span> redis
<span class="hljs-keyword">import</span> logger <span class="hljs-keyword">as</span> lg
<span class="hljs-keyword">from</span> fastapi <span class="hljs-keyword">import</span> FastAPI, Form
<span class="hljs-keyword">import</span> subprocess
start_redis = <span class="hljs-string">"redis-server redis.conf"</span>

r = redis.Redis(host=<span class="hljs-string">'localhost'</span>, port=<span class="hljs-number">6379</span>, db=<span class="hljs-number">0</span>)


<span class="hljs-comment"># 如果你用的个人版，请将以下填入环境变量中</span>
<span class="hljs-comment"># 并取消注释以下代码</span>
<span class="hljs-comment"># import os</span>
<span class="hljs-comment"># my_secret = os.environ['wecom_cid']</span>
<span class="hljs-comment"># wecom_aid = os.environ['wecom_aid']</span>
<span class="hljs-comment"># wecom_secret = os.environ['wecom_secret']</span>

wecom_cid = <span class="hljs-string">"wwXXXXXXXXXXXXXXX"</span>
wecom_aid = <span class="hljs-string">"1000XXX"</span>
wecom_secret = <span class="hljs-string">"XXXXXXXXXXXX-XXXXXXXXXXX-XXXXXXXXXXXXXXXX"</span>
app = FastAPI()


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_token</span>():</span>
    <span class="hljs-keyword">global</span> wecom_cid, wecom_aid, wecom_secret
    access_token = r.get(<span class="hljs-string">'token'</span>)
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> access_token:
        lg.logger_info(<span class="hljs-string">'Redis access_token is empty, get from wecom'</span>)
        get_token_url = <span class="hljs-string">f"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=<span class="hljs-subst">{wecom_cid}</span>&amp;corpsecret=<span class="hljs-subst">{wecom_secret}</span>"</span>
        lg.logger_info(<span class="hljs-string">'get_token_url: '</span> + get_token_url)
        response = requests.get(get_token_url).content
        lg.logger_info(<span class="hljs-string">'response: '</span> + str(response))
        access_token = json.loads(response).get(<span class="hljs-string">'access_token'</span>)
        lg.logger_success(<span class="hljs-string">'access_token: '</span> + str(access_token))
        r.set(<span class="hljs-string">'token'</span>, access_token, ex=<span class="hljs-number">7000</span>)
    <span class="hljs-keyword">else</span>:
        access_token = access_token.decode(<span class="hljs-string">'utf-8'</span>)
        lg.logger_success(<span class="hljs-string">f"从Redis 中拿到 access_token"</span>)
    <span class="hljs-keyword">return</span> access_token


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_to_wecom</span>(<span class="hljs-params">text, wecom_touid=<span class="hljs-string">'@all'</span></span>):</span>
    access_token = get_token()
    lg.logger_success(<span class="hljs-string">"message: "</span> + str(text))
    <span class="hljs-keyword">if</span> access_token <span class="hljs-keyword">and</span> len(access_token) &gt; <span class="hljs-number">0</span>:
        send_msg_url = <span class="hljs-string">f'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=<span class="hljs-subst">{access_token}</span>'</span>
        data = {
            <span class="hljs-string">"touser"</span>: wecom_touid,
            <span class="hljs-string">"agentid"</span>: wecom_aid,
            <span class="hljs-string">"msgtype"</span>: <span class="hljs-string">"text"</span>,
            <span class="hljs-string">"text"</span>: {
                <span class="hljs-string">"content"</span>: text
            },
            <span class="hljs-string">"duplicate_check_interval"</span>: <span class="hljs-number">600</span>
        }
        response = requests.post(send_msg_url, data=json.dumps(data)).content
        lg.logger_info(<span class="hljs-string">"response: "</span> + str(response))
        <span class="hljs-keyword">return</span> response
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_to_wecom_image</span>(<span class="hljs-params">base64_content, wecom_touid=<span class="hljs-string">'@all'</span></span>):</span>
    access_token = get_token()
    lg.logger_info(<span class="hljs-string">'access_token: '</span> + str(access_token))
    <span class="hljs-keyword">if</span> access_token <span class="hljs-keyword">and</span> len(access_token) &gt; <span class="hljs-number">0</span>:
        upload_url = <span class="hljs-string">f'https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=<span class="hljs-subst">{access_token}</span>&amp;type=image'</span>
        upload_response = requests.post(upload_url, files={
            <span class="hljs-string">"picture"</span>: base64.b64decode(base64_content)
        }).json()
        <span class="hljs-keyword">if</span> <span class="hljs-string">"media_id"</span> <span class="hljs-keyword">in</span> upload_response:
            media_id = upload_response[<span class="hljs-string">'media_id'</span>]
        <span class="hljs-keyword">else</span>:
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>

        send_msg_url = <span class="hljs-string">f'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=<span class="hljs-subst">{access_token}</span>'</span>
        data = {
            <span class="hljs-string">"touser"</span>: wecom_touid,
            <span class="hljs-string">"agentid"</span>: wecom_aid,
            <span class="hljs-string">"msgtype"</span>: <span class="hljs-string">"image"</span>,
            <span class="hljs-string">"image"</span>: {
                <span class="hljs-string">"media_id"</span>: media_id
            },
            <span class="hljs-string">"duplicate_check_interval"</span>: <span class="hljs-number">600</span>
        }
        response = requests.post(send_msg_url, data=json.dumps(data)).content
        lg.logger_success(<span class="hljs-string">"response: "</span> + str(response))
        <span class="hljs-keyword">return</span> response
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_to_wecom_markdown</span>(<span class="hljs-params">text, wecom_touid=<span class="hljs-string">'@all'</span></span>):</span>
    access_token = get_token()
    <span class="hljs-keyword">if</span> access_token <span class="hljs-keyword">and</span> len(access_token) &gt; <span class="hljs-number">0</span>:
        send_msg_url = <span class="hljs-string">f'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=<span class="hljs-subst">{access_token}</span>'</span>
        data = {
            <span class="hljs-string">"touser"</span>: wecom_touid,
            <span class="hljs-string">"agentid"</span>: wecom_aid,
            <span class="hljs-string">"msgtype"</span>: <span class="hljs-string">"markdown"</span>,
            <span class="hljs-string">"markdown"</span>: {
                <span class="hljs-string">"content"</span>: text
            },
            <span class="hljs-string">"duplicate_check_interval"</span>: <span class="hljs-number">600</span>
        }
        lg.logger_success(<span class="hljs-string">"message: "</span> + str(text))
        response = requests.post(send_msg_url, data=json.dumps(data)).content
        lg.logger_success(<span class="hljs-string">"response: "</span> + str(response))
        <span class="hljs-keyword">return</span> response
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>


<span class="hljs-meta">@app.post("/")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span>(<span class="hljs-params">type: str = Form(<span class="hljs-params">...</span>), title: str = Form(<span class="hljs-params">...</span>), body: str = Form(<span class="hljs-params">...</span>), wecom_touid: str = Form(<span class="hljs-params">...</span>)</span>):</span>
    <span class="hljs-keyword">if</span> type == <span class="hljs-string">'note'</span>:
        lg.logger_info(<span class="hljs-string">f'收到笔记消息：<span class="hljs-subst">{title}</span>'</span>)
        data = send_to_wecom(title + <span class="hljs-string">'\n'</span> + body, wecom_touid)
    <span class="hljs-keyword">elif</span> type == <span class="hljs-string">'image'</span>:
        lg.logger_info(<span class="hljs-string">f'收到图片消息：<span class="hljs-subst">{title}</span>'</span>)
        data = send_to_wecom_image(body, wecom_touid)
    <span class="hljs-keyword">elif</span> type == <span class="hljs-string">'markdown'</span>:
        lg.logger_info(<span class="hljs-string">f'收到markdown消息：<span class="hljs-subst">{title}</span>'</span>)
        data = send_to_wecom_markdown(title + <span class="hljs-string">'\n'</span> + body, wecom_touid)
    <span class="hljs-keyword">else</span>:
        data = send_to_wecom(title + <span class="hljs-string">'\n'</span> + body, wecom_touid)
    <span class="hljs-keyword">return</span> data

<span class="hljs-meta">@app.get("/")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span>():</span>
    <span class="hljs-keyword">return</span> {<span class="hljs-string">"msg"</span>: <span class="hljs-string">"好耶，部署成功了！但是值得注意的是请不要将此地址告诉别人（（防止微信消息被刷爆"</span>}

<span class="hljs-meta">@app.head("/")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">head</span>():</span>
    <span class="hljs-keyword">return</span> {<span class="hljs-string">"msg"</span>: <span class="hljs-string">"好耶，部署成功了！但是值得注意的是请不要将此地址告诉别人（（防止微信消息被刷爆"</span>}


<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    print(<span class="hljs-string">"start redis"</span>)
    subprocess.Popen(start_redis, shell=<span class="hljs-literal">True</span>)
    uvicorn.run(<span class="hljs-string">"main:app"</span>, host=<span class="hljs-string">"0.0.0.0"</span>, port=<span class="hljs-number">8080</span>, log_level=<span class="hljs-string">"info"</span>)
</code></pre>
<h3 id="heading-5pel5bx5yqf6io9">日志功能</h3>
<p><code>.\logger.py</code></p>
<pre><code class="lang-python"><span class="hljs-comment"># coding:utf-8</span>
<span class="hljs-keyword">from</span> loguru <span class="hljs-keyword">import</span> logger

logger.add(<span class="hljs-string">"./log/file_{time}.log"</span>, rotation=<span class="hljs-string">"20 MB"</span>)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">logger_error</span>(<span class="hljs-params">msg</span>):</span>
    logger.error(msg)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">logger_warning</span>(<span class="hljs-params">msg</span>):</span>
    logger.warning(msg)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">logger_debug</span>(<span class="hljs-params">msg</span>):</span>
    logger.debug(msg)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">logger_exception</span>(<span class="hljs-params">msg</span>):</span>
    logger.exception(msg)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">logger_critical</span>(<span class="hljs-params">msg</span>):</span>
    logger.critical(msg)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">logger_success</span>(<span class="hljs-params">msg</span>):</span>
    logger.success(msg)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">logger_info</span>(<span class="hljs-params">msg</span>):</span>
    logger.info(msg)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">logger_trace</span>(<span class="hljs-params">msg</span>):</span>
    logger.trace(msg)
</code></pre>
<p><code>.\redis.conf</code></p>
<pre><code class="lang-bash"><span class="hljs-built_in">bind</span> 127.0.0.1 -::1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile <span class="hljs-string">""</span>
databases 16
always-show-logo no
set-proc-title yes
proc-title-template <span class="hljs-string">"{title} {listen-addr} {server-mode}"</span>
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
lazyfree-lazy-user-flush no
oom-score-adj no
oom-score-adj-values 0 200 800
disable-thp yes
appendonly no
appendfilename <span class="hljs-string">"appendonly.aof"</span>
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events <span class="hljs-string">""</span>
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
</code></pre>
<p><code>.\replit.nix</code> （若 使用的 Replit）</p>
<pre><code class="lang-bash">{ pkgs }: {
  deps = [
    pkgs.python38Full
    pkgs.redis
  ];
  env = {
    PYTHON_LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [
      <span class="hljs-comment"># Neded for pandas / numpy</span>
      pkgs.stdenv.cc.cc.lib
      pkgs.zlib
      <span class="hljs-comment"># Needed for pygame</span>
      pkgs.glib
      <span class="hljs-comment"># Needed for matplotlib</span>
      pkgs.xorg.libX11
    ];
    PYTHONBIN = <span class="hljs-string">"<span class="hljs-variable">${pkgs.python38Full}</span>/bin/python3.8"</span>;
    LANG = <span class="hljs-string">"en_US.UTF-8"</span>;
  };
}
</code></pre>
<p><code>.\.replit</code></p>
<pre><code class="lang-bash"><span class="hljs-comment"># The command that runs the program.</span>
run = [<span class="hljs-string">"python3"</span>, <span class="hljs-string">"main.py"</span>]
<span class="hljs-comment"># The primary language of the repl. There can be others, though!</span>
language = <span class="hljs-string">"python3"</span>
<span class="hljs-comment"># The main file, which will be shown by default in the editor.</span>
entrypoint = <span class="hljs-string">"main.py"</span>
<span class="hljs-comment"># A list of globs that specify which files and directories should</span>
<span class="hljs-comment"># be hidden in the workspace.</span>
hidden = [<span class="hljs-string">"venv"</span>, <span class="hljs-string">".config"</span>, <span class="hljs-string">"**/__pycache__"</span>, <span class="hljs-string">"**/.mypy_cache"</span>, <span class="hljs-string">"**/*.pyc"</span>]

<span class="hljs-comment"># Specifies which nix channel to use when building the environment.</span>
[nix]
channel = <span class="hljs-string">"stable-21_11"</span>

<span class="hljs-comment"># Per-language configuration: python3</span>
[languages.python3]
<span class="hljs-comment"># Treats all files that end with `.py` as Python.</span>
pattern = <span class="hljs-string">"**/*.py"</span>
<span class="hljs-comment"># Tells the workspace editor to syntax-highlight these files as</span>
<span class="hljs-comment"># Python.</span>
syntax = <span class="hljs-string">"python"</span>

  <span class="hljs-comment"># The command needed to start the Language Server Protocol. For</span>
  <span class="hljs-comment"># linting and formatting.</span>
  [languages.python3.languageServer]
  start = [<span class="hljs-string">"pyls"</span>]

<span class="hljs-comment"># The command to start the interpreter.</span>
[interpreter]
  [interpreter.command]
  args = [
    <span class="hljs-string">"stderred"</span>,
    <span class="hljs-string">"--"</span>,
    <span class="hljs-string">"prybar-python3"</span>,
    <span class="hljs-string">"-q"</span>,
    <span class="hljs-string">"--ps1"</span>,
    <span class="hljs-string">"\u0001\u001b[33m\u0002\u0001\u001b[00m\u0002 "</span>,
    <span class="hljs-string">"-i"</span>,
  ]
  env = { LD_LIBRARY_PATH = <span class="hljs-string">"<span class="hljs-variable">$PYTHON_LD_LIBRARY_PATH</span>"</span> }

<span class="hljs-comment"># The environment variables needed to correctly start Python and use the</span>
<span class="hljs-comment"># package proxy.</span>
[env]
VIRTUAL_ENV = <span class="hljs-string">"/home/runner/<span class="hljs-variable">${REPL_SLUG}</span>/venv"</span>
PATH = <span class="hljs-string">"<span class="hljs-variable">${VIRTUAL_ENV}</span>/bin"</span>
PYTHONPATH=<span class="hljs-string">"<span class="hljs-variable">${VIRTUAL_ENV}</span>/lib/python3.8/site-packages"</span>
REPLIT_POETRY_PYPI_REPOSITORY=<span class="hljs-string">"https://package-proxy.replit.com/pypi/"</span>
MPLBACKEND=<span class="hljs-string">"TkAgg"</span>

<span class="hljs-comment"># Enable unit tests. This is only supported for a few languages.</span>
[unitTest]
language = <span class="hljs-string">"python3"</span>

<span class="hljs-comment"># Add a debugger!</span>
[debugger]
support = <span class="hljs-literal">true</span>

  <span class="hljs-comment"># How to start the debugger.</span>
  [debugger.interactive]
  transport = <span class="hljs-string">"localhost:0"</span>
  startCommand = [<span class="hljs-string">"dap-python"</span>, <span class="hljs-string">"main.py"</span>]

    <span class="hljs-comment"># How to communicate with the debugger.</span>
    [debugger.interactive.integratedAdapter]
    dapTcpAddress = <span class="hljs-string">"localhost:0"</span>

    <span class="hljs-comment"># How to tell the debugger to start a debugging session.</span>
    [debugger.interactive.initializeMessage]
    <span class="hljs-built_in">command</span> = <span class="hljs-string">"initialize"</span>
    <span class="hljs-built_in">type</span> = <span class="hljs-string">"request"</span>

      [debugger.interactive.initializeMessage.arguments]
      adapterID = <span class="hljs-string">"debugpy"</span>
      clientID = <span class="hljs-string">"replit"</span>
      clientName = <span class="hljs-string">"replit.com"</span>
      columnsStartAt1 = <span class="hljs-literal">true</span>
      linesStartAt1 = <span class="hljs-literal">true</span>
      locale = <span class="hljs-string">"en-us"</span>
      pathFormat = <span class="hljs-string">"path"</span>
      supportsInvalidatedEvent = <span class="hljs-literal">true</span>
      supportsProgressReporting = <span class="hljs-literal">true</span>
      supportsRunInTerminalRequest = <span class="hljs-literal">true</span>
      supportsVariablePaging = <span class="hljs-literal">true</span>
      supportsVariableType = <span class="hljs-literal">true</span>

    <span class="hljs-comment"># How to tell the debugger to start the debuggee application.</span>
    [debugger.interactive.launchMessage]
    <span class="hljs-built_in">command</span> = <span class="hljs-string">"attach"</span>
    <span class="hljs-built_in">type</span> = <span class="hljs-string">"request"</span>

      [debugger.interactive.launchMessage.arguments]
      logging = {}

<span class="hljs-comment"># Configures the packager.</span>
[packager]
<span class="hljs-comment"># Search packages in PyPI.</span>
language = <span class="hljs-string">"python3"</span>
<span class="hljs-comment"># Never attempt to install `unit_tests`. If there are packages that are being</span>
<span class="hljs-comment"># guessed wrongly, add them here.</span>
ignoredPackages = [<span class="hljs-string">"unit_tests"</span>]

  [packager.features]
  enabledForHosting = <span class="hljs-literal">false</span>
  <span class="hljs-comment"># Enable searching packages from the sidebar.</span>
  packageSearch = <span class="hljs-literal">true</span>
  <span class="hljs-comment"># Enable guessing what packages are needed from the code.</span>
  guessImports = <span class="hljs-literal">true</span>
</code></pre>
<p>OK，跑起来之后，就实现了自动刷新缓存 token 推送微信的功能</p>
<h3 id="heading-try-post">Try Post 发送请求至部署的地址</h3>
<pre><code class="lang-json">POST Method
Body X-WWW-form-urlencoded 表单
<span class="hljs-string">"type"</span>: <span class="hljs-string">"Note"</span>,
<span class="hljs-string">"title"</span>: <span class="hljs-string">"Test title"</span>,
<span class="hljs-string">"body"</span>: <span class="hljs-string">"Test body"</span>,
<span class="hljs-string">"wecom_touid"</span>: <span class="hljs-string">"@all"</span>
</code></pre>
<p>应该可以收到消息了，那么这么一个推送端我们就搭好了</p>
<p>只需要对接 <code>Uptime</code> 就 OK 了，我选择的是改造 <code>pushbullet.js</code> 这个推送源（里面的推送网址改成你的）</p>
<p><code>.\server\notification-providers\pushbullet.js</code></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> NotificationProvider = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./notification-provider"</span>);
<span class="hljs-keyword">const</span> axios = <span class="hljs-built_in">require</span>(<span class="hljs-string">"axios"</span>);
<span class="hljs-keyword">var</span> qs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'qs'</span>);

<span class="hljs-keyword">const</span> { DOWN, UP } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../../src/util"</span>);

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Pushbullet</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">NotificationProvider</span> </span>{

    name = <span class="hljs-string">"pushbullet"</span>;

    <span class="hljs-keyword">async</span> send(notification, msg, monitorJSON = <span class="hljs-literal">null</span>, heartbeatJSON = <span class="hljs-literal">null</span>) {
        <span class="hljs-keyword">let</span> okMsg = <span class="hljs-string">"Sent Successfully."</span>;
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">let</span> pushbulletUrl = <span class="hljs-string">"https://xxxxx.xxxxxxxxxxxxxx.xxxx.xx"</span>;
            <span class="hljs-keyword">let</span> config = {
                <span class="hljs-attr">headers</span>: {
                    <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>
                }
            };
            <span class="hljs-keyword">if</span> (heartbeatJSON == <span class="hljs-literal">null</span>) {
                <span class="hljs-keyword">let</span> testdata = {
                    <span class="hljs-string">"type"</span>: <span class="hljs-string">"note"</span>,
                    <span class="hljs-string">"title"</span>: <span class="hljs-string">"Uptime Kuma Alert"</span>,
                    <span class="hljs-string">"body"</span>: <span class="hljs-string">"Testing Successful."</span>,
                    <span class="hljs-string">"wecom_touid"</span>: notification.pushbulletAccessToken
                }
                <span class="hljs-comment">// 提交 构造from表单</span>
                <span class="hljs-keyword">var</span> access_token_data = qs.stringify(testdata);
                <span class="hljs-keyword">var</span> _config = {
                  <span class="hljs-attr">method</span>: <span class="hljs-string">'post'</span>,
                  <span class="hljs-attr">url</span>: pushbulletUrl,
                  <span class="hljs-attr">headers</span>: { 
                    <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/x-www-form-urlencoded'</span>
                  },
                  <span class="hljs-attr">data</span> : access_token_data
                };
                <span class="hljs-keyword">await</span> axios(_config)
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (heartbeatJSON[<span class="hljs-string">"status"</span>] == DOWN) {
                <span class="hljs-keyword">let</span> downdata = {
                    <span class="hljs-string">"type"</span>: <span class="hljs-string">"note"</span>,
                    <span class="hljs-string">"title"</span>: <span class="hljs-string">"UptimeKuma Alert: "</span> + monitorJSON[<span class="hljs-string">"name"</span>],
                    <span class="hljs-string">"body"</span>: <span class="hljs-string">"[🔴 Down] "</span> + heartbeatJSON[<span class="hljs-string">"msg"</span>] + <span class="hljs-string">"\nTime (UTC): "</span> + heartbeatJSON[<span class="hljs-string">"time"</span>],
                    <span class="hljs-string">"wecom_touid"</span>: notification.pushbulletAccessToken
                }
                <span class="hljs-comment">// 提交 构造from表单</span>
                <span class="hljs-keyword">var</span> access_token_data = qs.stringify(downdata);
                <span class="hljs-keyword">var</span> _config = {
                  <span class="hljs-attr">method</span>: <span class="hljs-string">'post'</span>,
                  <span class="hljs-attr">url</span>: pushbulletUrl,
                  <span class="hljs-attr">headers</span>: { 
                    <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/x-www-form-urlencoded'</span>
                  },
                  <span class="hljs-attr">data</span> : access_token_data
                };
                <span class="hljs-keyword">await</span> axios(_config)
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (heartbeatJSON[<span class="hljs-string">"status"</span>] == UP) {
                <span class="hljs-keyword">let</span> updata = {
                    <span class="hljs-string">"type"</span>: <span class="hljs-string">"note"</span>,
                    <span class="hljs-string">"title"</span>: <span class="hljs-string">"UptimeKuma Alert: "</span> + monitorJSON[<span class="hljs-string">"name"</span>],
                    <span class="hljs-string">"body"</span>: <span class="hljs-string">"[✅ Up] "</span> + heartbeatJSON[<span class="hljs-string">"msg"</span>] + <span class="hljs-string">"\nTime (UTC): "</span> + heartbeatJSON[<span class="hljs-string">"time"</span>],
                    <span class="hljs-string">"wecom_touid"</span>: notification.pushbulletAccessToken
                }
                <span class="hljs-comment">// 提交 构造from表单</span>
                <span class="hljs-keyword">var</span> access_token_data = qs.stringify(updata);
                <span class="hljs-keyword">var</span> _config = {
                  <span class="hljs-attr">method</span>: <span class="hljs-string">'post'</span>,
                  <span class="hljs-attr">url</span>: pushbulletUrl,
                  <span class="hljs-attr">headers</span>: { 
                    <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/x-www-form-urlencoded'</span>
                  },
                  <span class="hljs-attr">data</span> : access_token_data
                };
                <span class="hljs-keyword">await</span> axios(_config)
            }
            <span class="hljs-keyword">return</span> okMsg;
        } <span class="hljs-keyword">catch</span> (error) {
            <span class="hljs-built_in">this</span>.throwGeneralAxiosError(error)
        }
    }
}

<span class="hljs-built_in">module</span>.exports = Pushbullet;
</code></pre>
<p>因为我技术菜，所以这里多引入了一个库 <code>qs</code> ，需要引入一下</p>
<p><code>package.json</code></p>
<pre><code class="lang-json"><span class="hljs-string">"dependencies"</span>: {
+        <span class="hljs-attr">"qs"</span>: <span class="hljs-string">"6.10.3"</span>,
},
</code></pre>
<p>ok，这样部署好了，但是我们还缺少一个参数 </p>
<ul>
<li><code>wecom_touid</code> ：到底要发给谁呢？</li>
<li>你可以选这两种方式 ： <code>@all</code> 推送给所有关注服务的人，也可以填用户 <code>ID</code></li>
</ul>
<h3 id="heading-id">用户ID在这里看</h3>
<ul>
<li><a target="_blank" href="https://sct.ftqq.com/forward">Server酱·Turbo版 (ftqq.com)</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446897927/9F6NPvezx.png" alt="5" /></p>
<p>里面的 </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446899195/sxLaHo_hq.png" alt="6" /></p>
<p>这个就是 用户 ID ，成功将监控项目跑起来之后</p>
<p>添加通知项，选择 <code>pushbullet</code> 里面的 <code>Access Token</code> 填</p>
<ul>
<li><p>要通知的 <code>用户 ID</code> </p>
</li>
<li><p>或 <code>@all</code></p>
</li>
</ul>
<p>点击测试，能收到消息即搭建成功</p>
<hr />
<h3 id="heading-6ag65l65oq5lia5zi0">顺便提一嘴</h3>
<h5 id="heading-pushdeer">方糖的 <code>PushDeer</code> 也对接成功了</h5>
<p>还是那个文件</p>
<p><code>.\server\notification-providers\pushbullet.js</code></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> NotificationProvider = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./notification-provider"</span>);
<span class="hljs-keyword">const</span> axios = <span class="hljs-built_in">require</span>(<span class="hljs-string">"axios"</span>);
<span class="hljs-keyword">var</span> qs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'qs'</span>);

<span class="hljs-keyword">const</span> { DOWN, UP } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../../src/util"</span>);

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Pushbullet</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">NotificationProvider</span> </span>{

    name = <span class="hljs-string">"pushbullet"</span>;

    <span class="hljs-keyword">async</span> send(notification, msg, monitorJSON = <span class="hljs-literal">null</span>, heartbeatJSON = <span class="hljs-literal">null</span>) {
        <span class="hljs-keyword">let</span> okMsg = <span class="hljs-string">"Sent Successfully."</span>;

        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">let</span> pushbulletUrl = <span class="hljs-string">"https://sc.ftqq.com/"</span> + notification.pushbulletAccessToken + <span class="hljs-string">".send"</span>;
            <span class="hljs-keyword">let</span> config = {
                <span class="hljs-attr">headers</span>: {
                    <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>
                }
            };
            <span class="hljs-keyword">if</span> (heartbeatJSON == <span class="hljs-literal">null</span>) {
                <span class="hljs-keyword">let</span> testdata = {
                    <span class="hljs-string">"title"</span>: <span class="hljs-string">"Uptime Kuma Alert"</span>,
                    <span class="hljs-string">"desp"</span>: <span class="hljs-string">"Testing Successful."</span>
                }
                <span class="hljs-comment">// 提交 构造from表单</span>
                <span class="hljs-keyword">var</span> access_token_data = qs.stringify(testdata);
                <span class="hljs-keyword">var</span> _config = {
                  <span class="hljs-attr">method</span>: <span class="hljs-string">'post'</span>,
                  <span class="hljs-attr">url</span>: pushbulletUrl,
                  <span class="hljs-attr">headers</span>: { 
                    <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/x-www-form-urlencoded'</span>
                  },
                  <span class="hljs-attr">data</span> : access_token_data
                };
                <span class="hljs-keyword">await</span> axios(_config)
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (heartbeatJSON[<span class="hljs-string">"status"</span>] == DOWN) {
                <span class="hljs-keyword">let</span> downdata = {
                    <span class="hljs-string">"title"</span>: <span class="hljs-string">"UptimeKuma Alert: "</span> + monitorJSON[<span class="hljs-string">"name"</span>],
                    <span class="hljs-string">"desp"</span>: <span class="hljs-string">"[🔴 Down] "</span> + heartbeatJSON[<span class="hljs-string">"msg"</span>] + <span class="hljs-string">"\nTime (UTC): "</span> + heartbeatJSON[<span class="hljs-string">"time"</span>],
                }
                <span class="hljs-comment">// 提交 构造from表单</span>
                <span class="hljs-keyword">var</span> access_token_data = qs.stringify(downdata);
                <span class="hljs-keyword">var</span> _config = {
                  <span class="hljs-attr">method</span>: <span class="hljs-string">'post'</span>,
                  <span class="hljs-attr">url</span>: pushbulletUrl,
                  <span class="hljs-attr">headers</span>: { 
                    <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/x-www-form-urlencoded'</span>
                  },
                  <span class="hljs-attr">data</span> : access_token_data
                };
                <span class="hljs-keyword">await</span> axios(_config)
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (heartbeatJSON[<span class="hljs-string">"status"</span>] == UP) {
                <span class="hljs-keyword">let</span> updata = {
                    <span class="hljs-string">"title"</span>: <span class="hljs-string">"UptimeKuma Alert: "</span> + monitorJSON[<span class="hljs-string">"name"</span>],
                    <span class="hljs-string">"desp"</span>: <span class="hljs-string">"[✅ Up] "</span> + heartbeatJSON[<span class="hljs-string">"msg"</span>] + <span class="hljs-string">"\nTime (UTC): "</span> + heartbeatJSON[<span class="hljs-string">"time"</span>],
                }
                <span class="hljs-comment">// 提交 构造from表单</span>
                <span class="hljs-keyword">var</span> access_token_data = qs.stringify(updata);
                <span class="hljs-keyword">var</span> _config = {
                  <span class="hljs-attr">method</span>: <span class="hljs-string">'post'</span>,
                  <span class="hljs-attr">url</span>: pushbulletUrl,
                  <span class="hljs-attr">headers</span>: { 
                    <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/x-www-form-urlencoded'</span>
                  },
                  <span class="hljs-attr">data</span> : access_token_data
                };
                <span class="hljs-keyword">await</span> axios(_config)
            }
            <span class="hljs-keyword">return</span> okMsg;
        } <span class="hljs-keyword">catch</span> (error) {
            <span class="hljs-built_in">this</span>.throwGeneralAxiosError(error)
        }
    }
}

<span class="hljs-built_in">module</span>.exports = Pushbullet;
</code></pre>
<p>这个针对方糖的订阅用户（（</p>
<p>还是那个 <code>pushbullet</code> 通道，<code>Access Token</code> 填成你的就行</p>
<p>类似于</p>
<ul>
<li><code>SCT888888XXXXXXXXXXXXXXXXXXXXXXX</code></li>
</ul>
<p>这种的，填上测试一下，如果收到消息即对接成功（老规矩要先加上那个 <code>qs</code> 的库）</p>
<hr />
<p>有问题评论区联系（</p>
]]></content:encoded></item><item><title><![CDATA[Vercel | Python 云函数文档摘抄]]></title><description><![CDATA[Python
The Python Runtime is used by Vercel to compile Python Serverless Functions, that defines a singular HTTP handler variable, inheritting from the BaseHTTPRequestHandler class, from a .py file within an /api directory at your project's root.
Pyt...]]></description><link>https://hn.icodeq.com/vercel-or-python-yun-han-shu-wen-dang-zhai-chao</link><guid isPermaLink="true">https://hn.icodeq.com/vercel-or-python-yun-han-shu-wen-dang-zhai-chao</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Wed, 20 Apr 2022 10:45:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446762040/LCtsOWlNX.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-pythonhttpsvercelcomdocsruntimesofficial-runtimespython"><a target="_blank" href="https://vercel.com/docs/runtimes#official-runtimes/python">Python</a></h2>
<p><em>The Python Runtime is used by Vercel to compile Python Serverless Functions, that defines a singular HTTP <code>handler</code> variable, inheritting from the <code>BaseHTTPRequestHandler</code> class, from a <code>.py</code> file within an <code>/api</code> directory at your project's root.</em></p>
<p>Python 平台被用作 vercel 的 Python 云函数编译器，它定义了一个单一的 HTTP <code>handler</code> 变量，继承自 <code>BaseHTTPRequestHandler</code> 类，并且来自于  <code>/api</code> 目录下以 <code>.py</code> 结尾的文件 </p>
<p><em>For example, define an <code>index.py</code> file inside a <code>/api</code> directory as follows:</em></p>
<p>示例：这是一个 <code>/api</code> 目录下以 <code>.py</code> 结尾的文件 </p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> http.server <span class="hljs-keyword">import</span> BaseHTTPRequestHandler
<span class="hljs-keyword">from</span> cowpy <span class="hljs-keyword">import</span> cow

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">handler</span>(<span class="hljs-params">BaseHTTPRequestHandler</span>):</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">do_GET</span>(<span class="hljs-params">self</span>):</span>
        self.send_response(<span class="hljs-number">200</span>)
        self.send_header(<span class="hljs-string">'Content-type'</span>,<span class="hljs-string">'text/plain'</span>)
        self.end_headers()
        message = cow.Cowacter().milk(<span class="hljs-string">'Hello from Python from a Serverless Function!'</span>)
        self.wfile.write(message.encode())
        <span class="hljs-keyword">return</span>
</code></pre>
<p><em>An example <code>index.py</code> file inside an <code>/api</code> directory.</em></p>
<p><em>Inside <code>requirements.txt</code> define:</em></p>
<p>在 <code>requirements.txt</code> 中这样定义</p>
<pre><code><span class="hljs-attribute">cowpy</span>==<span class="hljs-number">1</span>.<span class="hljs-number">0</span>.<span class="hljs-number">3</span>
</code></pre><p><em>An example <code>requirements.txt</code> file that defines <code>cowpy</code> as a dependency.</em></p>
<p><code>requirements.txt</code> 定义了需要 <code>cowpy</code> 这个依赖项</p>
<p><em>For advanced usage, such as using WSGI or ASGI for your Python projects, see the <a target="_blank" href="https://vercel.com/docs/runtimes#advanced-usage/advanced-python-usage">Advanced Python Usage section</a>.</em></p>
<p>有关高级用法，例如在 Python 项目中使用 WSGI 或 ASGI，请参阅 <a target="_blank" href="https://vercel.com/docs/runtimes#advanced-usage/advanced-python-usage">高级 Python 用法部分</a>。（本文的后半部分）</p>
<h3 id="heading-python-versionhttpsvercelcomdocsruntimesofficial-runtimespythonpython-version"><a target="_blank" href="https://vercel.com/docs/runtimes#official-runtimes/python/python-version">Python Version</a></h3>
<p><em>Python projects deployed with Vercel use Python version 3.9.</em></p>
<p>使用 Vercel 部署的 Python 项目使用 Python 3.9 版。</p>
<p><em>You can specify the version of Python by defining <code>python_version</code> in <code>Pipfile</code>, like so:</em></p>
<p>您可以通过在 <code>Pipfile</code> 中定义 <code>python_version</code> 来指定 Python 的版本，如下所示：</p>
<pre><code><span class="hljs-section">[[source]]</span>
<span class="hljs-attr">url</span> = <span class="hljs-string">"https://pypi.org/simple"</span>
<span class="hljs-attr">verify_ssl</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">name</span> = <span class="hljs-string">"pypi"</span>

<span class="hljs-section">[packages]</span>
<span class="hljs-attr">flask</span> = <span class="hljs-string">"*"</span>

<span class="hljs-section">[requires]</span>
<span class="hljs-attr">python_version</span> = <span class="hljs-string">"3.9"</span>
</code></pre><p><em>An example <code>Pipfile</code> generated with<code>pipenv install flask</code>.</em></p>
<p><em>Currently, the following Python versions are available:</em></p>
<p>目前，有如下版本可用</p>
<ul>
<li>3.9 (<a target="_blank" href="https://vercel.com/changelog/python-3-9-is-now-available">default since November 23rd 2021</a>)</li>
<li>3.6 (being deprecated)</li>
</ul>
<p><strong>Note:</strong> <em>The <code>python_version</code> must exactly match one of the options above or it will be ignored.</em></p>
<p>注意：<code>python_version</code> 必须与上述选项之一 完全匹配 ，否则将被忽略。</p>
<h3 id="heading-python-dependencieshttpsvercelcomdocsruntimesofficial-runtimespythonpython-dependencies"><a target="_blank" href="https://vercel.com/docs/runtimes#official-runtimes/python/python-dependencies">Python Dependencies</a></h3>
<blockquote>
<p>Python 的依赖项</p>
</blockquote>
<p><em>You can install dependencies for your Python projects by defining them in <code>requirements.txt</code> or a <code>Pipfile</code> with corresponding <code>Pipfile.lock</code>.</em></p>
<p>您可以通过在 <code>requirements.txt</code> 或具有相应 <code>Pipfile.lock</code> 的 <code>Pipfile</code> 中定义 Python 项目的依赖项来安装依赖项。</p>
<hr />
<hr />
<hr />
<h2 id="heading-advanced-python-usagehttpsvercelcomdocsruntimesadvanced-usageadvanced-python-usage"><a target="_blank" href="https://vercel.com/docs/runtimes#advanced-usage/advanced-python-usage">Advanced Python Usage</a></h2>
<blockquote>
<p>高级 Python 用法</p>
</blockquote>
<p><em>In order to use this Runtime, no configuration is needed. You only need to create a file inside the <code>api</code> directory.</em></p>
<p>要使用这个云函数，您不需要过多配置。只需要创建在 <code>api</code> 目录下创建一个文件。</p>
<p><em>The entry point of this Runtime is a glob matching <code>.py</code> source files with one of the following variables defined:</em></p>
<p>这个运行的入口函数要以 <code>.py</code> 结尾，并且具备以下两种特征中的一种。</p>
<ul>
<li><p><em><code>handler</code> that inherits from the <code>BaseHTTPRequestHandler</code> class.</em></p>
<p>有 <code>handler</code> class 属性并且继承于 <code>BaseHTTPRequestHandler</code></p>
</li>
<li><p><em><code>app</code> that exposes a WSGI or ASGI Application.</em></p>
<p>WSGI 或者 ASGI 应用并且有 <code>app</code> 的入口。</p>
</li>
</ul>
<h3 id="heading-reading-relative-files-in-pythonhttpsvercelcomdocsruntimesadvanced-usageadvanced-python-usagereading-relative-files-in-python"><a target="_blank" href="https://vercel.com/docs/runtimes#advanced-usage/advanced-python-usage/reading-relative-files-in-python">Reading Relative Files in Python</a></h3>
<blockquote>
<p>在 Python 中读取相关文件</p>
</blockquote>
<p><em>Python uses the current working directory when a relative file is passed to <a target="_blank" href="https://docs.python.org/3/library/functions.html#open">open()</a>.</em></p>
<p>当一个文件被由  <code>open()</code> 打开时。</p>
<p><em>The current working directory is the base of your project, not the <code>api/</code> directory.</em></p>
<p>工作目录是以根目录为基础的，而不是 <code>api/</code></p>
<p><em>For example, the following directory structure:</em></p>
<p>例如，若有如下目录结构</p>
<pre><code>├── README.md
├── api
<span class="hljs-operator">|</span>  ├── user.py
├── data
<span class="hljs-operator">|</span>  └── file.txt
└── requirements.txt
</code></pre><p><em>With the above directory structure, your function in <code>api/user.py</code> can read the contents of <code>data/file.txt</code> in a couple different ways.</em></p>
<p>有了上面的结构， <code>api/user.py</code> 中的函数可以通过几种不同的方式读取 <code>data/file.txt</code> 的内容。</p>
<p><em>You can use the path relative to the project's base directory.</em></p>
<p>您可以使用 绝对路径 </p>
<pre><code class="lang-python"><span class="hljs-comment"># api/user.py</span>
<span class="hljs-keyword">from</span> http.server <span class="hljs-keyword">import</span> BaseHTTPRequestHandler
<span class="hljs-keyword">from</span> os.path <span class="hljs-keyword">import</span> join

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">handler</span>(<span class="hljs-params">BaseHTTPRequestHandler</span>):</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">do_GET</span>(<span class="hljs-params">self</span>):</span>
        self.send_response(<span class="hljs-number">200</span>)
        self.send_header(<span class="hljs-string">'Content-type'</span>,<span class="hljs-string">'text/plain'</span>)
        self.end_headers()
        <span class="hljs-keyword">with</span> open(join(<span class="hljs-string">'data'</span>, <span class="hljs-string">'file.txt'</span>), <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> file:
          <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> file:
            self.wfile.write(line.encode())
        <span class="hljs-keyword">return</span>
</code></pre>
<p><em>Or you can use the path relative to the current file's directory.</em></p>
<p>或者使用相对路径</p>
<pre><code class="lang-python"><span class="hljs-comment"># api/user.py</span>
<span class="hljs-keyword">from</span> http.server <span class="hljs-keyword">import</span> BaseHTTPRequestHandler
<span class="hljs-keyword">from</span> os.path <span class="hljs-keyword">import</span> dirname, abspath, join
dir = dirname(abspath(__file__))

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">handler</span>(<span class="hljs-params">BaseHTTPRequestHandler</span>):</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">do_GET</span>(<span class="hljs-params">self</span>):</span>
        self.send_response(<span class="hljs-number">200</span>)
        self.send_header(<span class="hljs-string">'Content-type'</span>,<span class="hljs-string">'text/plain'</span>)
        self.end_headers()
        <span class="hljs-keyword">with</span> open(join(dir, <span class="hljs-string">'..'</span>, <span class="hljs-string">'data'</span>, <span class="hljs-string">'file.txt'</span>), <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> file:
          <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> file:
            self.wfile.write(line.encode())
        <span class="hljs-keyword">return</span>
</code></pre>
<h3 id="heading-web-server-gateway-interfacehttpsvercelcomdocsruntimesadvanced-usageadvanced-python-usageweb-server-gateway-interface"><a target="_blank" href="https://vercel.com/docs/runtimes#advanced-usage/advanced-python-usage/web-server-gateway-interface">Web Server Gateway Interface</a></h3>
<blockquote>
<p>Web服务器网关接口</p>
</blockquote>
<p><em>The Web Server Gateway Interface (WSGI) is a calling convention for web servers to forward requests to web applications written in Python. You can use WSGI with frameworks such as Flask or Django.</em></p>
<p>Web 服务器网关接口 (WSGI) 是 Web 服务器将请求转发到用 Python 编写的 Web 应用程序的调用约定。 您可以将 WSGI 与 Flask 或 Django 等框架一起使用。</p>
<p><em>Instead of defining a <code>handler</code>, define an <code>app</code> variable in your Python file, when using <code>vercel.json</code> config. For example, define a <code>index.py</code> file inside your project as follows:</em></p>
<p>使用 <code>vercel.json</code> 配置时，不要定义 <code>handler</code>，而是在 Python 文件中定义 <code>app</code> 变量。 例如，在您的项目中定义一个 <code>index.py</code> 文件，如下所示：</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask, Response
app = Flask(__name__)

<span class="hljs-meta">@app.route('/', defaults={'path': ''})</span>
<span class="hljs-meta">@app.route('/&lt;path:path&gt;')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">catch_all</span>(<span class="hljs-params">path</span>):</span>
    <span class="hljs-keyword">return</span> Response(<span class="hljs-string">"&lt;h1&gt;Flask&lt;/h1&gt;&lt;p&gt;You visited: /%s&lt;/p&gt;"</span> % (path), mimetype=<span class="hljs-string">"text/html"</span>)
</code></pre>
<p><em>An example <code>index.py</code> file, using Flask for a WSGI application.</em></p>
<p>一个示例 <code>index.py</code> 文件，将 Flask 用于 WSGI 应用程序。</p>
<p><em>Inside <code>requirements.txt</code> define:</em></p>
<p>在 <code>requirements.txt</code> 中定义：</p>
<pre><code><span class="hljs-attribute">flask</span>==<span class="hljs-number">1</span>.<span class="hljs-number">0</span>.<span class="hljs-number">2</span>
</code></pre><p><em>An example <code>requirements.txt</code> file, listing <code>flask</code> as a dependency.</em></p>
<p>一个示例 <code>requirements.txt</code> 文件，将 <code>flask</code> 列为依赖项。</p>
<h3 id="heading-asynchronous-server-gateway-interfacehttpsvercelcomdocsruntimesadvanced-usageadvanced-python-usageasynchronous-server-gateway-interface"><a target="_blank" href="https://vercel.com/docs/runtimes#advanced-usage/advanced-python-usage/asynchronous-server-gateway-interface">Asynchronous Server Gateway Interface</a></h3>
<blockquote>
<p>异步服务器网关接口</p>
</blockquote>
<p><em>The Asynchronous Server Gateway Interface (ASGI) is a calling convention for web servers to forward requests to asynchronous web applications written in Python. You can use ASGI with frameworks such as <a target="_blank" href="https://sanic.readthedocs.io/">Sanic</a>.</em></p>
<p>异步服务器网关接口 (ASGI) 是 Web 服务器将请求转发到用 Python 编写的异步 Web 应用程序的调用约定。 您可以将 ASGI 与 <a target="_blank" href="https://sanic.readthedocs.io/">Sanic</a> 等框架一起使用。</p>
<p><em>Instead of defining a <code>handler</code>, define an <code>app</code> variable in your Python file.</em></p>
<p>不要定义一个 <code>handler</code>，而是在你的 Python 文件中定义一个 <code>app</code> 变量。</p>
<p><em>For example, define a <code>index.py</code> file inside a folder as follows:</em></p>
<p>例如，在文件夹中定义一个 <code>index.py</code> 文件，如下所示：</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> sanic <span class="hljs-keyword">import</span> Sanic
<span class="hljs-keyword">from</span> sanic.response <span class="hljs-keyword">import</span> json
app = Sanic()


<span class="hljs-meta">@app.route('/')</span>
<span class="hljs-meta">@app.route('/&lt;path:path&gt;')</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">index</span>(<span class="hljs-params">request, path=<span class="hljs-string">""</span></span>):</span>
    <span class="hljs-keyword">return</span> json({<span class="hljs-string">'hello'</span>: path})
</code></pre>
<p><em>An example <code>index.py</code> file, using Sanic for a ASGI application.</em></p>
<p>一个示例 <code>index.py</code> 文件，将 Sanic 用于 ASGI 应用程序。</p>
<p><em>Inside <code>requirements.txt</code> define:</em></p>
<p>在 <code>requirements.txt</code> 中定义：</p>
<pre><code><span class="hljs-attribute">sanic</span>==<span class="hljs-number">19</span>.<span class="hljs-number">6</span>.<span class="hljs-number">0</span>
</code></pre><p><em>An example <code>requirements.txt</code> file, listing <code>sanic</code> as a dependency.</em></p>
<p>一个示例 <code>requirements.txt</code> 文件，将 <code>sanic</code> 列为依赖项。</p>
]]></content:encoded></item><item><title><![CDATA[MySQL | 数据库的索引机制]]></title><description><![CDATA[数据排序的好处

一旦数据排序之后，查找的速度就会翻倍，现实世界跟程序世界都是如此

如何创建索引

CREATE TABLE t_message(
    id INT UNSIGNED PRIMARY KEY,
    content VARCHAR(200) NOT NULL,
    type ENUM("公告", "通报", "个人通知") NOT NULL,
    create_time TIMESTAMP NOT NULL,
    INDEX idx_type (type)
)...]]></description><link>https://hn.icodeq.com/mysql-or-shu-ju-ku-de-suo-yin-ji-zhi</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-shu-ju-ku-de-suo-yin-ji-zhi</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Wed, 20 Apr 2022 01:00:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445795747/u_t3-EH_Y.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-5pww5o2u5o6s5bqp55qe5aw95ase">数据排序的好处</h3>
<ul>
<li>一旦数据排序之后，查找的速度就会翻倍，现实世界跟程序世界都是如此</li>
</ul>
<h4 id="heading-5aac5l2v5yib5bu657si5byv">如何创建索引</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445792174/l24L96txF.jpeg" alt="20" /></p>
<pre><code class="lang-SQL"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_message(
    <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span> <span class="hljs-keyword">UNSIGNED</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    <span class="hljs-keyword">content</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">200</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    <span class="hljs-keyword">type</span> ENUM(<span class="hljs-string">"公告"</span>, <span class="hljs-string">"通报"</span>, <span class="hljs-string">"个人通知"</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    create_time <span class="hljs-built_in">TIMESTAMP</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    <span class="hljs-keyword">INDEX</span> idx_type (<span class="hljs-keyword">type</span>)
)
</code></pre>
<h4 id="heading-5aac5l2v5re75yqg5lio5yig6zmk57si5byv">如何添加与删除索引</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445793306/tLBEWfKNg.jpeg" alt="21" /></p>
<pre><code class="lang-SQL"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">INDEX</span> idx_type <span class="hljs-keyword">ON</span> t_message;
<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">INDEX</span> idx_type <span class="hljs-keyword">ON</span> t_message(<span class="hljs-keyword">type</span>);
<span class="hljs-keyword">SHOW</span> <span class="hljs-keyword">INDEX</span> <span class="hljs-keyword">FROM</span> t_message;
<span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> t_message <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">INDEX</span> idx_type(<span class="hljs-keyword">type</span>);
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445794550/v6_tDFMHd.png" alt="22" /></p>
<h4 id="heading-57si5byv55qe5l255so5y6f5yiz">索引的使用原则</h4>
<ul>
<li>数据库很大，而且经常被查询的数据表可以设置索引</li>
<li>索引只添加在经常被用作索引条件的字段上面</li>
<li>不要在大字段上创建索引</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_message(
    <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span> <span class="hljs-keyword">UNSIGNED</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    <span class="hljs-keyword">content</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">200</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    <span class="hljs-keyword">type</span> ENUM(<span class="hljs-string">"公告"</span>, <span class="hljs-string">"通报"</span>, <span class="hljs-string">"个人通知"</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    create_time <span class="hljs-built_in">TIMESTAMP</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    <span class="hljs-keyword">INDEX</span> idx_type (<span class="hljs-keyword">type</span>)
);

<span class="hljs-keyword">DROP</span> <span class="hljs-keyword">INDEX</span> idx_type <span class="hljs-keyword">ON</span> t_message;
<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">INDEX</span> idx_type <span class="hljs-keyword">ON</span> t_message(<span class="hljs-keyword">type</span>);
<span class="hljs-keyword">SHOW</span> <span class="hljs-keyword">INDEX</span> <span class="hljs-keyword">FROM</span> t_message;
<span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> t_message <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">INDEX</span> idx_type(<span class="hljs-keyword">type</span>);
</code></pre>
]]></content:encoded></item><item><title><![CDATA[MySQL | 数据库表字段约束]]></title><description><![CDATA[数据定义语言：字段约束
数据库的范式

构造数据库必须遵循一定的规则，这种规则就是范式
目前关系数据库有 6 种范式，一般情况下，只满足第三范式即可

第一范式：原子性

第一范式是数据库的基本要求，不满足这一点就不是关系数据库
数据表的每一列都是不可分割的基本数据项，同一列中不能有多个值，也不能存在重复的属性。


第二范式：唯一性

数据表中的每条记录必须是唯一的。为了实现区分，通常要为表上加一个列用来存储唯一标识，这个唯一属性列被称作主键列


第三范式：关联性

每列都与主键有直接关系，...]]></description><link>https://hn.icodeq.com/mysql-or-shu-ju-ku-biao-zi-duan-yue-shu</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-shu-ju-ku-biao-zi-duan-yue-shu</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Tue, 19 Apr 2022 23:44:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445809518/qcos9_EhJ.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-5pww5o2u5a6a5lmj6kt6kia77ya5a2x5q6157qm5p2f">数据定义语言：字段约束</h2>
<h3 id="heading-5pww5o2u5bqt55qe6iyd5byp">数据库的范式</h3>
<ul>
<li>构造数据库必须遵循一定的规则，这种规则就是范式</li>
<li>目前关系数据库有 6 种范式，一般情况下，只满足第三范式即可</li>
</ul>
<h4 id="heading-56ys5lia6iyd5byp77ya5y6f5a2q5ocn">第一范式：原子性</h4>
<ul>
<li>第一范式是数据库的基本要求，不满足这一点就不是关系数据库</li>
<li>数据表的每一列都是不可分割的基本数据项，同一列中不能有多个值，也不能存在重复的属性。</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445800926/vUZoEVGSv.jpeg" alt="14" /></p>
<h4 id="heading-56ys5lqm6iyd5byp77ya5zsv5lia5ocn">第二范式：唯一性</h4>
<ul>
<li>数据表中的每条记录必须是唯一的。为了实现区分，通常要为表上加一个列用来存储唯一标识，这个唯一属性列被称作主键列</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445802800/8tJpHrsf4.jpeg" alt="15" /></p>
<h4 id="heading-56ys5lij6iyd5byp77ya5ywz6igu5ocn">第三范式：关联性</h4>
<ul>
<li>每列都与主键有直接关系，不存在传递依赖</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445804438/y63l1ZoiA.png" alt="16" /></p>
<ul>
<li>依照第三范式，数据可以拆分保存到不同的数据表，依次保持关联</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445805691/JqfRLcX0h.png" alt="17" /></p>
<h3 id="heading-5a2x5q6157qm5p2f">字段约束</h3>
<ul>
<li>MySQL 中的字段约束共有四种：</li>
</ul>
<div class="hn-table">
<table>
<thead>
<tr>
<td>约束名称</td><td>关键字</td><td>描述</td></tr>
</thead>
<tbody>
<tr>
<td>主键约束</td><td><code>PRIMARY KEY</code></td><td>字段值唯一，且不能为 NULL</td></tr>
<tr>
<td>非空约束</td><td><code>NOT NULL</code></td><td>字段值不能为 <code>NULL</code></td></tr>
<tr>
<td>唯一约束</td><td><code>UNIQUE</code></td><td>字段值唯一，且可以为 <code>NULL</code></td></tr>
<tr>
<td>外键约束</td><td><code>FOREIGN KEY</code></td><td>保持关联数据的逻辑性</td></tr>
</tbody>
</table>
</div><ul>
<li>外键约束是唯一不推荐使用的约束</li>
</ul>
<h4 id="heading-5li76zsu57qm5p2f">主键约束</h4>
<ul>
<li>主键约束要求字段的值在全表必须唯一，而且不能为 <code>NULL</code> 值</li>
<li>建议主键一定要使用数据类型，因为数字的检索速度会非常快</li>
<li>如果主键是数字类型，还可以设置自动增长</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_teacher(
    <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span> PRIMARY <span class="hljs-keyword">KEY</span> AUTO_INCREMENT,
    ... ...
);
</code></pre>
<h4 id="heading-6z2e56m657qm5p2f">非空约束</h4>
<ul>
<li>非空约束要求字段的值不能为 <code>NULL</code> 值</li>
<li><code>NULL</code> 值为没有值，而不是  <code>""</code> 空字符串</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_teacher(
    <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span> PRIMARY <span class="hljs-keyword">KEY</span> AUTO_INCREMENT,
    <span class="hljs-keyword">name</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">200</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    married <span class="hljs-built_in">BOOLEAN</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> <span class="hljs-keyword">DEFAULT</span> <span class="hljs-literal">FALSE</span>
);
</code></pre>
<ul>
<li><code>BOOLEAN</code> 实际为<code>TINYINT</code> 数据类型</li>
</ul>
<h4 id="heading-5zsv5lia57qm5p2f">唯一约束</h4>
<ul>
<li>唯一约束要求字段值如果不为 <code>NULL</code>，那么在全表必须唯一</li>
</ul>
<pre><code class="lang-SQL"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_teacher(
    ......
    tel <span class="hljs-built_in">CHAR</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> <span class="hljs-keyword">UNIQUE</span>
);
</code></pre>
<h4 id="heading-5lul5lik5lij56en55qe57ud5lmg">以上三种的练习</h4>
<pre><code class="lang-SQL"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_teacher(
    <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span> <span class="hljs-keyword">UNSIGNED</span> PRIMARY <span class="hljs-keyword">KEY</span> AUTO_INCREMENT,
    <span class="hljs-keyword">name</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">20</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    tel <span class="hljs-built_in">CHAR</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> <span class="hljs-keyword">UNIQUE</span>,
    married <span class="hljs-built_in">BOOLEAN</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> <span class="hljs-keyword">DEFAULT</span> <span class="hljs-literal">FALSE</span>
);
</code></pre>
<h4 id="heading-5asw6zsu57qm5p2f77yi5ps5byd77yj">外键约束（放弃）</h4>
<ul>
<li>外键约束用来保证关联数据的逻辑关系</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445807194/uIM6A9Nc3.png" alt="18" /></p>
<ul>
<li>外键约束的定义是写在字表上的</li>
</ul>
<p>创建父表</p>
<pre><code class="lang-SQL"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_dept(
    deptno <span class="hljs-built_in">INT</span> <span class="hljs-keyword">UNSIGNED</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    dname <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">20</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> <span class="hljs-keyword">UNIQUE</span>,
    tel <span class="hljs-built_in">CHAR</span>(<span class="hljs-number">4</span>) <span class="hljs-keyword">UNIQUE</span>
);
</code></pre>
<p>创建子表</p>
<pre><code class="lang-SQL"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_emp(
    empno <span class="hljs-built_in">INT</span> <span class="hljs-keyword">UNSIGNED</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    ename <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">20</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    sex ENUM(<span class="hljs-string">"男"</span>, <span class="hljs-string">"女"</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>, <span class="hljs-comment"># 枚举的数据类型，挑选一个</span>
    deptno <span class="hljs-built_in">INT</span> <span class="hljs-keyword">UNSIGNED</span>,
    biredate <span class="hljs-keyword">DATA</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    <span class="hljs-keyword">FOREIGN</span> <span class="hljs-keyword">KEY</span> (deptno) <span class="hljs-keyword">REFERENCES</span> t_dept(deptno)
);
</code></pre>
<p>可执行代码</p>
<pre><code class="lang-SQL"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_dept(
    deptno <span class="hljs-built_in">INT</span> <span class="hljs-keyword">UNSIGNED</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    dname <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">20</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> <span class="hljs-keyword">UNIQUE</span>,
    tel <span class="hljs-built_in">CHAR</span>(<span class="hljs-number">4</span>) <span class="hljs-keyword">UNIQUE</span>
);

<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_emp(
    empno <span class="hljs-built_in">INT</span> <span class="hljs-keyword">UNSIGNED</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    ename <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">20</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    sex ENUM(<span class="hljs-string">"男"</span>, <span class="hljs-string">"女"</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    deptno <span class="hljs-built_in">INT</span> <span class="hljs-keyword">UNSIGNED</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    hiredate <span class="hljs-built_in">DATE</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    <span class="hljs-keyword">FOREIGN</span> <span class="hljs-keyword">KEY</span> (deptno) <span class="hljs-keyword">REFERENCES</span> t_dept(deptno)
)
</code></pre>
<h4 id="heading-5asw6zsu57qm5p2f55qe6zet546v6zeu6aky">外键约束的闭环问题</h4>
<ul>
<li>如果形成外键闭环，我们将无法删除任何一张表的记录</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445808427/pCIUASU0V.png" alt="19" /></p>
]]></content:encoded></item><item><title><![CDATA[MySQL | 修改数据表结构]]></title><description><![CDATA[数据定义语言：字段约束
添加字段

ALTER TABLE student
ADD address VARCHAR(200) NOT NULL,
ADD home_tel char(11) NOT NULL;

修改字段类型和约束

ALTER TABLE student
MODIFY home_tel VARCHAR(20) NOT NULL;

DESC student;

修改字段名称

DESC student;

ALTER TABLE student
CHANGE address h...]]></description><link>https://hn.icodeq.com/mysql-or-xiu-gai-shu-ju-biao-jie-gou</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-xiu-gai-shu-ju-biao-jie-gou</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Tue, 19 Apr 2022 23:11:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445744675/U8uLcot5x.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-5pww5o2u5a6a5lmj6kt6kia77ya5a2x5q6157qm5p2f">数据定义语言：字段约束</h2>
<h3 id="heading-5re75yqg5a2x5q61">添加字段</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445740105/OzojAu2Ma8.jpeg" alt="10" /></p>
<pre><code class="lang-SQL"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> student
<span class="hljs-keyword">ADD</span> address <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">200</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
<span class="hljs-keyword">ADD</span> home_tel <span class="hljs-built_in">char</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>;
</code></pre>
<h3 id="heading-5lu5ps55a2x5q6157g75z6l5zkm57qm5p2f">修改字段类型和约束</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445741232/kYrRvJGzwa.jpeg" alt="11" /></p>
<pre><code class="lang-SQL"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> student
<span class="hljs-keyword">MODIFY</span> home_tel <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">20</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>;

DESC student;
</code></pre>
<h3 id="heading-5lu5ps55a2x5q615zcn56ew">修改字段名称</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445742351/19BE_F7eQ.jpeg" alt="12" /></p>
<pre><code class="lang-SQL">DESC student;

<span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> student
<span class="hljs-keyword">CHANGE</span> address home_address <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">200</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>;
</code></pre>
<h3 id="heading-5yig6zmk5a2x5q61">删除字段</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445743489/ETRa-Kg8cG.jpeg" alt="13" /></p>
<pre><code class="lang-SQL">DESC student;

<span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> student
<span class="hljs-keyword">DROP</span> home_address,
<span class="hljs-keyword">DROP</span> home_tel;
</code></pre>
<h3 id="heading-5oc757ut6kt5yl">总结语句</h3>
<pre><code class="lang-SQL"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> student <span class="hljs-comment"># DDL 语句 没有操作数据类型</span>
<span class="hljs-keyword">ADD</span> address <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">200</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
<span class="hljs-keyword">ADD</span> home_tel <span class="hljs-built_in">char</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>;

<span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> student <span class="hljs-comment"># DDL 语句 没有操作数据类型</span>
<span class="hljs-keyword">MODIFY</span> home_tel <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">20</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>;

DESC student;

<span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> student <span class="hljs-comment"># DDL 语句 没有操作数据类型</span>
<span class="hljs-keyword">CHANGE</span> address home_address <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">200</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>;

<span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> student <span class="hljs-comment"># DDL 语句 没有操作数据类型</span>
<span class="hljs-keyword">DROP</span> home_address,
<span class="hljs-keyword">DROP</span> home_tel;
</code></pre>
]]></content:encoded></item><item><title><![CDATA[MySQL | 不同的数据类型]]></title><description><![CDATA[数据定义语言：数据类型
数据类型：数字




类型大小说明



TINYINT1字节 ^1小整数

SMALLINT2字节普通整数

MEDIUMINT3字节普通整数

INT4字节较大整数

BIGINT8字节大整数

FLOAT4字节单精度浮点数

DOUBLE8字节双精度浮点数

DECIMAL--------DECIMAL(10, 2)


1^ : (-2^7  --- +2^7-1)
不精确的浮点数

十进制的浮点数无法在计算机中用二进制精确表达


CREATE TABLE t...]]></description><link>https://hn.icodeq.com/mysql-or-bu-tong-de-shu-ju-lei-xing</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-bu-tong-de-shu-ju-lei-xing</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Tue, 19 Apr 2022 22:15:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445721028/Uq-ynZ2eS.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-5pww5o2u5a6a5lmj6kt6kia77ya5pww5o2u57g75z6l">数据定义语言：数据类型</h3>
<h5 id="heading-5pww5o2u57g75z6l77ya5pww5a2x">数据类型：数字</h5>
<div class="hn-table">
<table>
<thead>
<tr>
<td>类型</td><td>大小</td><td>说明</td></tr>
</thead>
<tbody>
<tr>
<td><code>TINYINT</code></td><td>1字节 ^1</td><td>小整数</td></tr>
<tr>
<td><code>SMALLINT</code></td><td>2字节</td><td>普通整数</td></tr>
<tr>
<td><code>MEDIUMINT</code></td><td>3字节</td><td>普通整数</td></tr>
<tr>
<td><code>INT</code></td><td>4字节</td><td>较大整数</td></tr>
<tr>
<td><code>BIGINT</code></td><td>8字节</td><td>大整数</td></tr>
<tr>
<td><code>FLOAT</code></td><td>4字节</td><td>单精度浮点数</td></tr>
<tr>
<td><code>DOUBLE</code></td><td>8字节</td><td>双精度浮点数</td></tr>
<tr>
<td><code>DECIMAL</code></td><td>--------</td><td><code>DECIMAL(10, 2)</code></td></tr>
</tbody>
</table>
</div><p>1^ : <code>(-2^7  --- +2^7-1)</code></p>
<h6 id="heading-5lin57k56gu55qe5rwu54k55pww">不精确的浮点数</h6>
<ul>
<li>十进制的浮点数无法在计算机中用二进制精确表达</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445719870/fqLMGxVCa.jpeg" alt="09" /></p>
<pre><code class="lang-SQL"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> temp(
    <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span> <span class="hljs-keyword">UNSIGNED</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    <span class="hljs-keyword">num</span> <span class="hljs-built_in">FLOAT</span>(<span class="hljs-number">20</span>,<span class="hljs-number">10</span>)
)
<span class="hljs-number">0.2</span> <span class="hljs-comment">----&gt; 0.2000000030</span>
</code></pre>
<pre><code class="lang-SQL"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">TABLE</span> temp
<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> temp(
    <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span> <span class="hljs-keyword">UNSIGNED</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    <span class="hljs-keyword">num</span> <span class="hljs-built_in">DECIMAL</span>(<span class="hljs-number">20</span>,<span class="hljs-number">10</span>)
)
<span class="hljs-number">0.2</span> <span class="hljs-comment">----&gt; 0.2000000000</span>
</code></pre>
<h5 id="heading-5pww5o2u57g75z6l77ya5a2x56ym5liy">数据类型：字符串</h5>
<div class="hn-table">
<table>
<thead>
<tr>
<td>类型</td><td>大小</td><td>说明</td></tr>
</thead>
<tbody>
<tr>
<td><code>CHAR</code></td><td>1 - 255 字符</td><td>固定长度字符串</td></tr>
<tr>
<td><code>VARCHAR</code></td><td>1 - 65535 字符</td><td>不固定长度字符串</td></tr>
<tr>
<td><code>TEXT</code></td><td>1 - 65535 字符</td><td>不确定长度字符串</td></tr>
<tr>
<td><code>MEDIUMTEXT</code></td><td>1 - 1 千 6 百万字符</td><td>不确定长度字符串</td></tr>
<tr>
<td><code>LONGTEXT</code></td><td>1 - 42 亿字符</td><td>不确定长度字符串</td></tr>
</tbody>
</table>
</div><h5 id="heading-5pww5o2u57g75z6l77ya5pel5pyf57g75z6l">数据类型：日期类型</h5>
<div class="hn-table">
<table>
<thead>
<tr>
<td>类型</td><td>大小</td><td>说明</td></tr>
</thead>
<tbody>
<tr>
<td><code>DATE</code></td><td>3 字节</td><td>日期</td></tr>
<tr>
<td><code>TIME</code></td><td>3 字节</td><td>时间</td></tr>
<tr>
<td><code>YEAR</code></td><td>1 字节</td><td>年份</td></tr>
<tr>
<td><code>DATETIME</code></td><td>8 字节</td><td>日期时间</td></tr>
<tr>
<td><code>TIMESTAMP</code></td><td>4 字节</td><td>时间戳</td></tr>
</tbody>
</table>
</div>]]></content:encoded></item><item><title><![CDATA[MySQL | 什么是 SQL 语言？]]></title><description><![CDATA[什么是 SQL 语言？

SQL  是用于访问和处理数据的标准的计算机语言
不能通用的叫 方言







名称功能



DML（数据操作语言）添加，删除，修改，查询

DCL（数据控制语言）用户，权限，事务

DDL（数据定义语言）逻辑库，数据库，视图，索引


SQL 语句注意事项

SQL 语句不区分大小写，但是 字符串 区分大小写。
SELECT "HelloWorld" ;
关键字    非关键词
推荐 关键字大写，这样写出来的才错落有致


SQL 语句必须以分号结尾。
SQL ...]]></description><link>https://hn.icodeq.com/mysql-or-shen-me-shi-sql-yu-yan</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-shen-me-shi-sql-yu-yan</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Tue, 19 Apr 2022 20:22:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445734536/pqJZYO4gF.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4 id="heading-sql">什么是 <code>SQL</code> 语言？</h4>
<ul>
<li><code>SQL</code>  是用于访问和处理数据的标准的计算机语言<ul>
<li>不能通用的叫 <code>方言</code></li>
</ul>
</li>
</ul>
<div class="hn-table">
<table>
<thead>
<tr>
<td>名称</td><td>功能</td></tr>
</thead>
<tbody>
<tr>
<td><code>DML</code>（数据操作语言）</td><td>添加，删除，修改，查询</td></tr>
<tr>
<td><code>DCL</code>（数据控制语言）</td><td>用户，权限，事务</td></tr>
<tr>
<td><code>DDL</code>（数据定义语言）</td><td>逻辑库，数据库，视图，索引</td></tr>
</tbody>
</table>
</div><h4 id="heading-sql">SQL 语句注意事项</h4>
<ul>
<li>SQL 语句不区分大小写，但是 字符串 区分大小写。<ul>
<li><code>SELECT "HelloWorld" ;</code></li>
<li>关键字    非关键词</li>
<li>推荐 关键字大写，这样写出来的才错落有致</li>
</ul>
</li>
<li>SQL 语句必须以分号结尾。</li>
<li>SQL 语句中的空白和换行没有限制，但是不能破坏语法。</li>
</ul>
<h4 id="heading-sql">SQL 语句的注释</h4>
<ul>
<li>SQL 语句的注释有两种，分别如下：<ol>
<li><code># 这是一段注释</code> （适合单行）</li>
<li><code>/* 这是另一端注释 */</code> （适合多行）</li>
</ol>
</li>
</ul>
<h4 id="heading-5yib5bu66yc76l6r5bqt">创建逻辑库</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445726440/UJvVIDLj8.jpeg" alt="03" /></p>
<h4 id="heading-5yib5bu65pww5o2u6kgo">创建数据表</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445727592/-iS8QMmbZ.jpeg" alt="04" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445728844/OcbteQYd-.jpeg" alt="05" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445730017/rgNXEoddu.png" alt="06" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445731303/Ud4mQKqr-.png" alt="07" /></p>
<pre><code class="lang-SQL"><span class="hljs-keyword">USE</span> <span class="hljs-keyword">test</span>;
<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> student(
    <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span> <span class="hljs-keyword">UNSIGNED</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    <span class="hljs-keyword">name</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">20</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    sex <span class="hljs-built_in">CHAR</span>(<span class="hljs-number">1</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    brithday <span class="hljs-built_in">DATE</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    tel <span class="hljs-built_in">CHAR</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    remark <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">200</span>)
) ;

<span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> student <span class="hljs-keyword">VALUES</span>(<span class="hljs-number">1</span>, <span class="hljs-string">"李强"</span>, <span class="hljs-string">"男"</span>, <span class="hljs-string">"1995-05-15"</span>, <span class="hljs-string">"13312345678"</span>, <span class="hljs-literal">NULL</span>);
</code></pre>
<h4 id="heading-5pww5o2u5bqt55qe5yw25luw5pon5l2c">数据库的其他操作</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445732680/4ziVI_0SD.jpeg" alt="08" /></p>
<pre><code class="lang-SQL"><span class="hljs-keyword">SHOW</span> <span class="hljs-keyword">TABLES</span>;
DESC student;
<span class="hljs-keyword">SHOW</span> <span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> student;
<span class="hljs-keyword">DROP</span> <span class="hljs-keyword">TABLE</span> student;
</code></pre>
]]></content:encoded></item><item><title><![CDATA[MySQL | Python Hello World]]></title><description><![CDATA[感谢 @xcsoft 大佬带小白入门.....

代码
import pymysql.cursors

# Connect to the database
connection = pymysql.connect(host='localhost',
                             user='py',
                             password='MsXMAFiaaSKRei6j',
                           ...]]></description><link>https://hn.icodeq.com/mysql-or-python-hello-world</link><guid isPermaLink="true">https://hn.icodeq.com/mysql-or-python-hello-world</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Tue, 19 Apr 2022 00:48:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445714102/uYKzhV1SE.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>感谢 <a target="_blank" href="https://github.com/soxft">@xcsoft</a> 大佬带小白入门.....</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653445712699/1F8Kbx4JK.png" alt="1" /></p>
<h2 id="heading-5luj56cb">代码</h2>
<pre><code class="lang-Python"><span class="hljs-keyword">import</span> pymysql.cursors

<span class="hljs-comment"># Connect to the database</span>
connection = pymysql.connect(host=<span class="hljs-string">'localhost'</span>,
                             user=<span class="hljs-string">'py'</span>,
                             password=<span class="hljs-string">'MsXMAFiaaSKRei6j'</span>,
                             database=<span class="hljs-string">'py'</span>,
                             cursorclass=pymysql.cursors.DictCursor)

<span class="hljs-keyword">with</span> connection:
    <span class="hljs-comment"># Create a new cursor</span>
    <span class="hljs-comment"># 这个游标的意思，应该是跟鼠标差不多？</span>
    <span class="hljs-keyword">with</span> connection.cursor() <span class="hljs-keyword">as</span> cursor:
        sql_create = <span class="hljs-string">"""
                    CREATE TABLE `users` (
                    `id` int(11) NOT NULL AUTO_INCREMENT,
                    `email` varchar(255) COLLATE utf8_bin NOT NULL,
                    `password` varchar(255) COLLATE utf8_bin NOT NULL,
                    PRIMARY KEY (`id`)
                    ) 
                    ENGINE=InnoDB 
                    DEFAULT 
                    CHARSET=utf8mb4 
                    COLLATE=utf8mb4_bin
                    AUTO_INCREMENT=1 ;
                    """</span>
        <span class="hljs-comment"># 首先建表</span>
        cursor.execute(sql_create)
        <span class="hljs-comment"># 只需要建表一次哦</span>
        <span class="hljs-comment"># Create a new record</span>
        <span class="hljs-comment"># 再执行语句</span>
        sql = <span class="hljs-string">"INSERT INTO `users` (`email`, `password`) VALUES (%s, %s)"</span>
        cursor.execute(sql, (<span class="hljs-string">'webmaster@python.org'</span>, <span class="hljs-string">'very-secret'</span>))
        <span class="hljs-comment"># 执行完毕之后就关闭这个连接</span>
    <span class="hljs-comment"># connection is not autocommit by default. So you must commit to save</span>
    <span class="hljs-comment"># your changes.</span>
    <span class="hljs-comment"># 想要保存数据，就要提交？</span>
    connection.commit()

    <span class="hljs-keyword">with</span> connection.cursor() <span class="hljs-keyword">as</span> cursor:
        <span class="hljs-comment"># Read a single record</span>
        sql = <span class="hljs-string">"SELECT `id`, `password` FROM `users` WHERE `email`=%s"</span>
        cursor.execute(sql, (<span class="hljs-string">'webmaster@python.org'</span>,))
        result = cursor.fetchone()
        print(result)
</code></pre>
]]></content:encoded></item><item><title><![CDATA[归档 | 自建 不蒜子 API]]></title><description><![CDATA[自建 不蒜子 API

https://busuanzi.icodeq.com

前言：

不蒜子是一款很好用的前端计数工具，但是因为流量日渐变多，经常会出现 502 的情况
故尝试对其后端进行了仿造，达到了相同的效果，并且在首次添加域名时，会自动从 busuanzi 官网同步数据
本项目使用 Redis 做数据库，若您的网站一个月内没有访问量，数据会自动清除。
即下一次再使用本工具时将再次从 Busuanzi 官网 同步数据
本项目托管于 replit.com ，开源地址： zkeq/Busu...]]></description><link>https://hn.icodeq.com/gui-dang-or-zi-jian-bu-suan-zi-api</link><guid isPermaLink="true">https://hn.icodeq.com/gui-dang-or-zi-jian-bu-suan-zi-api</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Tue, 12 Apr 2022 19:13:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446854013/nQ11o_mVu.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446850053/hUXEnED1o.png" alt="2" /></p>
<h2 id="heading-httpsbusuanziibruceinfo-api">自建 <a target="_blank" href="https://busuanzi.ibruce.info/">不蒜子</a> API</h2>
<ul>
<li>https://busuanzi.icodeq.com</li>
</ul>
<h3 id="heading-5ymn6kia77ya">前言：</h3>
<ol>
<li><a target="_blank" href="https://busuanzi.ibruce.info/">不蒜子</a>是一款很好用的前端计数工具，但是因为流量日渐变多，经常会出现 <code>502</code> 的情况</li>
<li>故尝试对其后端进行了仿造，达到了相同的效果，并且在首次添加域名时，会自动从 busuanzi 官网同步数据</li>
<li>本项目使用 <code>Redis</code> 做数据库，若您的网站一个月内没有访问量，数据会自动清除。</li>
<li>即下一次再使用本工具时将再次从 <code>Busuanzi</code> 官网 同步数据</li>
<li>本项目托管于 replit.com ，开源地址： <a target="_blank" href="https://github.com/zkeq/Busuanzi_backend_self">zkeq/Busuanzi_backend_self</a> [ MIT License ]</li>
</ol>
<h3 id="heading-5l255so77ya">使用：</h3>
<ol>
<li>将官网的 <code>//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js</code> 文件改为</li>
<li><code>https://busuanzi.icodeq.com/busuanzi.pure.mini.js</code> （本项目暂不支持 <code>http</code> 协议的网站）</li>
<li>即可使用，首次加载网站会较慢（后台同步不蒜子的 <code>Site_uv</code> 和 <code>Site_pv</code> ）</li>
<li>之后会保持在 <code>360ms</code> 左右加载出数据 (服务器处理数据仅用时 <code>5ms</code>)</li>
</ol>
<h3 id="heading-55so5rov77ya">用法：</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">async</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://busuanzi.icodeq.com/busuanzi.pure.mini.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

本文总阅读量 <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"busuanzi_value_page_pv"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> 次

本站总访问量 <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"busuanzi_value_site_pv"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> 次

本站总访客数 <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"busuanzi_value_site_uv"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> 人
</code></pre>
<h2 id="heading-api">不蒜子自建后端 API 🗺️</h2>
<ul>
<li>https://github.com/zkeq/Busuanzi_backend_self</li>
</ul>
<h3 id="heading-5a6j6kof">安装</h3>
<h5 id="heading-5liq5lq654mi">个人版</h5>
<ul>
<li><p>点击一键部署：<a target="_blank" href="https://replit.com/github/zkeq/Busuanzi_backend_self"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446851596/TQg32kpR3.svg+xml" alt="Run on Replit" /></a></p>
<p>本项目使用 Redis 做数据库， 空转占用内存大概 200M，请按需规划。</p>
</li>
<li><p>成功导入后点击 🏃 <code>RUN</code> 按钮，即可完成安装！</p>
</li>
</ul>
<h5 id="heading-or">教育版 or 专业版</h5>
<p>【资源额度更高，但好像无法一键导入】</p>
<ol>
<li><p>创建新项目</p>
</li>
<li><p>复制本项目的文件到上一步创建的项目中</p>
</li>
<li><p>点击 🏃 <code>RUN</code> 按钮，即可完成安装！</p>
</li>
</ol>
<p>出现下图表示安装成功！~（首次会同步 busuanzi 的数据，多次尝试属于正常状态）~ :</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446852686/-pkE7NX2i.png" alt="Snipaste_2022-04-21_17-06-47" /></p>
<h3 id="heading-5l255so">使用</h3>
<ol>
<li><p>在 <code>white_list.json</code> 中添加你的域名白名单</p>
</li>
<li><p>将 <code>不蒜子</code> 官网提供的 <code>js</code> 代码里面的网址，改成你的 <strong>即可</strong></p>
</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-comment">//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js</span>

<span class="hljs-keyword">var</span> bszCaller,bszTag;!<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{<span class="hljs-keyword">var</span> c,d,e,a=!<span class="hljs-number">1</span>,b=[];ready=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">c</span>)</span>{<span class="hljs-keyword">return</span> a||<span class="hljs-string">"interactive"</span>===<span class="hljs-built_in">document</span>.readyState||<span class="hljs-string">"complete"</span>===<span class="hljs-built_in">document</span>.readyState?c.call(<span class="hljs-built_in">document</span>):b.push(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{<span class="hljs-keyword">return</span> c.call(<span class="hljs-built_in">this</span>)}),<span class="hljs-built_in">this</span>},d=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{<span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> a=<span class="hljs-number">0</span>,c=b.length;c&gt;a;a++)b[a].apply(<span class="hljs-built_in">document</span>);b=[]},e=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{a||(a=!<span class="hljs-number">0</span>,d.call(<span class="hljs-built_in">window</span>),<span class="hljs-built_in">document</span>.removeEventListener?<span class="hljs-built_in">document</span>.removeEventListener(<span class="hljs-string">"DOMContentLoaded"</span>,e,!<span class="hljs-number">1</span>):<span class="hljs-built_in">document</span>.attachEvent&amp;&amp;(<span class="hljs-built_in">document</span>.detachEvent(<span class="hljs-string">"onreadystatechange"</span>,e),<span class="hljs-built_in">window</span>==<span class="hljs-built_in">window</span>.top&amp;&amp;(<span class="hljs-built_in">clearInterval</span>(c),c=<span class="hljs-literal">null</span>)))},<span class="hljs-built_in">document</span>.addEventListener?<span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">"DOMContentLoaded"</span>,e,!<span class="hljs-number">1</span>):<span class="hljs-built_in">document</span>.attachEvent&amp;&amp;(<span class="hljs-built_in">document</span>.attachEvent(<span class="hljs-string">"onreadystatechange"</span>,<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{/loaded|complete/.test(<span class="hljs-built_in">document</span>.readyState)&amp;&amp;e()}),<span class="hljs-built_in">window</span>==<span class="hljs-built_in">window</span>.top&amp;&amp;(c=<span class="hljs-built_in">setInterval</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{<span class="hljs-keyword">try</span>{a||<span class="hljs-built_in">document</span>.documentElement.doScroll(<span class="hljs-string">"left"</span>)}<span class="hljs-keyword">catch</span>(b){<span class="hljs-keyword">return</span>}e()},<span class="hljs-number">5</span>)))}(),bszCaller={<span class="hljs-attr">fetch</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">a,b</span>)</span>{<span class="hljs-keyword">var</span> c=<span class="hljs-string">"BusuanziCallback_"</span>+<span class="hljs-built_in">Math</span>.floor(<span class="hljs-number">1099511627776</span>*<span class="hljs-built_in">Math</span>.random());<span class="hljs-built_in">window</span>[c]=<span class="hljs-built_in">this</span>.evalCall(b),a=a.replace(<span class="hljs-string">"=BusuanziCallback"</span>,<span class="hljs-string">"="</span>+c),scriptTag=<span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"SCRIPT"</span>),scriptTag.type=<span class="hljs-string">"text/javascript"</span>,scriptTag.defer=!<span class="hljs-number">0</span>,scriptTag.src=a,scriptTag.referrerPolicy=<span class="hljs-string">"no-referrer-when-downgrade"</span>,<span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">"HEAD"</span>)[<span class="hljs-number">0</span>].appendChild(scriptTag)},<span class="hljs-attr">evalCall</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">a</span>)</span>{<span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">b</span>)</span>{ready(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{<span class="hljs-keyword">try</span>{a(b),scriptTag.parentElement.removeChild(scriptTag)}<span class="hljs-keyword">catch</span>(c){bszTag.hides()}})}}},bszCaller.fetch(<span class="hljs-string">"//busuanzi.ibruce.info/busuanzi?jsonpCallback=BusuanziCallback"</span>,<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">a</span>)</span>{bszTag.texts(a),bszTag.shows()}),bszTag={<span class="hljs-attr">bszs</span>:[<span class="hljs-string">"site_pv"</span>,<span class="hljs-string">"page_pv"</span>,<span class="hljs-string">"site_uv"</span>],<span class="hljs-attr">texts</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">a</span>)</span>{<span class="hljs-built_in">this</span>.bszs.map(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">b</span>)</span>{<span class="hljs-keyword">var</span> c=<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"busuanzi_value_"</span>+b);c&amp;&amp;(c.innerHTML=a[b])})},<span class="hljs-attr">hides</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{<span class="hljs-built_in">this</span>.bszs.map(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">a</span>)</span>{<span class="hljs-keyword">var</span> b=<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"busuanzi_container_"</span>+a);b&amp;&amp;(b.style.display=<span class="hljs-string">"none"</span>)})},<span class="hljs-attr">shows</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{<span class="hljs-built_in">this</span>.bszs.map(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">a</span>)</span>{<span class="hljs-keyword">var</span> b=<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"busuanzi_container_"</span>+a);b&amp;&amp;(b.style.display=<span class="hljs-string">"inline"</span>)})}};
</code></pre>
<pre><code>把里面的这个链接
<span class="hljs-comment">//busuanzi.ibruce.info/busuanzi?jsonpCallback=BusuanziCallback</span>
改成
你的域名，例如：
<span class="hljs-attribute">https</span>:<span class="hljs-comment">//counter.busuanzi.icodeq.com/?jsonpCallback=BusuanziCallback</span>
</code></pre><ol>
<li>把你网站引入的 <code>busuanzi.pure.mini.js</code> 地址替换为上一步改好的即可 ✨</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[归档 | 记录一次视频切片并上传大厂图床的尝试]]></title><description><![CDATA[经常在各种影视站看到图床切片的视频，研究了下。
首先看效果（新人练手项目，代码很烂，重在思路）




视频仅提供示例，随便下的一个视频
本文不提供相关接口，仅做技术复现！
前期准备

需要首先安装 ffmpeg 并配置到环境变量（使用命令行输入 ffmpeg 可以正常打开的那种）
https://www.gyan.dev/ffmpeg/builds/
或
https://github.com/BtbN/FFmpeg-Builds/releases

目录结构
项目分为以下几部分

对 mp4 ...]]></description><link>https://hn.icodeq.com/gui-dang-or-ji-lu-yi-ci-shi-pin-qie-pian-bing-shang-chuan-da-chang-tu-chuang-de-chang-shi</link><guid isPermaLink="true">https://hn.icodeq.com/gui-dang-or-ji-lu-yi-ci-shi-pin-qie-pian-bing-shang-chuan-da-chang-tu-chuang-de-chang-shi</guid><dc:creator><![CDATA[zhou keqiang]]></dc:creator><pubDate>Sat, 09 Apr 2022 16:20:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446860512/_Ppai7rBW.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>经常在各种影视站看到图床切片的视频，研究了下。</p>
<p>首先看效果（新人练手项目，代码很烂，重在思路）</p>
<div>
<iframe style="position:absolute;width:100%;height:100%;left:0;top:0" src="https://player.icodeq.com/v3/?url=https://s-bj-2220-zkeq.oss.dogecdn.com/video-meituan-demo.m3u8"></iframe>
</div>

<p>视频仅提供示例，随便下的一个<a target="_blank" href="https://www.bilibili.com/video/BV1P3411J7uj">视频</a></p>
<p><strong>本文不提供相关接口，仅做技术复现！</strong></p>
<h3 id="heading-5ymn5pyf5yeg5ash">前期准备</h3>
<blockquote>
<p>需要首先安装 <code>ffmpeg</code> 并配置到环境变量（使用命令行输入 <code>ffmpeg</code> 可以正常打开的那种）
https://www.gyan.dev/ffmpeg/builds/
或
https://github.com/BtbN/FFmpeg-Builds/releases</p>
</blockquote>
<h3 id="heading-55uu5b2v57ut5p6e">目录结构</h3>
<p>项目分为以下几部分</p>
<ol>
<li>对 mp4 文件进行格式转换，转成单个 ts 文件</li>
<li>对 单个 ts 文件进行转换，转成 m3u8 文件和 ts 切片文件</li>
<li>对 ts 切片文件进行重构，使其具有 <code>PNG</code> 文件格式的文件头</li>
<li>上传图床并根据返回的结果重写之前 m3u8 文件。</li>
</ol>
<h3 id="heading-5lia44cb5pah5lu26l2s5o2i6yoo5yig">一、文件转换部分</h3>
<p><code>mp4</code> 转 单个 <code>ts</code></p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">video_to_ts</span>(<span class="hljs-params">video_path</span>):</span>
    ts_all = <span class="hljs-string">".//ts_single//ts_single.ts"</span>
    cmd_str = <span class="hljs-string">f'ffmpeg -y -i <span class="hljs-subst">{video_path}</span> -vcodec copy -acodec copy -vbsf h264_mp4toannexb <span class="hljs-subst">{ts_all}</span>'</span>
    subprocess.run(cmd_str, encoding=<span class="hljs-string">"utf-8"</span>, shell=<span class="hljs-literal">True</span>)
    print(<span class="hljs-string">f'从 <span class="hljs-subst">{video_path}</span> 转换到 <span class="hljs-subst">{cmd_str}</span> 成功！'</span>)
</code></pre>
<h3 id="heading-m3u8">二、生成 <code>m3u8</code> 文件</h3>
<p>单个 <code>ts</code> 转 <code>m3u8</code></p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">ts_to_m3u8</span>(<span class="hljs-params">ts_single, singlg_time</span>):</span>
    cmd_str = <span class="hljs-string">f'ffmpeg -i <span class="hljs-subst">{ts_single}</span> -c copy -map 0 -f segment -segment_list temp_playlist.m3u8 -segment_time <span class="hljs-subst">{singlg_time}</span> ./ts_all/%03d.ts'</span>
    subprocess.run(cmd_str, encoding=<span class="hljs-string">"utf-8"</span>, shell=<span class="hljs-literal">True</span>)
    print(<span class="hljs-string">f'从 <span class="hljs-subst">{ts_single}</span> 转换到 temp_playlist.m3u8 成功！'</span>)
</code></pre>
<h3 id="heading-ts">三、<code>ts</code> 文件格式处理部分</h3>
<p>首先重命名为 <code>PNG</code> 后缀</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">rename_ts_to_png</span>():</span>
    file_list = os.listdir(<span class="hljs-string">"./ts_all"</span>)
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> file_list:
        <span class="hljs-keyword">if</span> i.endswith(<span class="hljs-string">".ts"</span>):
            new_name = i.replace(<span class="hljs-string">".ts"</span>, <span class="hljs-string">".png"</span>)
            os.rename(<span class="hljs-string">"./ts_all/"</span> + i, <span class="hljs-string">"./ts_all/"</span> + new_name)
    print(<span class="hljs-string">"rename_ts_to_png"</span>)
</code></pre>
<p>重写覆写 <code>ts</code>文件头，使其拥有 <code>PNG</code> 文件头</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653446859266/cmio0NXfK.png" alt="11" /></p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">rewrite_ts_to_png</span>():</span>
    file_list = os.listdir(<span class="hljs-string">"./ts_all"</span>)
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> file_list:
        copyfile(<span class="hljs-string">"PNG"</span>, <span class="hljs-string">"./ts_rewrite/"</span> + i)
    print(<span class="hljs-string">"rewrite_ts_to_png"</span>)
    file_list = os.listdir(<span class="hljs-string">"./ts_rewrite"</span>)
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> file_list:
        <span class="hljs-keyword">if</span> i.endswith(<span class="hljs-string">".png"</span>):
            bin_file = open(<span class="hljs-string">"./ts_all/"</span> + i, <span class="hljs-string">'rb'</span>)  <span class="hljs-comment"># 打开二进制文件</span>
            <span class="hljs-comment"># 合并文件</span>
            <span class="hljs-keyword">with</span> open(<span class="hljs-string">"./ts_rewrite/"</span> + i, <span class="hljs-string">'ab'</span>) <span class="hljs-keyword">as</span> f:
                f.write(bin_file.read())
            bin_file.close()
    <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>
</code></pre>
<p>PNG 文件头 16 进制数据如下（放在项目目录命名为 <code>PNG</code> ）</p>
<pre><code>89504E470D0A1A0A0000000D4948445200000320000003200803000000ECAEF65A0000001974455874536F6674776172650041646F626520496D616765526561647971C9653C00000006504C5445000000000000A567B9CF0000000174524E530040E6D866000002864944415478DAECC1010D000000C2A0F74F6D0E37A0
</code></pre><h3 id="heading-m3u8">四、文件上传以及重写 <code>M3U8</code> 文件</h3>
<p>文件上传</p>
<pre><code class="lang-python"><span class="hljs-comment"># 上传图片</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">updateImage</span>(<span class="hljs-params">filepath</span>):</span>
    _upload_url = <span class="hljs-string">"******************************/api/content/file/upload"</span>
    files = {<span class="hljs-string">'media'</span>: open(filepath, <span class="hljs-string">'rb'</span>)}
    upload_res = requests.post(_upload_url, files=files)
    print(<span class="hljs-string">'正在上传：'</span>, filepath)
    <span class="hljs-keyword">return</span> upload_res.json()
</code></pre>
<p>提取返回的 <code>url</code></p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">upload_list</span>(<span class="hljs-params">_upload_url</span>):</span>
    _file_dict = {}
    file_list = os.listdir(_upload_url)
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> file_list:
        data_json = updateImage(_upload_url + i)
        _file_dict[i] = data_json[<span class="hljs-string">"***"</span>][<span class="hljs-string">"*pic*"</span>] + <span class="hljs-string">"\n"</span>
    <span class="hljs-keyword">return</span> _file_dict
</code></pre>
<p>重写 m3u8 文件</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">rewrite_m3u8</span>(<span class="hljs-params">m3u8_file, file_dict</span>):</span>
    print(file_dict)
    <span class="hljs-keyword">with</span> open(m3u8_file, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> f:
        lines = f.readlines()
        <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> lines:
            rename = i.replace(<span class="hljs-string">"ts"</span>, <span class="hljs-string">"png"</span>).replace(<span class="hljs-string">"\n"</span>, <span class="hljs-string">""</span>)
            <span class="hljs-keyword">if</span> rename <span class="hljs-keyword">in</span> file_dict.keys():
                lines[lines.index(i)] = file_dict[rename]
                print(<span class="hljs-string">"正在替换："</span>, i)
    <span class="hljs-keyword">with</span> open(m3u8_file, <span class="hljs-string">'w'</span>) <span class="hljs-keyword">as</span> f:
        f.writelines(lines)
    print(<span class="hljs-string">"rewrite_m3u8"</span>)
</code></pre>
<h3 id="heading-5lqu44cb5liy6igu5lul5lik5luj56cb55qe5ywl5yj5ye95pww">五、串联以上代码的入口函数</h3>
<pre><code class="lang-python"><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
    video_to_ts(<span class="hljs-string">"video.mp4"</span>)
    ts_to_m3u8(<span class="hljs-string">"./ts_single/ts_single.ts"</span>, <span class="hljs-string">"5"</span>)
    rename_ts_to_png()
    rewrite_ts_to_png()
    upload_url = <span class="hljs-string">"./ts_rewrite/"</span>
    file_dict = upload_list(upload_url)
    rewrite_m3u8(<span class="hljs-string">"./temp_playlist.m3u8"</span>, file_dict)
    print(<span class="hljs-string">"main"</span>)
</code></pre>
<p>需要自行创建文件夹及准备文件</p>
<ul>
<li>./ts_single/</li>
<li>./ts_all/</li>
<li>./ts_rewrite/</li>
<li>./video.mp4</li>
<li>./PNG</li>
</ul>
<p>完整代码
(无上传接口版本)</p>
<pre><code class="lang-python"><span class="hljs-comment"># coding:utf-8</span>

<span class="hljs-keyword">import</span> subprocess
<span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">from</span> shutil <span class="hljs-keyword">import</span> copyfile
<span class="hljs-keyword">import</span> os


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">video_to_ts</span>(<span class="hljs-params">video_path</span>):</span>
    ts_all = <span class="hljs-string">".//ts_single//ts_single.ts"</span>
    cmd_str = <span class="hljs-string">f'ffmpeg -y -i <span class="hljs-subst">{video_path}</span> -vcodec copy -acodec copy -vbsf h264_mp4toannexb <span class="hljs-subst">{ts_all}</span>'</span>
    subprocess.run(cmd_str, encoding=<span class="hljs-string">"utf-8"</span>, shell=<span class="hljs-literal">True</span>)
    print(<span class="hljs-string">f'从 <span class="hljs-subst">{video_path}</span> 转换到 <span class="hljs-subst">{cmd_str}</span> 成功！'</span>)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">ts_to_m3u8</span>(<span class="hljs-params">ts_single, singlg_time</span>):</span>
    cmd_str = <span class="hljs-string">f'ffmpeg -i <span class="hljs-subst">{ts_single}</span> -c copy -map 0 -f segment -segment_list temp_playlist.m3u8 -segment_time <span class="hljs-subst">{singlg_time}</span> ./ts_all/%03d.ts'</span>
    subprocess.run(cmd_str, encoding=<span class="hljs-string">"utf-8"</span>, shell=<span class="hljs-literal">True</span>)
    print(<span class="hljs-string">f'从 <span class="hljs-subst">{ts_single}</span> 转换到 temp_playlist.m3u8 成功！'</span>)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">rename_ts_to_png</span>():</span>
    file_list = os.listdir(<span class="hljs-string">"./ts_all"</span>)
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> file_list:
        <span class="hljs-keyword">if</span> i.endswith(<span class="hljs-string">".ts"</span>):
            new_name = i.replace(<span class="hljs-string">".ts"</span>, <span class="hljs-string">".png"</span>)
            os.rename(<span class="hljs-string">"./ts_all/"</span> + i, <span class="hljs-string">"./ts_all/"</span> + new_name)
    print(<span class="hljs-string">"rename_ts_to_png"</span>)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">rewrite_ts_to_png</span>():</span>
    file_list = os.listdir(<span class="hljs-string">"./ts_all"</span>)
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> file_list:
        copyfile(<span class="hljs-string">"PNG"</span>, <span class="hljs-string">"./ts_rewrite/"</span> + i)
    print(<span class="hljs-string">"rewrite_ts_to_png"</span>)
    file_list = os.listdir(<span class="hljs-string">"./ts_rewrite"</span>)
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> file_list:
        <span class="hljs-keyword">if</span> i.endswith(<span class="hljs-string">".png"</span>):
            bin_file = open(<span class="hljs-string">"./ts_all/"</span> + i, <span class="hljs-string">'rb'</span>)  <span class="hljs-comment"># 打开二进制文件</span>
            <span class="hljs-comment"># 合并文件</span>
            <span class="hljs-keyword">with</span> open(<span class="hljs-string">"./ts_rewrite/"</span> + i, <span class="hljs-string">'ab'</span>) <span class="hljs-keyword">as</span> f:
                f.write(bin_file.read())
            bin_file.close()
    <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>


<span class="hljs-comment"># 上传图片</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">updateImage</span>(<span class="hljs-params">filepath</span>):</span>
    _upload_url = <span class="hljs-string">"*************************************************"</span>
    files = {<span class="hljs-string">'media'</span>: open(filepath, <span class="hljs-string">'rb'</span>)}
    upload_res = requests.post(_upload_url, files=files)
    print(<span class="hljs-string">'正在上传：'</span>, filepath)
    <span class="hljs-keyword">return</span> upload_res.json()


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">upload_list</span>(<span class="hljs-params">_upload_url</span>):</span>
    _file_dict = {}
    file_list = os.listdir(_upload_url)
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> file_list:
        data_json = updateImage(_upload_url + i)
        _file_dict[i] = data_json[<span class="hljs-string">"****"</span>][<span class="hljs-string">"******"</span>] + <span class="hljs-string">"\n"</span>
    <span class="hljs-keyword">return</span> _file_dict


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">rewrite_m3u8</span>(<span class="hljs-params">m3u8_file, file_dict</span>):</span>
    print(file_dict)
    <span class="hljs-keyword">with</span> open(m3u8_file, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> f:
        lines = f.readlines()
        <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> lines:
            rename = i.replace(<span class="hljs-string">"ts"</span>, <span class="hljs-string">"png"</span>).replace(<span class="hljs-string">"\n"</span>, <span class="hljs-string">""</span>)
            <span class="hljs-keyword">if</span> rename <span class="hljs-keyword">in</span> file_dict.keys():
                lines[lines.index(i)] = file_dict[rename]
                print(<span class="hljs-string">"正在替换："</span>, i)
    <span class="hljs-keyword">with</span> open(m3u8_file, <span class="hljs-string">'w'</span>) <span class="hljs-keyword">as</span> f:
        f.writelines(lines)
    print(<span class="hljs-string">"rewrite_m3u8"</span>)


<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
    video_to_ts(<span class="hljs-string">"video.mp4"</span>)
    ts_to_m3u8(<span class="hljs-string">"./ts_single/ts_single.ts"</span>, <span class="hljs-string">"5"</span>)
    rename_ts_to_png()
    rewrite_ts_to_png()
    upload_url = <span class="hljs-string">"./ts_rewrite/"</span>
    file_dict = upload_list(upload_url)
    rewrite_m3u8(<span class="hljs-string">"./temp_playlist.m3u8"</span>, file_dict)
    print(<span class="hljs-string">"main"</span>)
</code></pre>
]]></content:encoded></item></channel></rss>