最近用presto引擎查数据,发现了语法和MYSQL,PG的稍许区别,写此文章留念~~

文章目录

  • 1 数据类型
  • 2 SELECT 搜索查询
    • 2.1 with 子句
    • 2.2 GROUP BY 子句
      • 2.2.1 GROUP BY
      • 2.2.2 GROUPING SETS
      • 2.2.3 CUBE
      • 2.2.4 ROLLUP
      • 2.2.5 group by, clue, rollup区别
      • 2.2.6 group sets, clue, rollup 组合使用
      • 2.2.7 ALL 和 DISTINCT 的使用
    • 2.3 HAVING
    • 2.4 UNION,INTERSECT, EXCEPT
      • 2.4.1 UNION
      • 2.4.2 INTERSECT
      • 2.4.3 EXCEPT
    • 2.5 ORDER BY 排序
    • 2.6 LIMIT
  • 3 其他常用SQL
    • 3.1 SCHEMA 操作
      • 3.1.1 重命名 SCHEMA
      • 3.1.2 创建 SCHEMA
      • 3.1.2 删除 SCHEMA
    • 3.2 TABLE 操作
      • 3.2.1 创建 TABLE
      • 3.2.2 查看建表语句
      • 3.2.3 修改 TABLE
      • 3.2.4 删除 TABLE
      • 3.2.5 CREATE TABLE AS 使用搜索结果建新表
    • 3.3 ANALYZE 统计表和列信息
    • 3.4 CALL 调用存储过程
    • 3.5 START TRANSACTION,ROLLBACK,COMMIT 事务
    • 3.6 DELETE 删除
    • 3.8 PREPARE, EXECUTE, DEALLOCATE PREPARE
    • 3.9 INSERT 插入数据
    • 3.10 查看数据仓库目录,SCHEMA, TABLE,COLUMN

presto是Facebook主持下运营的开源的分布式SQL查询引擎,用于针对各种大小(从千兆字节到千兆字节)的数据源运行交互式分析查询。本文主要介绍常用SQL,具体可参考官方文档: https://prestodb.github.io/docs/current/

1 数据类型

  • Boolean: true, false
  • Integer: tinyint, smallint, integer, bigint
  • Floating-Point: real, double
  • Fixed-Precision:DECIMAL
  • String:varchar, char, varbinary, json
  • Date and Time: date, time, time with time zone, timestamp, timestamp with time zone, interval year to month, interval day to second
  • Structural: array, map, row
  • Network Address: ipaddress
  • HyperLogLog: HyperLogLog, P4HyperLogLog
  • Quantile Digest: QDigest

2 SELECT 搜索查询

[ WITH with_query [, ...] ]
SELECT [ ALL | DISTINCT ] select_expr [, ...]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY [ ALL | DISTINCT ] grouping_element [, ...] ]
[ HAVING condition]
[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
[ ORDER BY expression [ ASC | DESC ] [, ...] ]
[ LIMIT [ count | ALL ] ]以下是这些参数可能的格式
- from_itemtable_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]from_item join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]- join_type[ INNER ] JOINLEFT [ OUTER ] JOINRIGHT [ OUTER ] JOINFULL [ OUTER ] JOINCROSS JOIN- grouping_element()expressionGROUPING SETS ( ( column [, ...] ) [, ...] )CUBE ( column [, ...] )ROLLUP ( column [, ...] )

2.1 with 子句

with 定义要在查询中使用的命名关系

WITH x AS (SELECT a, MAX(b) AS b FROM t GROUP BY a)
SELECT a, b FROM x;等同于
SELECT a, b
FROM (SELECT a, MAX(b) AS b FROM t GROUP BY a
) AS x;也可以用于多条定义
WITHt1 AS (SELECT a, MAX(b) AS b FROM x GROUP BY a),t2 AS (SELECT a, AVG(d) AS d FROM y GROUP BY a)
SELECT t1.*, t2.*
FROM t1
JOIN t2 ON t1.a = t2.a;也可以链式使用
WITHx AS (SELECT a FROM t),y AS (SELECT a AS b FROM x),z AS (SELECT b AS c FROM y)
SELECT c FROM z;

