<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>PostgreSQL on 个人技术随想</title>
        <link>https://www.dhao2001.com/tags/postgresql/</link>
        <description>Recent content in PostgreSQL on 个人技术随想</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh</language>
        <lastBuildDate>Mon, 23 May 2022 12:09:16 +0800</lastBuildDate><atom:link href="https://www.dhao2001.com/tags/postgresql/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>速通PostGIS地理数据分析</title>
            <link>https://www.dhao2001.com/2022/05/23/quickrun-spatial-analysis-with-postgis-geopandas/</link>
            <pubDate>Mon, 23 May 2022 12:09:16 +0800</pubDate>
            <guid>https://www.dhao2001.com/2022/05/23/quickrun-spatial-analysis-with-postgis-geopandas/</guid>
            <description>&lt;h2 id=&#34;前言&#34;&gt;&lt;a href=&#34;#%e5%89%8d%e8%a8%80&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;前言&#xA;&lt;/h2&gt;&lt;p&gt;因为一些缘故，接触了一下对空间地理数据的分析工作。忙完以后，想了想决定写下这篇文章，方便日后如有需要，可以快速查阅，也供后人参考。&lt;/p&gt;&#xA;&lt;h3 id=&#34;背景条件&#34;&gt;&lt;a href=&#34;#%e8%83%8c%e6%99%af%e6%9d%a1%e4%bb%b6&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;背景条件&#xA;&lt;/h3&gt;&lt;p&gt;我们主要是针对&lt;strong&gt;给定的&lt;/strong&gt;空间地理数据（如GeoJson，Shapefile）进行一些数据提取和分析，获得我们想要的分析结果。本文不讨论这些数据如何收集，抑或是如何编制，我们只讨论&lt;strong&gt;分析&lt;/strong&gt;方面的内容，并且也不会涉及非常深，因为&lt;strong&gt;本文重点更在于，快速介绍对地理数据进行分析的大致方法&lt;/strong&gt;，而具体的分析思路、分析流程，是各位灵感发挥的重要地方。&lt;/p&gt;&#xA;&lt;p&gt;本文会涉及到对PostgreSQL数据库的使用，建议未接触过PostgreSQL的读者自行查阅相关的基础资料。不过，假如对基本的SQL，特别是MySQL/MariaDB有基本的了解，甚至是一定的使用经验，可以参考本文的前序文章&lt;a class=&#34;link&#34; href=&#34;https://www.dhao2001.com/2022/05/23/quickrun-postgresql-from-mysql/&#34; &gt;在MySQL基础上速通PostgreSQL&lt;/a&gt;&lt;/p&gt;&#xA;&lt;!-- more --&gt;&#xA;&lt;p&gt;因为我本身不是学地理信息专业的，因此以上知识与理解是临时抱佛脚速成学得，如果本文有什么错误，还请批评指正（请发邮件给我）！多谢各位包涵。&lt;/p&gt;&#xA;&lt;h3 id=&#34;目标&#34;&gt;&lt;a href=&#34;#%e7%9b%ae%e6%a0%87&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;目标&#xA;&lt;/h3&gt;&lt;p&gt;我们的分析工作环境可能需要我们做到以下几点。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;建立一个PostgreSQL数据库（下面简称psql），并启用PostGIS&lt;/li&gt;&#xA;&lt;li&gt;将收集到的数据放到psql中&lt;/li&gt;&#xA;&lt;li&gt;使用Python对这些数据进行进一步的分析计算&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;数据库为什么选择PostgreSQL呢？可能是由于PostgreSQL中的GIS插件PostGIS比较优秀，支持比较好。&lt;/p&gt;&#xA;&lt;p&gt;而选用Python进行数据分析，是因为其提供了Numpy/Pandas/Geopandas/Scipy等十分通用的工具。如果你喜欢其他工具体系，完全可以替换，只要可以连接读取psql中的地理数据即可。这里我们以Geopandas作为主要工具。&lt;/p&gt;&#xA;&lt;h2 id=&#34;环境配置&#34;&gt;&lt;a href=&#34;#%e7%8e%af%e5%a2%83%e9%85%8d%e7%bd%ae&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;环境配置&#xA;&lt;/h2&gt;&lt;p&gt;我觉得配环境向来是浪费口舌的，但又是最重要的一环，没有配好的环境，我们什么都做不了。&lt;/p&gt;&#xA;&lt;p&gt;我们需要安装的软件有:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;PostgreSQL + PostGIS插件&lt;/li&gt;&#xA;&lt;li&gt;Python + Pandas/Numpy/Scipy/SQLAlchemy/Matplotlib模块&lt;/li&gt;&#xA;&lt;li&gt;Geopandas/Geoalchemy&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;一般来说，最上面的两项是比较容易配置的，安装就好了，有非常多的方法，PostgreSQL在Windows上有安装包，在Linux上有软件包管理器。而Python部分无论是使用Conda还是使用Pip，都非常方便。&lt;/p&gt;&#xA;&lt;p&gt;但有个例外，就是Geopandas/Geoalchemy两项。不知道是怎么回事，Conda源中Geopandas版本号比较古老，而使用&lt;code&gt;conda-forge&lt;/code&gt;渠道会把安装卡在环境依赖关系检测部分。我当时是尝试了几次都没弄出理想的效果。&lt;/p&gt;&#xA;&lt;p&gt;如果你也遇到了这样的问题，或许可以试试下面的方法：容器/Windows Subsystem of Linux&lt;/p&gt;&#xA;&lt;h3 id=&#34;独立的环境&#34;&gt;&lt;a href=&#34;#%e7%8b%ac%e7%ab%8b%e7%9a%84%e7%8e%af%e5%a2%83&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;独立的环境&#xA;&lt;/h3&gt;&lt;p&gt;实际上这个方法比较诡异，但至少是能非常顺利地使用的。&lt;/p&gt;&#xA;&lt;p&gt;我当时是无意中，看到Ubuntu的APT源中，存在&lt;code&gt;python3-geopandas&lt;/code&gt;和&lt;code&gt;python3-geoalchemy2&lt;/code&gt;两个软件包，版本号也不过时(Debian源中也有，但Debian Bullseye使用的版本号比Ubuntu 22.04的老一些)，遂直接放弃使用Conda配环境的念头，直接安装这两个软件包，运行一切正常。&lt;/p&gt;&#xA;&lt;p&gt;当然，这样的方法能不出乱子，也得益于这些软件包没有依赖特定的硬件配置或者组件版本号。如果是需要依赖某个特定版本CUDA Toolkit的软件包，或许这样会出现更大的问题。&lt;/p&gt;&#xA;&lt;p&gt;不过，这样一来，环境隔离就变成了一个需要考虑的问题。我们希望将这些环境隔离起来，万一日后发生错误，可以整个删除，而不对骨干系统造成影响。而APT安装的软件包，是全局性的。&lt;/p&gt;&#xA;&lt;p&gt;因此，我们可以通过将这部分环境，整个作为一个容器进行隔离。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;如果你主力操作系统使用的是Windows，那么可以尝试在WSL中安装Ubuntu（目前WSL可以自己手动&lt;code&gt;import&lt;/code&gt;发行版，只要空间足够，可以添加非常多个实例，作为各自隔离的子系统，即便它们是同一个发行版，这和应用商店安装的有所不同）。&lt;/li&gt;&#xA;&lt;li&gt;如果你主力操作系统使用的是Linux，那么可以试试LXC/LXD解决方案，直接运行一个Ubuntu容器。Docker应该也是不错的选择。&lt;/li&gt;&#xA;&lt;li&gt;如果你主力操作系统使用的是Mac OS X，那………我也不清楚有什么好的解决方案，毕竟我不是苹果用户，反正思路和上面的是一样的。实在不行还有虚拟机对吧。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;创建容器后，就可以直接通过APT安装&lt;code&gt;python3-geopandas&lt;/code&gt;和&lt;code&gt;python3-geoalchemy2&lt;/code&gt;，以及其他需要的Python模块。&lt;/p&gt;&#xA;&lt;p&gt;如果你喜欢使用Visual Studio Code 配合 Jupyter Notebook，那么只需要安装&lt;code&gt;python3-ipykernel&lt;/code&gt;软件包，并将Visual Studio Code连接到你的WSL或者容器中，打开工作文件夹，创建一个&lt;code&gt;.ipynb&lt;/code&gt;文件，选择内核为系统目录下的&lt;code&gt;python&lt;/code&gt;，你喜欢的工作流程就呈现在你的面前了。&lt;/p&gt;&#xA;&lt;h2 id=&#34;postgis速通&#34;&gt;&lt;a href=&#34;#postgis%e9%80%9f%e9%80%9a&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;PostGIS速通&#xA;&lt;/h2&gt;&lt;p&gt;接下来，我们试着介绍以下，如何使用PostGIS对地理数据进行查询。假设我们需要在名为&lt;code&gt;gis_test1&lt;/code&gt;的数据库上存储空间数据。&lt;/p&gt;&#xA;&lt;p&gt;顺带一提，我好像并没有接触3D形状的查询分析，我接触的都是在平面上的地理数据分析。不过，方法几乎是相同的。&lt;/p&gt;&#xA;&lt;h3 id=&#34;启用postgis&#34;&gt;&lt;a href=&#34;#%e5%90%af%e7%94%a8postgis&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;启用PostGIS&#xA;&lt;/h3&gt;&lt;p&gt;若想要在一个数据库(Database)中存储地理空间数据，则必须启用PostGIS扩展。&lt;/p&gt;&#xA;&lt;blockquote class=&#34;alert alert-warning&#34;&gt;&#xA;        &lt;div class=&#34;alert-header&#34;&gt;&#xA;            &lt;span class=&#34;alert-icon&#34;&gt;⚠️&lt;/span&gt;&#xA;            &lt;span class=&#34;alert-title&#34;&gt;警告&lt;/span&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;div class=&#34;alert-body&#34;&gt;&#xA;            &lt;p&gt;这里的数据库(Database)概念，指的是PostgreSQL服务器下,一个个相对独立的Database，并不是指整个PostgreSQL服务器实例。&lt;/p&gt;&#xA;        &lt;/div&gt;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;我们连接到目标数据库后，使用以下代码启用PostGIS。操作前请确认执行以下语句时，是否已经切换到对应的数据库。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EXTENSION&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;postgis&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;gis中的形状&#34;&gt;&lt;a href=&#34;#gis%e4%b8%ad%e7%9a%84%e5%bd%a2%e7%8a%b6&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;GIS中的形状&#xA;&lt;/h3&gt;&lt;p&gt;小学数学课上学过的，点动成线，线动成面，面动成体，在我们三维空间中都遵循着这些道理。&lt;/p&gt;&#xA;&lt;p&gt;而如果我们将目光投向真实世界平面地图，我们会发现，地图上的许多事物，可以概括为以下几种类型:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;点(&lt;em&gt;Point&lt;/em&gt;): 地图上的一个点，例如，家门口的小卖部，抑或是市内的一座医院，就是一个点&lt;/li&gt;&#xA;&lt;li&gt;线(&lt;em&gt;Linestring&lt;/em&gt;): 地图上的一条线，例如，一条没有分支的地铁线路，从头到尾就是一条线&lt;/li&gt;&#xA;&lt;li&gt;多边形(&lt;em&gt;Polygon&lt;/em&gt;): 地图上的一个多边形，例如，在中国，一个县级行政区划（市辖区、县级市、县、旗等）所管辖的区域，就是一个多边形&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;GIS中Polygon的示例 - 来自postgis.net&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;671px&#34; data-flex-grow=&#34;279&#34; height=&#34;143&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://www.dhao2001.com/2022/05/23/quickrun-spatial-analysis-with-postgis-geopandas/polygons.png&#34; width=&#34;400&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;这几种类型，正是在GIS中，对二维地图上的空间事物进行描述的基本类型。参考&lt;a class=&#34;link&#34; href=&#34;https://postgis.net/workshops/postgis-intro/geometries.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;9. Geometries — Introduction to PostGIS&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;在此之上，如果我们将多个同类型的事物，放到一起，就会得到几个集合类型(Collection)，其中几个都是以 &lt;em&gt;Multi&lt;/em&gt; 开头的&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;点集(&lt;em&gt;MultiPoint&lt;/em&gt;): 地图上的多个点，例如，市内同名连锁便利店的集合，就是一个点集&lt;/li&gt;&#xA;&lt;li&gt;线集(&lt;em&gt;MultiLineString&lt;/em&gt;): 地图上的多条线，例如，市内地铁网络的线路集合，就是一个线集&lt;/li&gt;&#xA;&lt;li&gt;多边形集(&lt;em&gt;MultiPolygon&lt;/em&gt;): 地图上的多个多边形，例如，在中国，一个地级市下属的所有县级行政区划（市辖区、县级市、县、旗等），就是多个多边形组成的集合&lt;/li&gt;&#xA;&lt;li&gt;地理集合(&lt;em&gt;GeometryCollection&lt;/em&gt;): 如你所猜想的，以上几种任意类型的集合，而且也可以包含集合类型&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;这时候一定会有人问，&lt;strong&gt;上文中为什么要将医院、便利店标记成点(&lt;em&gt;Point&lt;/em&gt;)？许多地点都有一定的尺寸、占地面积，将其抽象成点是否合适&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;参照上面参考页面:&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;Points are used to represent objects when the exact details, such as shape and size, are not important at the target scale. For example, cities on a map of the world can be described as points, while a map of a single state might represent cities as polygons.&lt;/p&gt;&#xA;&lt;p&gt;Polygons are used to represent objects whose size and shape are important. City limits, parks, building footprints or bodies of water are all commonly represented as polygons when the scale is sufficiently high to see their area. Roads and rivers can sometimes be represented as polygons.&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;省流版本: &lt;strong&gt;这取决于考察的区域范围与这些地点大小的相对关系，以及这些地点的尺寸是否会对分析结果产生影响。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;举个例子，我们如果想要在城市火车站一角，张贴一张地铁线网&lt;strong&gt;概览图&lt;/strong&gt;，那么我们可以放心地将地铁线路抽象为一条条&lt;strong&gt;线&lt;/strong&gt;，而且这些线在图中的粗细，除了影响游客的可读性外，在传达信息的准确性上，并不会带来什么负面影响。&lt;/p&gt;&#xA;&lt;p&gt;但如果，我们需要在地铁线路附近新建一栋大楼，需要向下挖掘地基，那么我们就不能用上面例子中的概览图来确定施工范围边界！毕竟一条线本身并没有粗细，在考察施工边界这样精度的问题时，这样的一条条线不能告诉我们地铁隧道具体位于何处，也不能告诉我们应该从何处向下挖掘地基。我们必须将地下的铁路隧道视为&lt;strong&gt;具有具体粗细&lt;/strong&gt;的线，也就是一个&lt;strong&gt;多边形&lt;/strong&gt;，才能在地图中准确表现出地铁隧道的位置，从而让我们准确避开地铁隧道进行施工。&lt;/p&gt;&#xA;&lt;h3 id=&#34;postgis的形状运算&#34;&gt;&lt;a href=&#34;#postgis%e7%9a%84%e5%bd%a2%e7%8a%b6%e8%bf%90%e7%ae%97&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;PostGIS的形状运算&#xA;&lt;/h3&gt;&lt;p&gt;我们定义出上述元素，自然是为了方便接下来的运算工作。&lt;/p&gt;&#xA;&lt;p&gt;通常，我们存储到数据库中的数据，常常是地图上事物的原始数据，如城市中公交车站的位置，各建筑物的具体地理边界等。然而，对于我们的分析需求来说，从数据库中读取这些原始数据往往是不够的，我们通常需要进行更复杂的运算，例如查询某个区域内公交车站的数量，或是某个区域内道路的总长度。&lt;/p&gt;&#xA;&lt;p&gt;PostGIS提供的函数可以帮助我们通过SQL语句，构造上述查询目标的SQL表达式，从而轻松从数据库中获得上述信息。&lt;/p&gt;&#xA;&lt;h3 id=&#34;形状的关系&#34;&gt;&lt;a href=&#34;#%e5%bd%a2%e7%8a%b6%e7%9a%84%e5%85%b3%e7%b3%bb&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;形状的关系&#xA;&lt;/h3&gt;&lt;p&gt;在中小学时期，我们就学习过，两个图形是否相交，如何相交，会构成不同的模式。在PostGIS中，这一问题进一步和图形的内部、边界、外部结合起来，构成了GIS系统中的九维相交模型(9-Intersection Model)。&lt;/p&gt;&#xA;&lt;p&gt;具体的解释，可以参考&lt;a class=&#34;link&#34; href=&#34;&#34; &gt;https://postgis.net/docs/manual-3.2/using_postgis_query.html&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;简单来说，我们常常涉及到的运算，其实主要以计算相交(Intersect)和包含(Contain)关系为主。而PostGIS的函数，通常以&lt;code&gt;ST_&lt;/code&gt;开头。上述链接也提供了相关的示例，可以看看。&lt;/p&gt;&#xA;&lt;p&gt;以我编写的一个SQL查询为例。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ca&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crime_area&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ST_Area&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssa2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;geometry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nei_area&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;neighbourhoods&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;SUM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ST_Area&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ST_Intersection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssa&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;geometry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bae&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;geometry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crime_area&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;neighbourhoods&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sa2_statistical_areas&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssa&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssa&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SA2_MAIN16&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;break_and_enter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bae&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ST_Intersects&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssa&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;geometry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bae&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;geometry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;GROUP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ca&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ca&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sa2_statistical_areas&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssa2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssa2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SA2_MAIN16&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;在上述查询中，我们用&lt;code&gt;ST_Intersects&lt;/code&gt;函数，计算&lt;code&gt;ssa&lt;/code&gt;表中的&lt;code&gt;geometry&lt;/code&gt;列，与&lt;code&gt;bae&lt;/code&gt;表中的&lt;code&gt;geometry&lt;/code&gt;列的交集，如果有两条记录产生了交集，则&lt;code&gt;JOIN&lt;/code&gt;条件为真，联表查询生成的结果中会多出一行。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>在MySQL基础上速通PostgreSQL</title>
            <link>https://www.dhao2001.com/2022/05/23/quickrun-postgresql-from-mysql/</link>
            <pubDate>Mon, 23 May 2022 12:09:16 +0800</pubDate>
            <guid>https://www.dhao2001.com/2022/05/23/quickrun-postgresql-from-mysql/</guid>
            <description>&lt;h2 id=&#34;前言&#34;&gt;&lt;a href=&#34;#%e5%89%8d%e8%a8%80&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;前言&#xA;&lt;/h2&gt;&lt;p&gt;因为一些缘故，接触了一下对空间地理数据的分析工作。忙完以后，想了想决定写下这篇文章，方便日后如有需要，可以快速查阅，也供后人参考。&lt;/p&gt;&#xA;&lt;h3 id=&#34;背景条件&#34;&gt;&lt;a href=&#34;#%e8%83%8c%e6%99%af%e6%9d%a1%e4%bb%b6&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;背景条件&#xA;&lt;/h3&gt;&lt;p&gt;在我的分析过程中，需要使用PostgreSQL，但我之前用MySQL/MariaDB比较多，稍微花了一点点时间适应。怕下次忘了，干脆写出来。&lt;/p&gt;&#xA;&lt;p&gt;本文还假设你已经具备了最基本的SQL，尤其是MySQL知识。有了这些基础知识，我们的适应就会非常迅速。&lt;/p&gt;&#xA;&lt;!-- more --&gt;&#xA;&lt;h2 id=&#34;postgresql速通&#34;&gt;&lt;a href=&#34;#postgresql%e9%80%9f%e9%80%9a&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;PostgreSQL速通&#xA;&lt;/h2&gt;&lt;p&gt;我们会着重介绍几个概念。&lt;/p&gt;&#xA;&lt;h3 id=&#34;数据库实例---cluster&#34;&gt;&lt;a href=&#34;#%e6%95%b0%e6%8d%ae%e5%ba%93%e5%ae%9e%e4%be%8b---cluster&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;数据库实例 - Cluster&#xA;&lt;/h3&gt;&lt;p&gt;和我们平时常说的计算集群(&lt;em&gt;Computer Cluster&lt;/em&gt;)不同，也和SQL中的聚合索引(&lt;em&gt;Clustered Index&lt;/em&gt;)不同，PostgreSQL中的Cluster，其实可以简单理解成一个数据库实例。&lt;/p&gt;&#xA;&lt;p&gt;具体来说，同一套PostgreSQL的二进制文件，可以运行多个实例(Cluster)，每个实例具有不同的数据目录，配置文件，监听不同的端口。&lt;/p&gt;&#xA;&lt;p&gt;而如果想要创建一个Cluster，使用&lt;code&gt;initdb&lt;/code&gt;命令是最简单的方法。其手册可以参考&lt;a class=&#34;link&#34; href=&#34;&#34; &gt;https://www.postgresql.org/docs/current/app-initdb.html&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;也可以参考这里&lt;a class=&#34;link&#34; href=&#34;&#34; &gt;https://www.postgresql.org/docs/current/creating-cluster.html&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;数据库初始化&#34;&gt;&lt;a href=&#34;#%e6%95%b0%e6%8d%ae%e5%ba%93%e5%88%9d%e5%a7%8b%e5%8c%96&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;数据库初始化&#xA;&lt;/h3&gt;&lt;p&gt;大部分情况下，包括Windows安装包安装，以及Debian/Ubuntu APT源中的安装包安装，都会自动为我们创建好一个可以直接使用的Cluster，我们一般不需要手动创建一个Cluster。&lt;/p&gt;&#xA;&lt;p&gt;不过，如果在Windows上使用Zip压缩包进行安装时，需要运行&lt;code&gt;initdb.exe&lt;/code&gt;，指定一个数据目录，创建一个新的Cluster。毕竟没有程序自动地帮你做这件事。&lt;/p&gt;&#xA;&lt;h3 id=&#34;用户与权限&#34;&gt;&lt;a href=&#34;#%e7%94%a8%e6%88%b7%e4%b8%8e%e6%9d%83%e9%99%90&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;用户与权限&#xA;&lt;/h3&gt;&lt;p&gt;在较新版本(&amp;gt;=8.1)的PostgreSQL中，用户和组都统称为角色(ROLE)。在我看来，区别用户和组的最大的区别，或许在于，是否给一个角色赋予登录权限。&lt;/p&gt;&#xA;&lt;p&gt;在Debian/Ubuntu系统下，当从APT源安装PostgreSQL时，会在系统中自动创建一个&lt;code&gt;postgres&lt;/code&gt;用户，这个用户可以通过Unix Socket访问到PostgreSQL默认Cluster中创建的同名超级用户。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;root@MyPC:~# sudo -u postgres -i psql&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;psql &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;14.2 &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;Ubuntu 14.2-1ubuntu1&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Type &lt;span class=&#34;s2&#34;&gt;&amp;#34;help&amp;#34;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; help.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;postgres&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;如果你需要创建其他角色，则需要具有&lt;code&gt;CREATEROLE&lt;/code&gt;权限。&lt;/p&gt;&#xA;&lt;p&gt;要创建一个可以登录的角色（下面我就简称用户啦），可以使用以下SQL语句:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ROLE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;alice&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOGIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PASSWORD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;12345&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;这会创建一个名为&lt;code&gt;alice&lt;/code&gt;的用户，赋予（通过网络）登录权限，密码为&lt;code&gt;12345&lt;/code&gt;。我们可以运行&lt;code&gt;psql&lt;/code&gt;命令登录到这一用户。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;root@MyPC:~# psql -U alice -W postgres -h localhost&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Password:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;psql &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;14.2 &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;Ubuntu 14.2-1ubuntu1&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SSL connection &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Type &lt;span class=&#34;s2&#34;&gt;&amp;#34;help&amp;#34;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; help.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;postgres&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;gt; &lt;span class=&#34;se&#34;&gt;\c&lt;/span&gt;onninfo&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;You are connected to database &lt;span class=&#34;s2&#34;&gt;&amp;#34;postgres&amp;#34;&lt;/span&gt; as user &lt;span class=&#34;s2&#34;&gt;&amp;#34;alice&amp;#34;&lt;/span&gt; on host &lt;span class=&#34;s2&#34;&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;address &lt;span class=&#34;s2&#34;&gt;&amp;#34;127.0.0.1&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; at port &lt;span class=&#34;s2&#34;&gt;&amp;#34;5432&amp;#34;&lt;/span&gt;.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SSL connection &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;如果你希望赋予这个用户一些权限，例如&lt;code&gt;CREATEDB&lt;/code&gt;, &lt;code&gt;CREATEROLE&lt;/code&gt;, 甚至是&lt;code&gt;SUPERUSER&lt;/code&gt;，都可以在上方指定。例如，我们可以在创建时指定Alice为Superuser&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ROLE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;alice&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SUPERUSER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOGIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PASSWORD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;12345&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;查看&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;root@MyPC:~# psql -U alice -W postgres -h localhost&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Password:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;psql &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;14.2 &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;Ubuntu 14.2-1ubuntu1&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SSL connection &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Type &lt;span class=&#34;s2&#34;&gt;&amp;#34;help&amp;#34;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; help.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;postgres&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# \du+&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                          List of roles&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Role name &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;                         Attributes                         &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Member of &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Description&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-----------+------------------------------------------------------------+-----------+-------------&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; alice     &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Superuser                                                  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;        &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; postgres  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Superuser, Create role, Create DB, Replication, Bypass RLS &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;        &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;postgres&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;但使用SQL语句直接创建用户的记录，会将密码明文存储在数据库的历史查询中。我们觉得这样不好。&lt;/p&gt;&#xA;&lt;p&gt;PostgreSQL提供了许多命令行工具，即便不用显式登录到&lt;code&gt;psql&lt;/code&gt;，也可以管理数据库。&lt;code&gt;createuser&lt;/code&gt;便是其中用于创建角色的工具。其文档可以参考&lt;a class=&#34;link&#34; href=&#34;&#34; &gt;https://www.postgresql.org/docs/current/sql-createrole.html&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;基于此，我们可以将上面的创建用户代码，替换成Shell指令: &lt;code&gt;createuser -l -s -e -P alice&lt;/code&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;postgres@MyPC:~$ createuser -l -s -e -P alice&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Enter password &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; new role:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Enter it again:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SELECT pg_catalog.set_config&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;search_path&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;, &lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE ROLE alice PASSWORD &lt;span class=&#34;s1&#34;&gt;&amp;#39;SCRAM-SHA-256$4096:91DfHk6BEMX4Ay7S8TsfQw==$2tGBIh4PC/ce4ThLajfvm9ZwwVzidWCorlsHuHBKhX8=:0HZpvT5kReucYmGGwKR6I1OLsaZo3aOjcSMlBI7vrfQ=&amp;#39;&lt;/span&gt; SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;这一串命令中，&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;-l&lt;/code&gt;代表赋予&lt;code&gt;LOGIN&lt;/code&gt;登录权限&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;-s&lt;/code&gt;代表赋予&lt;code&gt;SUPERUSER&lt;/code&gt;超级用户身份&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;-e&lt;/code&gt;指示该命令将最终发送给PostgreSQL服务器的SQL语句打印出来（最后2行）&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;-P&lt;/code&gt;指示命令将提示输入该新用户的密码&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;可以看到，我们发送给数据库服务器的SQL命令，已经将密码哈希处理了。&lt;/p&gt;&#xA;&lt;p&gt;当然如果你觉得这一串参数记忆复杂，也可以直接使用&lt;code&gt;--interactive&lt;/code&gt;选项，回答程序提出的一系列问题，即可创建用户。&lt;/p&gt;&#xA;&lt;h3 id=&#34;数据库--模式--数据表&#34;&gt;&lt;a href=&#34;#%e6%95%b0%e6%8d%ae%e5%ba%93--%e6%a8%a1%e5%bc%8f--%e6%95%b0%e6%8d%ae%e8%a1%a8&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;数据库 &amp;amp; 模式 &amp;amp; 数据表&#xA;&lt;/h3&gt;&lt;p&gt;这三个词分别对应着:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;数据库 - Database&lt;/li&gt;&#xA;&lt;li&gt;模式 - Schema&lt;/li&gt;&#xA;&lt;li&gt;数据表 - Table&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;数据表很好理解。但前两个常常带来争议。&lt;/p&gt;&#xA;&lt;h3 id=&#34;mysql的schema&#34;&gt;&lt;a href=&#34;#mysql%e7%9a%84schema&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;MySQL的Schema&#xA;&lt;/h3&gt;&lt;p&gt;在MySQL中，我们可以在&lt;a class=&#34;link&#34; href=&#34;https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_schema&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;MySQL :: MySQL 8.0 Reference Manual :: MySQL Glossary&lt;/a&gt;中看到这一段话:&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;In MySQL, physically, a &lt;strong&gt;schema&lt;/strong&gt; is synonymous with a &lt;strong&gt;database&lt;/strong&gt;. You can substitute the keyword &lt;code&gt;SCHEMA&lt;/code&gt; instead of &lt;code&gt;DATABASE&lt;/code&gt; in MySQL SQL syntax, for example using &lt;code&gt;CREATE SCHEMA&lt;/code&gt; instead of &lt;code&gt;CREATE DATABASE&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Some other database products draw a distinction. For example, in the Oracle Database product, a &lt;strong&gt;schema&lt;/strong&gt; represents only a part of a database: the tables and other objects owned by a single user.&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;简单来说，在MySQL中，&lt;em&gt;Database&lt;/em&gt; 等价于 &lt;em&gt;Schema&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;h3 id=&#34;postgresql的schema&#34;&gt;&lt;a href=&#34;#postgresql%e7%9a%84schema&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;PostgreSQL的Schema&#xA;&lt;/h3&gt;&lt;p&gt;但PostgreSQL不完全这么想。在&lt;a class=&#34;link&#34; href=&#34;https://www.postgresql.org/docs/current/ddl-schemas.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;PostgreSQL: Documentation: 14: 5.9. Schemas&lt;/a&gt;中，是这么说的:&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;A PostgreSQL database cluster contains one or more named databases. Roles and a few other object types are shared across the entire cluster. A client connection to the server can only access data in a single database, the one specified in the connection request.&lt;/p&gt;&#xA;&lt;p&gt;A database contains one or more named &lt;em&gt;schemas&lt;/em&gt;, which in turn contain tables. Schemas also contain other kinds of named objects, including data types, functions, and operators. The same object name can be used in different schemas without conflict; for example, both &lt;code&gt;schema1&lt;/code&gt; and &lt;code&gt;myschema&lt;/code&gt; can contain tables named &lt;code&gt;mytable&lt;/code&gt;. Unlike databases, schemas are not rigidly separated: a user can access objects in any of the schemas in the database they are connected to, if they have privileges to do so.&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;简单来说，在PostgreSQL中，一个实例(&lt;em&gt;Cluster&lt;/em&gt;)可以包含多个数据库(&lt;em&gt;Database&lt;/em&gt;)，一个数据库(&lt;em&gt;Database&lt;/em&gt;)可以包含多个模式(&lt;em&gt;Schema&lt;/em&gt;)，一个模式(&lt;em&gt;Schema&lt;/em&gt;)下面有很多表(&lt;em&gt;Table&lt;/em&gt;)，数据就存储在表(&lt;em&gt;Table&lt;/em&gt;)中。&lt;/p&gt;&#xA;&lt;h3 id=&#34;postgresql中的默认schema&#34;&gt;&lt;a href=&#34;#postgresql%e4%b8%ad%e7%9a%84%e9%bb%98%e8%ae%a4schema&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;PostgreSQL中的默认Schema&#xA;&lt;/h3&gt;&lt;p&gt;在PostgreSQL中创建一个数据库时，该数据库会默认包含一个&lt;code&gt;public&lt;/code&gt;模式。对在该数据库上执行的所有SQL语句来说，如果没有显式指定模式名称，则都会被认为是对&lt;code&gt;public&lt;/code&gt;的操作。&lt;/p&gt;&#xA;&lt;p&gt;假设数据库中存在一个名为&lt;code&gt;public&lt;/code&gt;的模式，其下有一个&lt;code&gt;mytable&lt;/code&gt;表，则以下两个SQL语句是等效的。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mytable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;或者&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mytable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;跨库查询&#34;&gt;&lt;a href=&#34;#%e8%b7%a8%e5%ba%93%e6%9f%a5%e8%af%a2&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;跨库查询&#xA;&lt;/h3&gt;&lt;p&gt;两个数据库在组织这些术语时的差异，就进一步导出了一个，非常明显，但仔细思考之下显得比较有道理的限制条件：&lt;strong&gt;MySQL允许跨数据库查询，而PostgreSQL不允许跨数据库查询。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;更进一步，PostgreSQL虽然不允许跨数据库(&lt;em&gt;Database&lt;/em&gt;)查询，但&lt;strong&gt;允许跨模式(&lt;em&gt;Schema&lt;/em&gt;)查询。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;或许是因为，PostgreSQL认为，不同数据库存储的数据，涉及到的业务内容相互间应该是没有紧密关联的（如果有紧密联系，就应该放在同一个数据库内！）&lt;/p&gt;&#xA;&lt;p&gt;因此，PostgreSQL选择，从逻辑上将数据库彼此隔离。&lt;/p&gt;&#xA;&lt;p&gt;或许，只要我们把跨数据库查询(Cross-Database Query)，改名为跨模式查询(Cross-Schema Query)，或许就变成这两个数据库都能支持的操作了呢？&lt;/p&gt;&#xA;&lt;h3 id=&#34;构建数据库的思考&#34;&gt;&lt;a href=&#34;#%e6%9e%84%e5%bb%ba%e6%95%b0%e6%8d%ae%e5%ba%93%e7%9a%84%e6%80%9d%e8%80%83&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;构建数据库的思考&#xA;&lt;/h3&gt;&lt;p&gt;紧接而来的问题是，在PostgreSQL中，我们应该如何选择数据库的构建形式？&lt;/p&gt;&#xA;&lt;p&gt;这样的问题在应用程序&lt;strong&gt;不涉及跨Schema查询时&lt;/strong&gt;会更令人举棋不定，而跨Schema查询在构建微服务时从来都不是一个建议的选择。&lt;/p&gt;&#xA;&lt;p&gt;现在考虑这两种构建形式:&lt;/p&gt;&#xA;&lt;p&gt;第一种，大致如下图所示。&lt;strong&gt;每个数据库中只有一个Schema&lt;/strong&gt;，即&lt;code&gt;public&lt;/code&gt;。使用多个数据库存储不同业务模块数据，每个数据库彼此分离。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- PostgreSQL&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|---- mydatabase1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|     |---- public&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|           |---- mytable1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|           |---- mytable1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|           |---- mytable3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|---- mydatabase2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|     |---- public&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|           |---- mytable4&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|           |---- mytable5&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|           |---- mytable6&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;第二种，大致如下图所示。&lt;strong&gt;每个数据库中使用多个Schema&lt;/strong&gt;，尽可能减少PostgreSQL服务器下，Database的数量。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- PostgreSQL&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|---- mydatabase1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      |---- myschema1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      |     |---- mytable1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      |     |---- mytable1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      |     |---- mytable3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      |&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      |---- myschema2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            |---- mytable4&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            |---- mytable5&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            |---- mytable6&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;这两种方案从实现角度都是可行，现成的。第一种方案相较于第二种方案，失去了跨库查询的能力，但提高了隔离性。&lt;/p&gt;&#xA;&lt;p&gt;这时候一定有人问：&lt;strong&gt;性能如何？&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;目前似乎在网上暂时搜不到这两种方案性能差异的对比。StackOverflow上2009年的&lt;a class=&#34;link&#34; href=&#34;https://stackoverflow.com/questions/1152405/is-it-better-to-use-multiple-databases-with-one-schema-each-or-one-database-wit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;帖子&lt;/a&gt;里，有人曾经引用&lt;a class=&#34;link&#34; href=&#34;https://devcenter.heroku.com/articles/heroku-postgresql&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Heroku PostgreSQL&lt;/a&gt;上的文档，认为 &lt;em&gt;一个数据库内多个Schema(One Database - Many Schema)&lt;/em&gt; 的方案会严重拖累服务器性能，但似乎目前在该文档中已经找不到这一段文字，且实际上也没有给出两个方案具体的性能差异。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;因此我更倾向于认为，两者在性能上不会有天差地别的影响。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;blockquote class=&#34;alert alert-note&#34;&gt;&#xA;        &lt;div class=&#34;alert-header&#34;&gt;&#xA;            &lt;span class=&#34;alert-icon&#34;&gt;📝&lt;/span&gt;&#xA;            &lt;span class=&#34;alert-title&#34;&gt;备注&lt;/span&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;div class=&#34;alert-body&#34;&gt;&#xA;            &lt;p&gt;当数据越来越多时候，数据库的效率会自然下降。或许考虑其他方法，如分表，索引等手段加快性能，收益会更为明显。&lt;/p&gt;&#xA;        &lt;/div&gt;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;至于选择，我个人认为，第一种方案，即 &lt;em&gt;One Database - One Schema&lt;/em&gt; 会更方便我们管理数据库的权限，我更倾向采用这种方案。&lt;/p&gt;&#xA;&lt;h3 id=&#34;命名规则&#34;&gt;&lt;a href=&#34;#%e5%91%bd%e5%90%8d%e8%a7%84%e5%88%99&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;命名规则&#xA;&lt;/h3&gt;&lt;p&gt;虽然PostgreSQL的命名规则并不离经叛道，但我个人并&lt;strong&gt;不建议在数据库名、模式名、表名、字段名中使用大写字母！&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;因为，在PostgreSQL中，如果上述名字含有大写字母，需要将这一部分用双引号包起来！&lt;/p&gt;&#xA;&lt;blockquote class=&#34;alert alert-important&#34;&gt;&#xA;        &lt;div class=&#34;alert-header&#34;&gt;&#xA;            &lt;span class=&#34;alert-icon&#34;&gt;📌&lt;/span&gt;&#xA;            &lt;span class=&#34;alert-title&#34;&gt;重要&lt;/span&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;div class=&#34;alert-body&#34;&gt;&#xA;            &lt;p&gt;&lt;strong&gt;逃课方法: 使用GUI数据库管理工具，如DBeaver、Beekeeper Studio等。&lt;/strong&gt; 可以直接无视此部分问题。生成SQL语句复制粘贴即可。&lt;/p&gt;&#xA;        &lt;/div&gt;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;例如，如果我们创建一个数据表如下所示。注意到&lt;code&gt;Name&lt;/code&gt;字段包含了大写字母。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TABLE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mytb1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;integer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;NOT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;GENERATED&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DEFAULT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IDENTITY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;varchar&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CONSTRAINT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mytb1_pk&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;PRIMARY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;KEY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;插入一些数据&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mytb1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VALUES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Bob&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mytb1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VALUES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Cindy&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;执行简单的查询&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mytest1=# SELECT * FROM mytb1;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; id | Name&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;----+-------&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  1 | Bob&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  2 | Cindy&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(2 rows)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;如果我们在语句中，包含对&lt;code&gt;Name&lt;/code&gt;的操作但没有将其用双引号包围，会出现错误&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mytest1=# SELECT * FROM mytb1 WHERE Name = &amp;#39;Cindy&amp;#39;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ERROR:  column &amp;#34;name&amp;#34; does not exist&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;LINE 1: SELECT * FROM mytb1 WHERE Name = &amp;#39;Cindy&amp;#39;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                  ^&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;HINT:  Perhaps you meant to reference the column &amp;#34;mytb1.Name&amp;#34;.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;稍作修改，给&lt;code&gt;Name&lt;/code&gt;加上双引号，就可以正常工作&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mytest1=# SELECT * FROM mytb1 WHERE &amp;#34;Name&amp;#34; = &amp;#39;Cindy&amp;#39;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; id | Name&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;----+-------&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  2 | Cindy&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(1 row)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;如果你在查询时，总是找不到对应的关系，不妨检查一下有没有遗漏双引号。&lt;/p&gt;&#xA;&lt;h3 id=&#34;数据类型&#34;&gt;&lt;a href=&#34;#%e6%95%b0%e6%8d%ae%e7%b1%bb%e5%9e%8b&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;数据类型&#xA;&lt;/h3&gt;&lt;p&gt;PostgreSQL的数据类型也没啥特别的。不过，根据SQL规范，整型的名称默认应该是&lt;code&gt;integer&lt;/code&gt;，因此从MySQL迁移过来时需要稍微注意。&lt;/p&gt;&#xA;&lt;p&gt;另外值得一提的还有自动增长类型的功能。在PostgreSQL中，自动增长常用&lt;em&gt;Identity&lt;/em&gt;指代。注意，另有一种实现方法是通过&lt;em&gt;serial&lt;/em&gt;实现，但这似乎是旧的方法，推荐采用&lt;em&gt;Identity&lt;/em&gt;的方法。&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;Identity&lt;/em&gt; 有两种模式，即&lt;code&gt;BY DEFAULT&lt;/code&gt;和&lt;code&gt;ALWAYS&lt;/code&gt;。它们的区别在&lt;a class=&#34;link&#34; href=&#34;https://www.postgresql.org/docs/current/sql-createtable.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;PostgreSQL: Documentation: 14: CREATE TABLE&lt;/a&gt;中有说明:&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;The clauses ALWAYS and BY DEFAULT determine how explicitly user-specified values are handled in INSERT and UPDATE commands.&lt;/p&gt;&#xA;&lt;p&gt;In an INSERT command, if ALWAYS is selected, a user-specified value is only accepted if the INSERT statement specifies OVERRIDING SYSTEM VALUE. If BY DEFAULT is selected, then the user-specified value takes precedence. See INSERT for details. (In the COPY command, user-specified values are always used regardless of this setting.)&lt;/p&gt;&#xA;&lt;p&gt;In an UPDATE command, if ALWAYS is selected, any update of the column to any value other than DEFAULT will be rejected. If BY DEFAULT is selected, the column can be updated normally. (There is no OVERRIDING clause for the UPDATE command.)&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;省流: &lt;code&gt;ALWAYS&lt;/code&gt;在接受用户对数据表中，该自增序列作插入或修改时，条件比&lt;code&gt;BY DEFAULT&lt;/code&gt;更严苛。&lt;/p&gt;&#xA;&lt;blockquote class=&#34;alert alert-warning&#34;&gt;&#xA;        &lt;div class=&#34;alert-header&#34;&gt;&#xA;            &lt;span class=&#34;alert-icon&#34;&gt;⚠️&lt;/span&gt;&#xA;            &lt;span class=&#34;alert-title&#34;&gt;警告&lt;/span&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;div class=&#34;alert-body&#34;&gt;&#xA;            &lt;p&gt;&lt;code&gt;BY DEFAULT&lt;/code&gt;比较听用户的话，&lt;code&gt;ALWAYS&lt;/code&gt;有自己的执着。&lt;/p&gt;&#xA;        &lt;/div&gt;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;如果你之前有使用其他SQL的经验，上面的内容足够让你开心地在PostgreSQL上执行一系列查询了。&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
