你可能会问自己“为什么选择PostgreSQL?”我们有几种开源数据库可供选择(本文指的是MySQL、MariaDB和Firebird),那么PostgreSQL有哪些其他开源数据库没有的特性呢?什么?PostgreSQL号称是“世界上最先进的开源数据库”。我们将给出PostgreSQL声明的理由。本系列将带我们了解数据存储——数据模型、结构、数据类型和大小限制、数据操作和检索。PostgreSQL的数据模型不仅是关系型的,还是对象-关系型的,这使它比其他一些开源数据库(如MySQL、MariaDB和Firebird)更具优势。对象关系数据库的一个基本特征是支持用户定义的对象及其属性,包括数据类型、函数、运算符、字段和索引。这使得PostgreSQL非常灵活和健壮。除此之外,还可以创建、存储和检索复杂的数据结构。以下示例显示了标准RDBMS不支持的嵌套和复合结构。数据类型和结构PostgreSQL有一个广泛的支持数据类型列表。除了数值、浮点、字符串、布尔和你能想到的数据类型(并支持各种选项),PostgreSQL还自豪地支持uuid、货币、枚举、几何、二进制、网络地址、位串、文本搜索、xml、json、数组、复合和范围数据类型,以及一些内部对象ID和日志位置类型。公平地说,MySQL、MariaDB和Firebird都不同程度地支持上述部分数据类型,但只有PostgreSQL支持以上所有数据类型。让我们仔细看看其中的几种数据类型:网络地址类型PostgreSQL提供了用于存储不同网络地址的类型,CIDR(ClasslessInternetDomainRouting)数据类型适用于IPv4和IPv6网络地址,CIDR的一些示例:192.168.100.128/2510.1.2.3/322001:4f8:3:ba:2e0:81ff:fe22:d1f1/128::ffff:1.2.3.0/128还用于网络地址存储的是IPv4的INET数据类型和IPv6hosts,子网是可选的,MACADDR数据类型用于存储硬件识别的MAC地址,例如08-00-2b-01-02-03。MySQL和MariaDB提供了一些网络地址转换的INET函数,但没有直接提供存储网络地址的数据类型,而Firebird没有网络地址类型。多维数组因为PostgreSQL是一个对象关系数据库,数组的元素可以存储大多数现有的数据类型。数组是通过将方括号附加到使用数组类型的字段来定义的。可以指定数组大小,但不是必需的。让我们用假日野餐菜单来演示数组的使用:如果您想在传统的关系数据库中存储这样的数组,另一种解决方案是为数组值的每一行创建单独的表。几何数据正迅速成为许多应用程序的核心需求,而PostgreSQL一直支持多种几何数据类型,例如点、线、圆和多边形。路径数据类型就是其中之一。路径由一系列点组成,这些点可以是开放的(起点和终点不相连)或封闭的(起点和终点相连)。让我们用一个徒步旅行的例子作为路径,在这个例子中我的徒步旅行路线是圆形的,起点连接到终点,所以我的路径是闭环的。坐标中的括号表示闭合路径,方括号表示开放路径。PostGIS扩展增强了PostgreSQL现有的几何数据特性,例如额外的空间类型、函数、运算符和索引,它们支持位置特性以及栅格和矢量数据数据。它还提供与各种第三方开源和专有地理空间处理工具的互操作性,例如映射和渲染数据。今年1月,我们使PostGIS可用于ComposePostgreSQL部署:PostGIS适用于所有ComposePostgreSQL部署。注意在MySQL5.7.8和MariaDB5.3.3中,增加了支持OpenGIS地理信息标准的数据类型扩展。此版本的MySQL和后续的MariaDB版本提供了一种类似于PostgreSQL的便捷几何数据类型的数据类型存储。但是,在MySQL和MariaDB中,数据值在插入表之前必须使用简单的命令转换为几何格式,而Firebird目前不提供地理数据类型。JSON支持PostgreSQL的JSON支持支持SQL数据库中的非结构化数据,这在数据结构因开发需要灵活性或数据对象包含未知字段时非常有用。JSON数据类型强制执行JSON有效性检查,这允许您使用专门的JSON运算符和PostgreSQL提供的内置函数来查询和操作数据。也可以使用JSONB类型——JSON的二进制形式,它与JSON的区别在于删除了数据中的空格,以不同的顺序保存对象,优化了存储层次,只保留最后一次重复的键值。JSONB通常是首选格式,因为它需要更少的空间来存储对象,可以被索引,并且处理速度更快,因为它不需要被解析。要了解更多信息,请参阅:PostgreSQL是您的下一个JSON数据库吗?在MySQL5.7.8和MariaDB10.0.1中支持JSON对象,尽管目前这些数据库中有不同的函数和运算符支持JSON,并且它们的索引方式与PostgreSQL的JSONB不同。Firebird目前仅支持文本对象的JSON。创新的数据类型如果PostgreSQL提供的数据类型列表还不够,还可以使用CREATETYPE命令创建新的数据类型,如复合类型、枚举、范围等。下面是创建和使用一个新创建的复合类型。MySQL、MariaDB和Firebird不提供这种功能,因为它们不是面向对象的。数据大小PostgreSQL可以处理大量数据。当前大小限制如下所列:限制值最大数据库大小Unlimited最大表大小32TB最大行大小1.6TB最大字段大小1GB每个表的最大行数Unlimited每个表的最大列数250-1600,具体取决于列类型每个表的最大索引数Unlimited在Compose平台会自动扩展,因此您不必担心数据增长。但是,正如每个DBA都知道的那样,最好警惕容量限制,我们建议在创建表和索引时遵循通常的准则。相比之下,MySQL和MariaDB的行大小限制为65535字节,Firebird宣传的最大行大小为64KB,通常数据大小受操作系统文件大小的限制。因为PostgreSQL可以将表数据存储在多个小文件中,所以它可以解决这个限制-请注意,文件太多会对性能产生负面影响。然而,MySQL和MariaDB确实支持比PostgreSQL单表更多的列(最多4096列,取决于数据类型)和更大的单表大小,但在极少数情况下需要超过现有的PostgreSQL限制。数据完整性PostgreSQL无疑符合ANSI-SQL:2008,完全符合ACID(原子性、一致性、隔离性和持久性),并且以其稳定性和事务完整性而闻名。它支持主键、约束、外键、唯一约束、非空约束和其他数据完整性特性,以确保只存储有效数据。MySQL和MariaDB使用InnoDB/XtraDB存储引擎来兼容更多的SQL标准。他们现在为SQL模式提供了一个STRICT选项,它决定了使用的数据检查方法。但是,根据使用模式,插入或更新时可能会创建无效和截断的数据。目前这些数据库都不支持检查约束,还有很多外键约束的附加说明。此外,数据的完整性可能在很大程度上取决于所选的存储引擎。MySQL、MariaDB长期以来一直专注于速度和效率,而不是完整性和合规性。总结PostgreSQL可以提供很多东西。使用支持复杂结构和一组丰富的内置用户定义数据类型的对象关系模型,提供巨大的数据容量和可信的数据完整性,您可能不需要我在这里回顾的所有高级功能,但随着数据需求的发展这么快,拥有这一切无疑有明显的好处。如果PostgreSQL不能完全满足你的需求,或者你更喜欢更多的选择,那么可以看看我们在Compose平台上提供的NoSQL数据库或其他开源SQL数据库。他们每个人都有自己的优势,Compose坚信选择正确的。数据库是第一要务,有时这意味着选择多个数据库作为解决方案。准备好阅读有关PostgreSQL的更多信息了吗?刚才我们介绍了存储数据,包括数据模型、数据结构、类型、大小限制,并给出了PostgreSQL声称如此的一些原因。接下来我们将介绍数据操作和Retrieval,包括索引、虚表特性和查询能力。索引PostgreSQL提供了其他开源数据库所没有的索引功能。除了标准索引类型外,PostgreSQL还支持部分、表达式、GiST、GIN索引。我们来看看上面提到的这些特殊指标。部分索引当您只想将索引添加到表的一个子集时,您可以创建部分索引,例如列值满足特定条件的所有行。这个有益的特性可以让您保持合理的索引大小并实现提高性能和减少磁盘空间的目标。部分索引的一个关键方面是被索引的列可以不同于提供子集约束的列。例如,您可能只想为付费客户索引帐户,而不包括为内部测试创建的帐户。需要注意的是,有时MySQL的部分索引(PartialIndexes有时翻译为部分索引)术语是指将索引列值截取到一定字节数,而不是根据条件数量来限制索引行.MySQL不支持我们在这里描述的部分索引。表达式索引创建表达式索引以索引由函数预先计算的列。这些新值在查询时被索引并被视为常量,而不是每次运行查询时都需要重新计算。例如,如果你有一个网页点击日志,捕获他们收到的任何格式的URL点击,你可能想创建一个基于小写规范URL的索引(PostgreSQL区分大小写,compose.io和Compose.io将是考虑不同的结果):GIST和GINGiST(广义搜索树)允许结合B树、R树和用户定义的索引类型来创建具有高级查询功能的自定义索引。GiST用于PostGIS(自2015年1月以来我们所有PostgreSQL部署的标准)和OpenFTS(开源全文搜索引擎)。PostgreSQL还支持SP-GiST,它允许创建分区查找索引,使数据检索异常快速。GIN(GeneralizedInvertedIndex)可以索引复杂的数据类型。复杂数据类型允许您以不同方式组合其他数据类型以创建完全自定义的数据类型。查看本系列的第I部分,了解复杂数据类型的概述。创建GiST和GIN索引的语法是,CREATEINDEX..ON..USINGGIST|GIN..简单!在PostgreSQL9.5(译者注:目前处于beta2)中,将支持BRIN(BlockRangeIndex)。BRIN允许根据被索引的列将大表分成一系列范围。这意味着查询计划只需要扫描查询定义的某个范围。此外,范围索引需要的磁盘空间比标准B树索引少得多。与我们关注的其他SQL数据库相比,表达式索引正在缩小差距。MySQL5.7.6开始支持生成列(GeneratedColumn),可以作为表达式索引。对于MariaDB,从5.2版本开始支持虚拟列(VirtualColumns,也称为生成列或计算列),但只支持内置函数创建列(不能使用用户自定义函数)。从Firebird2.0版开始,支持使用计算列的表达式索引。但是,这些数据库不支持部分、GiST或GIN索引。创建索引并想分析其性能时,不要忘记阅读mySidewalk的MattBarr撰写的技术文章SimpleIndexCheckingwithPostgreSQL。虚拟表功能许多查询都需要虚拟表。我们比较的所有SQL数据库都提供一些虚拟表功能,PostgreSQL提供更多。公共表达式和递归PostgreSQL通过WITH子句支持公共表表达式(CTE)。我们在技术文章PostgreSQL–SeriesRandomandWith中演示了此功能。公用表表达式允许您在查询语句中内联创建虚拟表,逻辑表达一系列操作的顺序,比在其他地方使用子查询创建虚拟表更易读,更能保证质量。PostgreSQL中的公用表表达式可以递归使用。这个方便的功能使您可以单步执行层次结构,其中的语句重复引用自身,直到不再返回更多数据。这是一个递归公用表表达式的示例,用于标识主题类别中的层次结构、主题和父子关系:MySQL和MariaDB不使用WITH子句,因此不正式支持公用表表达式。这些数据库可以使用子查询来创建派生表,但是它们不允许递归。Firebird在这方面比MySQL和MariaDB做得更好,并且像PostgreSQL一样支持使用WITH子句的公用表表达式并提供递归。实体化视图实体化视图是PostgreSQL支持的另一个有用的虚拟表功能。物化视图就像普通视图一样表示经常使用的查询结果集,只是结果集像普通表一样存储在磁盘上。物化视图也可以被索引。与每次请求时重新生成的普通视图不同,物化视图是及时的快照。它们仅在特定时间刷新。这可以大大加快使用物化视图的查询的执行速度。与其在查询中使用普通视图或进行复杂的表连接或运行聚合函数,不如使用在磁盘上包含所需数据的物化视图可以提高效率。当您更新实体化视图中的数据时,您可以根据需要使用REFRESH命令。下面是一个生成聚合收入数据的物化视图示例:Firebird、MySQL和MariaDB不支持物化视图,但解决方法是创建一个普通表并使用存储过程或触发器更新它。查询能力PostgreSQL的查询功能非常丰富。在前面的章节中讨论了WITH子句之后,让我们看一下SELECT语句中使用的另外两个可选特性。集合查询PostgreSQL为SELECT语句之间的交互提供了UNION、INTERSECT和EXCEPT子句。UNION将第二个SELECT语句的结果附加到第一个。INTERSECT从两个SELECT语句返回行。EXCEPT返回第一个SELECT语句中但不在第二个SELECT语句中的行。让我们看一个使用EXCEPT的示例,它返回客户联系信息,除非客户在一周内收到并回复了电子邮件。MySQL、MariaDB和Firebird都支持UNION,但既不支持INTERSECT,也不支持EXCEPT。但是通过查询中的join和EXISTS条件可以获得和PostgreSQL一样的结果集。当然,这会使查询变得更加复杂。窗口函数窗口函数对于基于结果集行的子集(窗口的子集)运行聚合函数非常有用。本质上,它迭代分区中相对于当前行的所有行,运行该函数。常用函数包括ROW_NUMBER()、RANK()、DENSE_RANK()和PERCENT_RANK()。关键字OVER与PARTITIONBY和ORDERBY一起表示使用窗口函数。例如,在下面的“函数和其他”部分中,我们使用窗口函数ROW_NUMBER()OVER来确定一系列值的中位数。请注意,WINDOW子句不是必需的,但用于创建和命名窗口以帮助组织事物。Firebird、MySQL和MariaDB目前不支持窗口函数,尽管几年前在Firebird3支持计划中宣布了窗口函数。网络地址类型水平子查询的FROM子句中的关键字LATERAL可以作用于子查询,允许子查询与之前创建的其他表或虚表进行交叉引用。查询语句可以这样简化。它的工作方式是根据交叉引用表测量每一行,这意味着查询执行得更快。下面是一个例子,我们想要一个学生列表,看看他们最近是否阅读了一个面向技术的主题:MySQL、Firebird和MariaDB在这个阶段不支持横向子查询。同样,存在变通方法,但查询变得更加复杂。另一件需要注意的事情是MySQL和MariaDB不支持完全外部连接,但是使用UNIONALL的解决方法可用于组合两个表的所有行。函数等PostgreSQL提供了一组强大的内置运算符和函数,包括本系列第I部分中支持特定数据类型的运算符和函数,但您可以创建自己的运算符和函数(包括聚合函数),以及自定义存储程序和触发器。我们无法提及所有这些细节,因为要涵盖的内容太多,但我们可以看两个与函数相关的简单示例。PostgreSQL支持4种用户自定义函数:查询语言、过程语言、C语言和内部语言。每个都可以传入和返回原始类型和复杂类型。请注意,PostgreSQL中的CREATEFUNCTION命令不仅可以创建函数,还可以创建存储过程。让我们看一个示例,创建一个返回复杂类型的函数:这??是一个有用的自定义函数,用于查找数字序列中的中位数:我们用于比较的其他开源SQL数据库也允许创建您自己的函数,存储过程和触发器,但它们没有PostgreSQL提供的丰富的数据类型和自定义选项。此外,在PostgreSQL中,您可以创建自己的运算符。其他数据库不支持用户定义的运算符。语言扩展PostgreSQL有大量的语言扩展,一些分布和更多的第三方。在Compose,我们只支持受信任的PostgreSQL语言扩展,以确保您的部署安全。我们在2月重新支持PL/Perl,并在8月重新支持PL/v8,这是一种基于Javascript的过程语言。这些语言扩展具有比基于SQL的PL/pgSQL语言(也可用于Compose部署)更多的内置功能,允许您创建复杂的脚本来操作和处理服务器上的数据。总结PostgreSQL具有丰富的内置特性和大量可以定制或扩展以满足需要的方法。此外,它可靠且成熟,使其成为值得任何企业采用的数据库解决方案。即便如此,对于刚刚起步的开发项目来说,它仍然易于使用且高效。我们只介绍了PostgreSQL与其他开源SQL数据库不同的几个特性,还有很多特性没有涉及(9.5版本会带来更多)。我们希望这两篇文章能够全面概述您应该选择PostgreSQL的原因。