2.2 GROUP BY 子句

2.2.1 GROUP BY

当在select语句中使用group by时,所有输出表达式都必须是聚合函数或group by子句中存在的列。

按字段nationkey分组,并查出各组数量,以下两种写法是一致的,by 2 代表以输出表达式第2列做分组
SELECT count(*), nationkey FROM customer GROUP BY 2;
SELECT count(*), nationkey FROM customer GROUP BY nationkey;也可以不输出指定分组的列,如下
SELECT count(*) FROM customer GROUP BY mktsegment;

2.2.2 GROUPING SETS

可以指定多个列进行分组,结果列中不属于分组列的将被设置为NUll。
具有复杂分组语法(GROUPING SETS, CUBE 或 ROLLUP)的查询只从基础数据源读取一次,而使用UNION ALL的查询将读取基础数据三次。这就是当数据源不具有确定性时,使用UNION ALL的查询可能会产生不一致的结果的原因。

有一个表:SELECT * FROM shipping;origin_state | origin_zip | destination_state | destination_zip | package_weight
--------------+------------+-------------------+-----------------+----------------California   |      94131 | New Jersey        |            8648 |             13California   |      94131 | New Jersey        |            8540 |             42New Jersey   |       7081 | Connecticut       |            6708 |            225California   |      90210 | Connecticut       |            6927 |           1337California   |      94131 | Colorado          |           80302 |              5New York     |      10002 | New Jersey        |            8540 |              3
(6 rows)SELECT origin_state, origin_zip, destination_state, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS ((origin_state),(origin_state, origin_zip),(destination_state));这个的查询在逻辑上等同于多个分组查询的union all:SELECT origin_state, NULL, NULL, sum(package_weight)
FROM shipping GROUP BY origin_stateUNION ALLSELECT origin_state, origin_zip, NULL, sum(package_weight)
FROM shipping GROUP BY origin_state, origin_zipUNION ALLSELECT NULL, NULL, destination_state, sum(package_weight)
FROM shipping GROUP BY destination_state;结果如下:origin_state | origin_zip | destination_state | _col0
--------------+------------+-------------------+-------New Jersey   | NULL       | NULL              |   225California   | NULL       | NULL              |  1397New York     | NULL       | NULL              |     3California   |      90210 | NULL              |  1337California   |      94131 | NULL              |    60New Jersey   |       7081 | NULL              |   225New York     |      10002 | NULL              |     3NULL         | NULL       | Colorado          |     5NULL         | NULL       | New Jersey        |    58NULL         | NULL       | Connecticut       |  1562
(10 rows)

2.2.3 CUBE

为给定的列生成所有可能的分组,比如 (origin_state, destination_state) 的可能分组为(origin_state, destination_state),
(origin_state),
(destination_state),
()

SELECT origin_state, destination_state, sum(package_weight)
FROM shipping
GROUP BY CUBE (origin_state, destination_state);等同于SELECT origin_state, destination_state, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS ((origin_state, destination_state),(origin_state),(destination_state),());

2.2.4 ROLLUP

为给定的列集生成部分可能的分类汇总

SELECT origin_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY ROLLUP (origin_state, origin_zip);等同于SELECT origin_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS ((origin_state, origin_zip), (origin_state), ());

2.2.5 group by, clue, rollup区别

比如按字段1,2,3来分组,group 只会聚合1,2,3分组,clue会展示所有层级分组,rollup只会展示1以下所有分组
用列表标识会更直观

group by

1 2 3

clue

1 2 3
1 2
1
2 3
2
3

rollup

1 2 3
1 2
1

2.2.6 group sets, clue, rollup 组合使用

SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BYGROUPING SETS ((origin_state, destination_state)),ROLLUP (origin_zip);等同于SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BYGROUPING SETS ((origin_state, destination_state)),GROUPING SETS ((origin_zip), ());逻辑上等同于SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS ((origin_state, destination_state, origin_zip),(origin_state, destination_state));

