提交 93a694e9 编写于 作者: V Vonng

添加DDIA章节引用,ch5初翻

上级 24a40fa5
......@@ -385,7 +385,7 @@ Twitter的第一个版本使用了方法1,但系统努力跟上主页时间线
## 参考文献
[1]: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.68.9136&rep=rep1&type=pdf "Michael Stonebraker and Uğur Çetintemel: “'One Size Fits All': An Idea Whose Time Has Come and Gone,” at *21st International Conference on Data Engineering* (ICDE), April 2005."
[1]: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.68.9136&rep=rep1&type=pdf "Michael Stonebraker and Uğur Çetintemel: “'One Size Fits All': An Idea Whose Time Has Come and Gone,” at *21st International Conference on Data Engineering* (ICDE), April 2005."
[2]: http://www.sei.cmu.edu/reports/92tr033.pdf "Walter L. Heimerdinger and Charles B. Weinstock: “A Conceptual Framework for System Fault Tolerance,” Technical Report CMU/SEI-92-TR-033, Software Engineering Institute, Carnegie Mellon University, October 1992."
[3]: https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-yuan.pdf "Ding Yuan, Yu Luo, Xin Zhuang, et al.: “Simple Testing Can Prevent Most Critical Failures: An Analysis of Production Failures in Distributed Data-Intensive Systems,” at 11th USENIX Symposium on Operating Systems Design and Implementation (OSDI), October 2014."
[4]: http://techblog.netflix.com/2011/07/netflix-simian-army.html "Yury Izrailevsky and Ariel Tseitlin: “The Netflix Simian Army,” techblog.netflix.com, July 19, 2011."
......@@ -515,3 +515,11 @@ Twitter的第一个版本使用了方法1,但系统努力跟上主页时间线
(COMPSAC), July 2008.
[doi:10.1109/COMPSAC.2008.50](http://dx.doi.org/10.1109/COMPSAC.2008.50)
------
| 上一章 | 目录 | 下一章 |
| ----------------------------------- | ------------------------------- | ------------------------------------ |
| [第一部分:数据系统基础](part-i.md) | [设计数据密集型应用](README.md) | [第二章:数据模型与查询语言](ch2.md) |
\ No newline at end of file
......@@ -63,7 +63,7 @@
现在大多数应用程序开发都是在面向对象的编程语言中完成的,这导致了对SQL数据模型的普遍批评:如果数据存储在关系表中,那么应用程序代码中的对象之间需要一个笨拙的转换层,表,行和列的数据库模型。模型之间的不连贯有时被称为**阻抗不匹配(impedance mismatch)**[^i]。
[^i]: 从电子学借用一个术语。每个电路的输入和输出都有一定的阻抗(交流电阻)。当您将一个电路的输出连接到另一个电路的输入时,如果两个电路的输出和输入阻抗匹配,则连接上的功率传输将被最大化。阻抗不匹配可能导致信号反射和其他问题
[^i]: 从电子学借用一个术语。每个电路的输入和输出都有一定的阻抗(交流电阻)。当您将一个电路的输出连接到另一个电路的输入时,如果两个电路的输出和输入阻抗匹配,则连接上的功率传输将被最大化。阻抗不匹配可能导致信号反射和其他问题
像ActiveRecord和Hibernate这样的对象关系映射(ORM)框架减少了这个翻译层需要的样板代码的数量,但是它们不能完全隐藏这两个模型之间的差异。
......@@ -1085,3 +1085,10 @@ Datalog方法需要对本章讨论的其他查询语言采取不同的思维方
[ROOT for Big Data Analysis](http://indico.cern.ch/getFile.py/access?contribId=13&resId=0&materialId=slides&confId=246453),” at *Workshop on the Future of Big Data Management*,
London, UK, June 2013.
------
| 上一章 | 目录 | 下一章 |
| -------------------------------------- | ------------------------------- | ---------------------------- |
| [第一章:可靠、可扩展、可维护](ch1.md) | [设计数据密集型应用](README.md) | [第三章:存储与检索](ch3.md) |
......@@ -854,3 +854,12 @@ WHERE product_sk = 31 AND store_sk = 3
Discovery*, volume 1, number 1, pages 29–53, March 2007.
[doi:10.1023/A:1009726021843](http://dx.doi.org/10.1023/A:1009726021843)
------
| 上一章 | 目录 | 下一章 |
| ------------------------------------ | ------------------------------- | ---------------------------- |
| [第二章:数据模型与查询语言](ch2.md) | [设计数据密集型应用](README.md) | [第四章:编码与演化](ch4.md) |
......@@ -698,3 +698,9 @@ actor模型是单个进程中并发的编程模型。逻辑被封装在角色中
[Postscript: Maps](http://learnyousomeerlang.com/maps),” *learnyousomeerlang.com*,
April 9, 2014.
------
| 上一章 | 目录 | 下一章 |
| ---------------------------- | ------------------------------- | --------------------------------- |
| [第三章:存储与检索](ch3.md) | [设计数据密集型应用](README.md) | [第二部分:分布式数据](part-iimd) |
\ No newline at end of file
此差异已折叠。
......@@ -388,6 +388,11 @@ Couchbase不会自动重新平衡,这简化了设计。通常情况下,它
33. Shivnath Babu and Herodotos Herodotou: “[Massively Parallel Databases and MapReduce Systems](http://research.microsoft.com/pubs/206464/db-mr-survey-final.pdf),” *Foundations and Trends in Databases*, volume 5, number 1, pages 1–104, November 2013.[doi:10.1561/1900000036](http://dx.doi.org/10.1561/1900000036)
#####
#####
\ No newline at end of file
------
| 上一章 | 目录 | 下一章 |
| :--------------------: | :-----------------------------: | :--------------------: |
| [第五章:复制](ch5.md) | [设计数据密集型应用](README.md) | [第七章:事务](ch7.md) |
此差异已折叠。
# PostGIS简明教程
PostGIS是PostgreSQL强大扩展能力的最佳示例,它已经成为GIS行业的事实标准,值得用几本书去专门讲。但这里不妨先管中窥豹一下。
## 1. 安装与配置
安装与配置并不是PostGIS的学习重点,然而它确实是许多新人入门的最大拦路虎。
建议直接使用现成的二进制包,发行版来安装PostGIS,而不是手工编译,这会轻松很多。
在Mac上可以通过homebrew一键安装PostGIS
```bash
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```
在CentOS上可以通过yum安装,在Ubuntu可以通过apt-get安装,不再赘述
连接PostgreSQL并执行以下查询,确认PostGIS扩展已经正确地安装,可以被数据库识别:
```bash
vonng=# SELECT name,default_version FROM pg_available_extensions WHERE name ~ 'gis';
name | default_version
------------------------+-----------------
postgis | 2.4.3
postgis_tiger_geocoder | 2.4.3
postgis_topology | 2.4.3
btree_gist | 1.5
postgis_sfcgal | 2.4.3
```
## 2. 创建GIS数据库
PostGIS是PostgreSQL的一个扩展,连接并执行以下命令,可在当前数据库中加载PostGIS插件。
```sql
CREATE EXTENSION postgis;
CREATE EXTENSION postgis_topology;
CREATE EXTENSION postgis_sfcgal;
CREATE EXTENSION fuzzystrmatch;
CREATE EXTENSION address_standardizer;
CREATE EXTENSION address_standardizer_data_us;
CREATE EXTENSION postgis_tiger_geocoder;
```
执行完毕后,执行`postgis_full_version`查看当前PostGIS版本。
```sql
gis=# SELECT postgis_full_version();
POSTGIS="2.4.3 r16312" PGSQL="100" GEOS="3.6.2-CAPI-1.10.2 4d2925d6" PROJ="Rel. 4.9.3, 15 August 2016" GDAL="GDAL 1.11.5, released 2016/07/01" LIBXML="2.9.7" LIBJSON="0.12.1" RASTER
```
现在GIS数据库已经准备好了。让我们进入主题吧。
## 3. 几何对象
PostGIS支持很多几何类型:点,线,多边形,复合几何体等,并提供了大量实用的相关函数。
注意,虽然PostGIS中的几何类型与PostgreSQL内建的几何类型非常像,但它们并不是一回事。所有PostGIS中的对象命名通常都以`ST`开头,是空间类型(Spatial Type)的缩写。
对于PostGIS而言,所有几何对象都有一个公共父类`Geometry`,这种面向对象的组织形式允许在数据库中进行一些灵活的操作:例如在数据表中的同一列中存储不同的几何对象。
每种几何对象实际上都是PostGIS底层C++几何库geos中对象包装,这些几何类型按照面向对象的继承关系组成了一颗树:
![](img/gis-type.png)
### 几何对象的创建
几何对象可以通过PostGIS内建的函数进行创建,例如:
```sql
>>> SELECT ST_Point(1.0, 2.0);
0101000000000000000000F03F0000000000000040
```
注意,当查询原始集合类型时,PostgreSQL会返回几何对象的二进制数据的十六进制表示。这允许各类ETL工具以同样的方式高效处理PostGIS类型,但二进制表示对人类很不友好,可以通过`ST_AsText`获取人类可读的格式。
```sql
>>> SELECT ST_AsText(ST_Point(1.0, 2.0));
POINT(1 2)
```
当然,如同PostgreSQL内建的类型一样,PostGIS类型也可以使用字面值的方式创建。
```SQL
CREATE TABLE geom (
geom GEOMETRY
);
INSERT INTO geom VALUES
('Point(1 2)'),
('LineString(0 0,1 1,2 1,2 3)'),
('Polygon((0 0, 1 0, 1 1,0 1,0 0))'),
('MultiPoint(1 2,3 4)');
```
通常在使用PostGIS中,几何类型使用统一的`Geometry`类型。如果需要判断具体的几何类型,则可以使用`ST_GeometryType`
```sql
geo=# SELECT ST_GeometryType(geom), ST_AsText(geom) FROM geom;
st_geometrytype | st_astext
-----------------+--------------------------------
ST_Point | POINT(1 2)
ST_LineString | LINESTRING(0 0,1 1,2 1,2 3)
ST_Polygon | POLYGON((0 0,1 0,1 1,0 1,0 0))
ST_MultiPoint | MULTIPOINT(1 2,3 4)
```
### 点
让我们从最简单的**点(Point)**开始。PostGIS的点默认是二维空间中的点,具有两个`double`类型的分量`x,y`。使用`ST_X, ST_Y`可以从点中取出对应的坐标分量
```sql
geo=# SELECT ST_X(geom), ST_Y(geom) FROM geom WHERE ST_GeometryType(geom) = 'ST_Point';
st_x | st_y
------+------
1 | 2
```
在介绍更多几何类型前,
## 4. Play with Point
单纯使用PostGIS的Point,就已经可以实现许多有趣的功能了。
### 计算两点距离
```sql
geo=# SELECT ST_Point(1,1) <-> ST_Point(2,2);
1.4142135623730951
```
运算符`<->`可以计算左右两侧两点之间的距离。
### 应用:查找最近的餐馆
现在我们有一张包含全国所有餐馆的表,有五千万条记录:
```sql
CREATE TABLE poi(
id BIGSERIAL,
name TEXT,
position GEOMETRY
)
```
如果我现在在国贸`(116.458855, 39.909863)`,想要找到距离这里最近的10家餐厅。应该如何查询呢?
```sql
SELECT name FROM poi
ORDER BY position <-> ST_Point(116.458855, 39.909863) LIMIT 10;
```
```sql
QUERY PLAN
---------------------------------------------------------------------------------------------
Limit (cost=4610514.44..4610514.47 rows=10 width=31)
-> Sort (cost=4610514.44..4767389.77 rows=62750132 width=31)
Sort Key: (("position" <-> '0101000000CAA65CE15D1D5D40946B0A6476F44340'::geometry))
-> Seq Scan on poi (cost=0.00..3254506.65 rows=62750132 width=31)
```
执行需要一次扫表,需要几分钟的时间。对于只有几千行、每天查询几十次来说,这也没什么大不了的。但对于几千万的数据量,几万的查询QPS,就需要索引了。
`position`列上创建GIST索引:
```sql
CREATE INDEX CONCURRENTLY idx_poi_position_gist ON poi USING gist(position);
```
然后再执行同样的查询,变为了索引扫描。
```sql
QUERY PLAN
------------------------------------------------------------------------------------------------------
Limit (cost=0.42..9.73 rows=10 width=31)
-> Index Scan using idx_poi_position_gist on poi (cost=0.42..58440964.86 rows=62750132 width=31)
Order By: ("position" <-> '0101000000CAA65CE15D1D5D40946B0A6476F44340'::geometry)
```
结果,在0.1毫秒内就返回了结果!
```sql
geo=# SELECT name
FROM poi
ORDER BY position <-> ST_Point(116.458855, 39.909863)
LIMIT 10;
name
------------------------------
苹果智元咨询北京有限公司
住友商社
国贸
路易·费罗(国贸店)
addidas(国贸店)
博艺府家
北京尚正明远信息技术研究中心
北京竹露桐花商贸有限公司
文心雕龙
(10 rows)
Time: 0.993 ms
```
也许需要成百上千行应用代码实现的功能,现在一行SQL就可以搞定,而且性能相当瞩目。
## 线段
### 表示道路
* 找出城市里最长的道路
* 计算城市道路里程
* 计算全国道路里程
## 多边形
### 带洞的多边形
表示复杂的地理对象,例如:工人体育馆
### 地理围栏
例如你有用户的位置轨迹数据,现在希望研究用户经过了哪些商圈。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册