2.2.7 ALL 和 DISTINCT 的使用

在复杂的组合搜索中 ALL 和 DISTINCT 作用很强大,ALL 代表全部输出,DISTINCT代表去重后输出

SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY ALLCUBE (origin_state, destination_state),ROLLUP (origin_state, origin_zip);等同于SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS ((origin_state, destination_state, origin_zip),(origin_state, origin_zip),(origin_state, destination_state, origin_zip),(origin_state, origin_zip),(origin_state, destination_state),(origin_state),(origin_state, destination_state),(origin_state),(origin_state, destination_state),(origin_state),(destination_state),());
SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY DISTINCTCUBE (origin_state, destination_state),ROLLUP (origin_state, origin_zip);等同于SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS ((origin_state, destination_state, origin_zip),(origin_state, origin_zip),(origin_state, destination_state),(origin_state),(destination_state),());

2.3 HAVING

HAVING与聚合函数和GROUP BY一起使用,以过滤GROUP BY。

从customer表中选择帐户余额大于指定值的组
SELECT count(*), mktsegment, nationkey,CAST(sum(acctbal) AS bigint) AS totalbal
FROM customer
GROUP BY mktsegment, nationkey
HAVING sum(acctbal) > 5700000
ORDER BY totalbal DESC;

2.4 UNION,INTERSECT, EXCEPT

query UNION [ALL | DISTINCT] query
query INTERSECT [DISTINCT] query
query EXCEPT [DISTINCT] query- all: 最终结果集中包括所有行
- distinct: 组合结果集中只包含唯一的行
- 如果两者都未指定,则行为默认为distinct。区别
- intersect或except不支持all参数。
- 除非通过括号明确指定顺序,否则将从左到右处理多个集合操作
- INTERSECT 优先级高于UNION和EXCEPT比如:A UNION B INTERSECT C EXCEPT D 等同于A UNION (B INTERSECT C) EXCEPT D

2.4.1 UNION

以下结果返回13和42
SELECT 13 UNION SELECT 42;以下结果返回13和42
SELECT 13 UNION SELECT * FROM (VALUES 42, 13);以下结果返回13,42 和 13
SELECT 13 UNION ALL SELECT * FROM (VALUES 42, 13);

2.4.2 INTERSECT

使用INTERSECT代表返回的最终结果集为:INTERSECT之前的结果与INTERSECT查出的结果取交集

比如以下结果返回 13:
SELECT * FROM (VALUES 13, 42)
INTERSECT
SELECT 13;

2.4.3 EXCEPT

使用EXCEPT代表返回的最终结果集中排除EXCEPT查出的结果

比如以下结果返回 42:
SELECT * FROM (VALUES 13, 42)
EXCEPT
SELECT 13;

2.5 ORDER BY 排序

一般放到SELECT语句的最后,或在HAVING之前, 默认ASC NULLS LAST,

ORDER BY expression [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...]- ASC: 默认从小到大正序排序
- DESC: 倒序
- NULLS FIRST: NULL 值最大
- NULLS LAST: 默认 NULL 值最小

2.6 LIMIT

limit 5 代表只输出5条结果,limit all 代表全部输出,没有数量限制

3 其他常用SQL

3.1 SCHEMA 操作

3.1.1 重命名 SCHEMA

ALTER SCHEMA name RENAME TO new_nameeg: 将 web 重命名为 traffic
ALTER SCHEMA web RENAME TO traffic

3.1.2 创建 SCHEMA

CREATE SCHEMA [ IF NOT EXISTS ] schema_name
[ WITH ( property_name = expression [, ...] ) ]- IF NOT EXISTS 比较安全,防止SCHEMA已存在的报错
- WITH 可以给SCHEMA添加属性,通过以下SQL可以查看所有属性:
SELECT * FROM system.metadata.schema_propertieseg:
创建一个名为web的SCHEMA
CREATE SCHEMA web
创建一个在hive目录下名为sales的SCHEMA
CREATE SCHEMA hive.sales
如果名为traffic的SCHEMA不存在那么创建它
CREATE SCHEMA IF NOT EXISTS traffic

3.1.2 删除 SCHEMA

DROP SCHEMA [ IF EXISTS ] schema_name- IF EXISTS 可以防止SCHEMA不存在时的报错eg:
删除名为web的SCHEMA
DROP SCHEMA web
如果名为web的SCHEMA存在,则删除它
DROP SCHEMA IF EXISTS sales

3.2 TABLE 操作

3.2.1 创建 TABLE

CREATE TABLE [ IF NOT EXISTS ]
table_name ({ column_name data_type [ COMMENT comment ] [ WITH ( property_name = expression [, ...] ) ]| LIKE existing_table_name [ { INCLUDING | EXCLUDING } PROPERTIES ] }[, ...]
)
[ COMMENT table_comment ]
[ WITH ( property_name = expression [, ...] ) ]- IF NOT EXISTS 比较安全,防止TABLE已存在的报错
- WITH 可以给TABLE添加属性:
通过以下SQL可以查看所有表属性
SELECT * FROM system.metadata.table_properties
通过以下SQL可以查看所有列属性
SELECT * FROM system.metadata.column_properties
- COMMENT 为表添加注释
- LIKE 可用于在新表中包含来自现有表的所有列。可以指定多个LIKE子句,允许从多个表复制列。eg:
创建一个名为orders的表, 并添加表注释
CREATE TABLE orders (orderkey bigint,orderstatus varchar,totalprice double,orderdate date
)
COMMENT 'A table to keep track of orders.'
WITH (format = 'ORC')创建一个名为bigger_orders的表,并包含orders表的所有字段
CREATE TABLE bigger_orders (another_orderkey bigint,LIKE orders,another_orderdate date
)

3.2.2 查看建表语句

SHOW CREATE TABLE table_name

3.2.3 修改 TABLE

重命名
ALTER TABLE name RENAME TO new_name
添加字段
ALTER TABLE name ADD COLUMN column_name data_type [ COMMENT comment ] [ WITH ( property_name = expression [, ...] ) ]
删除字段
ALTER TABLE name DROP COLUMN column_name
重命名字段
ALTER TABLE name RENAME COLUMN column_name TO new_column_name

3.2.4 删除 TABLE

DROP TABLE  [ IF EXISTS ] table_name- IF EXISTS 可以防止TABLE不存在时的报错eg:
删除名为web的TABLE
DROP TABLE web
如果名为web的TABLE存在,则删除它
DROP TABLE IF EXISTS sales

3.2.5 CREATE TABLE AS 使用搜索结果建新表

CREATE TABLE [ IF NOT EXISTS ] table_name [ ( column_alias, ... ) ]
[ COMMENT table_comment ]
[ WITH ( property_name = expression [, ...] ) ]
AS query
[ WITH [ NO ] DATA ]eg:
创建一个新表orders_column_aliased,字段order_date, total_price分别来自于表orders的字段orderdate, totalprice
CREATE TABLE orders_column_aliased (order_date, total_price)
AS
SELECT orderdate, totalprice
FROM orders

3.3 ANALYZE 统计表和列信息

统计表和列信息,目前该语句只支持Hive connector。
ANALYZE table_name [ WITH ( property_name = expression [, ...] ) ]- WITH 可以给查询添加特定属性:
通过以下SQL可以查看所有可以使用的属性
SELECT * FROM system.metadata.analyze_properties

3.4 CALL 调用存储过程

调用存储过程,有些连接器,比如 PostgreSQL Connector,有自己的存储过程,不能通过call调用
CALL procedure_name ( [ name => ] expression [, ...] )eg:
传入必传参数,调用存储过程
CALL test(123, 'apple');
传入命名参数,调用存储过程
CALL test(name => 'apple', id => 123);
不需要传参,调用存储过程
CALL catalog.schema.test();

3.5 START TRANSACTION,ROLLBACK,COMMIT 事务

开启事务 (默认为READ WRITE读写事务)
START TRANSACTION [ mode [, ...] ]
回滚事务
ROLLBACK [ WORK ]
提交事务
COMMIT [ WORK ]- model 是以下的一种:
ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
READ { ONLY | WRITE }eg:
开始一个事务,默认为READ WRITE读写事务
START TRANSACTION;
开始一个可重复读事务
START TRANSACTION ISOLATION LEVEL REPEATABLE READ;
开始一个读写事务
START TRANSACTION READ WRITE;
开始一个提交读/不可重复读、只读事务
START TRANSACTION ISOLATION LEVEL READ COMMITTED, READ ONLY;
开始一个读写串行化事务
START TRANSACTION READ WRITE, ISOLATION LEVEL SERIALIZABLE;

3.6 DELETE 删除

有的连接器对于删除有限制或者是不支持, 需要看具体的连接器文档

DELETE FROM table_name [ WHERE condition ]eg:
删除lineitem表里的shipmode = 'AIR'的行
DELETE FROM lineitem WHERE shipmode = 'AIR';删除所有orders里的数据
DELETE FROM orders;

3.8 PREPARE, EXECUTE, DEALLOCATE PREPARE

声明一个名为statement_name的SQL
PREPARE statement_name FROM statement
执行名为statement_name的声明
EXECUTE statement_name [ USING parameter1 [ , parameter2, ... ] ]
删除名为statement_name的声明
DEALLOCATE PREPARE statement_nameeg:
准备一条sql语句
PREPARE my_select2 FROM
SELECT name FROM nation WHERE regionkey = ? and nationkey < ?;执行这个语句,并加入?的参数
EXECUTE my_select2 USING 1, 3;以上两句相当于执行下面这条SQL:
SELECT name FROM nation WHERE regionkey = 1 AND nationkey < 3;

3.9 INSERT 插入数据

INSERT INTO table_name [ ( column [, ... ] ) ] queryeg:
往orders表里插入数据,数据全部来源于new_orders表
INSERT INTO orders SELECT * FROM new_orders;往cities表里插入一条数据
INSERT INTO cities VALUES (1, 'San Francisco');往cities表里插入多条数据
INSERT INTO cities VALUES (2, 'San Jose'), (3, 'Oakland');指定字段名往nation表里插入多条数据,如果有字段未指定,则用字段默认值, 没有默认值就是null
INSERT INTO nation (nationkey, name, regionkey, comment)
VALUES (26, 'POLAND', 3, 'no comment');

3.10 查看数据仓库目录,SCHEMA, TABLE,COLUMN

查看数据仓库第一层目录
SHOW CATALOGS [ LIKE pattern ]查看所有SCHEMAS
SHOW SCHEMAS [ FROM catalog ] [ LIKE pattern ]查看schema里的表
SHOW TABLES [ FROM schema ] [ LIKE pattern ]查看表的字段类型,描述, 搜索出来的结果有:column type extra comment
DESCRIBE table_name
相当于 SHOW COLUMNS from table_name

presto 语法攻略相关推荐

  1. html基础开发-jQuery框架基础语法攻略(攻略一)

    1 jquery框架 ready方法使用 使用方法:$(document).ready()   当document中的所有节点全部加载完成后ready中的方法 例如下面的使用案例中,访问页面,当整个页 ...

  2. markdown笔记语法攻略,零基础包教包会

    1,markdown是什么 Markdown是一种轻量级标记语言,创始人是约翰·格鲁伯(John Gruber).它允许人们 "使用易读易写的纯文本格式编写文档,然后转换成有效的 HTML ...

  3. 关闭antimal_i wanna be the brown animal键位怎么操作玩法攻略

    i wanna be the brown animal键位怎么操作玩法攻略,i wanna be the brown animal硬盘版是i wanna系列的又一款经典之作了,里面的游戏boss根据神 ...

  4. 帆软获取上月的第一天与最后一天_《原神》岩港打工第一天怎么玩 岩港打工第一天玩法攻略...

    <原神>在11月2日开启了岩港奇珍行记,玩家可以在璃月港进行打工了,可能有的小伙伴还不清楚第一天的打工要怎么做,所以小编这次就为大家带来了<原神>岩港打工第一天玩法攻略,感兴趣 ...

  5. 云顶之弈机器人法爆_云顶之弈10.16b机器人阵容推荐 云顶之弈10.16b机器人娱乐阵容玩法攻略...

    云顶之弈10.16b机器人阵容推荐,在云顶之弈10.16b版本中机器人没有什么改动,所以以机器人为核心的娱乐阵容依然可以玩,而且运气好的话吃鸡也不是不可以,下面小编为大家带来了云顶之弈10.16b机器 ...

  6. 汤姆克兰西全境封锁服务器维护时间,汤姆克兰西全境封锁无法登录怎么解决 无法登录解决方法攻略...

    <汤姆克兰西:全境封锁>是款大型射击游戏,这款游戏的画面十分的精致,在这款游戏中会有各种不同的任务,玩家要带着武器来进行射击.在游戏的时候很多玩家们都反映无法登录怎么解决?那么下面小编就为 ...

  7. 冰雪复古鸿蒙碎片哪里出,冰雪复古:玩法攻略,如何高爆率搞回收!

    原标题:冰雪复古:玩法攻略,如何高爆率搞回收! 冰冻传说这个手游游戏刚内部测试的时候我就开始玩这个游戏了,第一方面这个游戏全部的装备都是靠打野怪获取的,这点很符合我的喜好,现在分享一些在个人游戏中摸索 ...

  8. 4 关卡流 进阶_赛博朋克2077:实用玩法攻略,技术流玩法攻略

    ❌❌​❌大家好,这里是守望者加速器的小编.在赛博朋克2077这款游戏中,技术流这个玩法被许多玩家使用,但是有些玩家还是不知道应怎么玩.今天,小编就来给大家介绍一下赛博朋克2077中关于技术流的玩法攻略 ...

  9. lol自动刷人机辅助_LOL星籁歌姬新手怎么玩 星籁歌姬技能出装符文打法攻略 新英雄星籁歌姬辅助攻略...

    不少的玩家都想要知道LOL星籁歌姬新手怎么玩,萨勒芬妮的被动叫做星光漫射,那么下面介绍下星籁歌姬技能出装符文打法攻略,每第三次释放基础技能,就会触发回响,就会自动释放两次,看了后定然清楚新英雄星籁歌姬 ...

最新文章

  1. 中国闪存联盟三百大行动成果发布 IBM存储助力企业突破数据临界点
  2. 常用的 服务器 与 交换机
  3. 花40分钟写一个-CBIR引擎-代码公开
  4. paper 46 :中文latex的安装与使用
  5. 【SqlServer】Sqlserver中的DOS命令操作
  6. 【自动化测试】整理各种测试开发工具!持续更新
  7. redis主从配置及无法连接处理
  8. 红橙Darren视频笔记 ViewGroup事件分发分析 基于API27
  9. flask-前端-requests之response对应关系 text
  10. Java开发工具(Eclipse工作空间的基本配置)
  11. IE 存在兼容元素归纳
  12. ZebraDesigner-设计label
  13. Julia最新windows版下载
  14. c语言判断字符串是否对称,c语言 判断字符串是否中心对称
  15. matlab fft 相位,从相位和幅度获取傅立叶变换 – Matlab
  16. DC(Design Compiler)使用说明
  17. python设置清华源镜像
  18. 1253. 将数字转换为16进制
  19. 浏览器实时查看日志log.io
  20. Android Studio的Logcat/Run/Terminal/Build等窗口没有了怎么调出

热门文章

  1. Android:展锐camera调试
  2. CAD中插入外部参照字体会变繁体_CAD外部参照插入后图形不匹配怎么办
  3. 还在花钱润色SCI?润色工具合集及教程!快来!
  4. 根据PEB判断是否被调试
  5. Java+JSP问卷调查系统(含源码+论文+答辩PPT等)
  6. usaco-milk2-pass
  7. python大数据分析入门实例-Python大数据分析与机器学习商业案例实战
  8. 带给你设计灵感的30个超棒的暗色系网站设计
  9. Inkscape插入LaTeX公式
  10. 线性回归阶段学习总结