从一个数据分析师的视角来对比两个关系型数据库。 0.本文是关于什么的?我在一个全球专业服务公司做数据分析师(你肯定听说过的)。我干了大概有10年。10中我处理数据、数据库软件、数据库硬件、数据库用户、数据库程序员以及数据分析方法,所以我对这些东西了解的比较多。我经常遇到对相关内容了解很少的人,虽然他们中的一部分并没有意识到这件事。 这些年里,我已经太多太多次的讨论了 PostgreSQL 和 MS SQL 的问题。IT 行业中一个知名的原则说:如果你准备不只一次的做同一件事,那就让它自动化。本文是我的自动化方法的谈话。 除非另有说明,我指的是PostgreSQL 9.3和MS SQL Server 2014,即使我的经验是在MS SQL Server 2008 R2和2012版。为了公平起见,我将比较最新版的MS SQL Server和PostgreSQL。由于微软的糟糕的文档,我不得不大量的依赖于Google、Stack Overflow以及网络上的用户。因为我对两个数据库的经验不相等,所以我知道像这样的比较不够科学严谨。不过这不是一个学者的练习题,这是现实中的比 较。我尽可能让我对于MS SQL Server的了解正确,因为我们都知道要糊弄整个互联网是不可能的。如果我发现我弄错了什么事情,我会修正的。 我将以一个数据分析师的角度来比较两个数据库。MS SQL Server可能会因为QLTP后台而踢PostgreSQL的屁股(虽然我比较怀疑),不过那些不是我这里要关注的,因为我不是一个OLTP开发者/DBA/系统管理员。 最后,右上角有一个email地址。如果你愿意的话你会用到的,我会尽可能回复的。 免责声明:本文所有观点仅代表我个人。 1. 为什么说 PostgreSQL 比 MS SQL Server 强的多
额,剧透了。本节从数据分析的角度对比这两种数据库。 1.1. 支持 CSV CSV 其实是转移结构化数据(如: 表)的一种标准方式。不论是哪一种数据库,都能用自己专有的格式,把数据导出来。以这种格式存储的数据,其他软件无法读取. 用来做备份或者复制数据还行。如果想从 X 系统, 把数据移植到 Y 系统,那问题就大了。 一个数据分析平台, 既要能读取不同系统的数据, 也要能生成其他系统能读取的分析结果. 也就是说, 要能快速, 稳定, 可重复的, 而且毫无痛苦的读写 CSV. 我再说一次:一个不能很好的处理 CSV 的数据分析平台,就是没用的累赘。 PostgresSQL对CSV的支持在业内是顶尖的。 COPY TO和 COPY FROM命令支持RFC4180(最接近官方标准的文档)中列出的所有规格,也支持很多常见的和不常见的变种和方言。 这些命令运行速度很快而且很强大。 发生一个错误时,它们会给出有帮助性的错误信息。 更重要的是,它们不会默默地损坏、误解、修改数据。 而MS SQL Server既不支持导入也不支持导出CSV文件。 很多人不相信当我告诉他们这一点时。 然后,某一次,他们自己验证了这一点。通常他们的观察是这样的:
如果你不相信,下载这个格式正确的、符合标准的UTF-8编码的CSV文件,用MS SQL Server计算文件中最后一列(共有50列)字符串的平均长度(或者是字符的数量,等等)。继续,试一下。 (你得到的答案将是 183.895。) 当然,事实上,对 PostgreSQL 来说,确定这么做非常简单。最耗费时间的地方是创建保存这些数据的且具有50个字段的数据表。微软本身似乎就很难理解CSV文件;而且打开这样的文件还会引起Access和Excel中断。 痛苦但却是事实的情况是:我了解到近期一些数据库编程人员花费大量的时间和精力编写Python代码,以实现对CSV文件的“清理”,从而让MS SQL服务器可以把这些文件的内容导入到数据库里。但是,这种处理方法不可避免的要更改实际的数据。这就像花费大量金钱购买了Photoshop,然后不 得不编写一些定制的代码来让Photoshop打开JPEG,到头来仅仅发现只是稍稍修改了图片那样让人抓狂。 1.2.人机工程值得一提的是每个数据分析平台都是图灵完备的,这大概意味着任何一个数据分析平台可以做其他数据分析平台做的任何事情。也就不存在“你可以在A软件中做X 这件事而不可以在B软件中做X这件事”。即你可以在任何软件里做任何事情-所不同是难易程度。好的工具让你要做的事情做起来非常简单;差的工具就会让你要 做的事情做起来很难。说到底就是这么回事。 (理论上来讲这一切都是正确的,然而现实中却不是这样的-例如,我了解到没有关系型数据库管理系统(RDBMS)使用3D图形。不过,任意一个关系型数据库管理系统都可以模拟GPU执行任何图形计算。)
诸如此类例子还有很多. 这些问题, 分来开看, 好像没什么. 可是放到一起, 问题就大了. 想要在 MS SQL Server 上面做好一件事, 要比在 PostgreSQL 做的难度大的多. 数据分析师把许多宝贵的时间和精力都花在, 解决各种问题, 手工处理的过程中, 而不是解决真正需要解决的问题. 更正: 有人跟我说, MS SQL Server 有个优势, 是 PostgreSQL 不具备的. 那就是在 SQL 脚本中声明变量. 如:
PostgreSQL 确实不能声明变量. 真心希望它能加上这个实用的功能. 你能够在Linux,BSD等平台上运行PostgreSQL(当然,在Windows上也可以)IT行业的开发人员都清楚跨平台是当今一个关注点。支持跨平台可以说是Java杀手级的特性,其实Java是一门尚显粗糙、丑陋的编程语言,但它依然获得了巨大的成功,广泛的影响及普及。Linux与苹果的崛起使微软在桌面领域无法再保持垄断地位。云服务的灵活性和高性能虚拟化技术的易访问性,使IT基础设施越来越多样化。跨平台软件能够提供给用户控制他们的基础设施。(工作中,我目前管理着好几个PostgreSQL 数据库,一些运行在Windows平台上,一些在Ubuntu Linux上。我和同事自由地在这些平台之间移动代码和数据库数据。我们使用Python和PHP,因为他们在两种操作系统上都能运行。它们全部运行得很好。) 微软的政策一直都是供应商锁定。 他们不开放自己的代码;他们不提供跨平台版本的软件;他们甚至自己创造一个完整的生态系统,.NET设计用于为微软用户和非微软用户搭建了一座桥梁。 这对他们是有利的,因为这种方式保证了他们的利润。 这对你(用户)是不利的,因为微软限制了你的选择,而且为你创建了一些不必要的工作。 这不是一篇对比 Linux和 Windows的文档,尽管我确定我最后会提到几点。 可以肯定地说,对于真正的 IT工作, Linux(和类 UNIX操作系统家族: Solaris, BSD等)把 Windows甩出几条街。 类 UNIX操作系统主宰着服务器市场、云服务、超级计算(在这个领域它近乎垄断)和科学计算,一个原因就是 - 这些系统是技术人员为技术人员设计的。 最终,他们以巨大的力量和灵活性换得了用户友好性。 一个合格的类 UNIX OS 不仅仅是一个漂亮的命令行集合 – 它是一个包含各种程序、实用工具、功能的生态系统,并且提供支持使完成工作变得高效和有趣。 一个合格的 Linux黑客可以用一行被抛弃的 Bash脚本达到目的,但是这个任务在 Windows中是艰巨且耗时的。 (例如,某一天,我在查看朋友影片收集情况,他对我说,他认为他的文件系统中文件的总数量太多,他想知道究竟有多少影片文件,还想知道他是否可还以把一个大型的文件夹结构复制到影片文件夹下。我使用下面语句对每个文件夹及其子文件夹所包含文件数进行了计算:
整件事情做下来编写花了一分钟,运行花了一秒钟。同时还证实某些文件夹有问题,并告诉他具体哪个文件夹有问题。Windows下怎么能做到这些呢?) 在做数据分析时,关系型数据管理系统(RDBMS)不可能处在真空里;它是整套工具中一部分。因此它所处的环境就非常重要。MS SQL服务器只可在Windows系统上使用,而Windows是一个很差劲的可用于分析的环境。 1.4程序语言特性这可是一个大问题。 一个“纯”字可以概括SQL,因为它只专注于它被设计的初衷,那就是关系型数据的操作和查询。如果你尝试用它做更多的分析处理的话,比如复杂的利息计算、时间序列分析以及通用算法设计,你将很快达到它的极限。SQL数据库的提供者对这些比较了解,所以几乎所有的SQL数据库都实现了某种程序语言。这就是使得数据库用户可以写命令式风格的代码以用于更复杂或繁琐的任务。 PostgreSQL的程序语言支持比较好。对它来说在一个小范围内是不可能做到公正的,不过这只是一个样本。这些程序语言的任何一个都可以用来写存储过程和函数或直接转储到一个内联执行的代码块。
MS SQL Server 内置的面向过程编程语言 (T-SQL 对 SQL 扩充的一部分) 既笨拙, 又缓慢, 各种缺点。 就如 Microsoft 自己的文档说的那样, 它有时会容易产生一些奇怪的错误和 Bug。 我还没见过哪个程序员说他喜欢 T-SQL 的。 那放到 MS SQL Server 上面用的 .NET 组件呢 ? 这种不算面向过程语言支持, 因为你不能直接向数据库引擎提交代码。要知道, 可管理性和人类工程学(ergonomics )都很重要。 直接将 Python 代码嵌入数据库查询语句中, 既简单又方便; 启动 Visual Studio, 然后管理一堆项目,复制一堆 DLL 文件 (都是在图形用户界面中处理的,不能很好的脚本化,版本控制, 自动化, 以及审查 )其实挺尴尬的,而且容易出错,扩展性又不好。总之, 这种机制在很大程度上受限于.NET 语言。 1.5支持原生正则表达式正则表达式(regexen或者regexes)对于分析工作来说就像会算术一样的基础,对于大量的文本处理任务来说它们是首选(经常是唯一选择)。不支持正则表达式的数据分析工具就像一个没有座的自行车一样,你仍然可以用它,但是充满痛苦(菊花都残了当然痛—译者加)。 PostgreSQL有开箱即用的正则表达式支持。看几个例子: 取得所有以重复数字并且紧跟元音字母开头的行:
取得某一个字段中第一个出现的单独的十六进制字符串:
将一个 字符串以空白字符分割,并且以单行的形式返回每一部分:
查找一个字符串中最少有10个字母的单词(不区分大小写):
MS SQL Server有 LIKE ,SUBSTRING,PATINDEX 等等,不过它们与恰当的正则表达式支持不具可比性(如果你对此怀疑,你可以尝试使用它们来实现上面的例子)。有第三方的库可用于MS SQL Server,它们不像PostgreSQL的支持那样好,并且获取和安装它们会增进管理开销。 还要注意到PostgreSQL的支持扩展程序语言特性也让你有好几个其他的正则表达式引擎可用,当然也包括它们的各种特性。比如Python的正则库提供的对正向和负向后行断言的支持。这正符合PostgreSQL的一贯作风,给你干好工作的所有你需要的工具。 1.6自定义聚合函数这是一个PostgreSQL和MS SQL Server两者都提供的一个技术上的特性。不过,在实现上却有巨大的不同。 在PostgreSQL中,自定义聚合很方便并且使用简单,产生了可以快速解决问题和可维护的代码:
简单吧?自定义的聚集函数主要关注的是内部的状态和我们输入新值给这个聚集函数时修改这个状态的方法。在这个例子里,我们假设一开始每个客户的余额为零,而且累计利息也为零,接着我们每天适当地进行利息累计,并对每天的支付和撤消记账。在每个月的1号,我们进行利息复合。注意:这个聚集函数接纳 顺带说明一下,上面的第二个链接里的例子实现了简单的字符串连接聚集。注意:实现如此简单的功能需要大量的代码和技巧(而PostgreSQL内部提供了此功能,随拿随用。这可能是因为这个功能有用!)MS SQL服务器还禁止在聚集函数里指定排序,使用这样的函数无法完成我现在要完成的任务-在MS SQL服务器里,字符串连接的顺序是随机的,因此使用这个函数查询的结果就是无法确定的(即每次运行结果都可能不同),而且这样的代码也不会通过质量审查的。 缺乏排序支持还可能使得以前编写的代码无法运行,比如上面计算利息的例子。正如我所说,你无法通过使用MS SQL服务器自定义的聚集函数完成当前的任务。 (实际上,可以让MS SQL服务器使用纯SQL语句实现结果可以确定的字符串连接聚集,不过,你需要多次使用 1.7Unicode 支持ASCII一统江湖的日子已经一去不复返了,“字符(character)”和“字节(byte)”是可互换的以及“外国(foreign)”(从Anglocentric观点来看)文本是具有异国情调的异常。合适的国际语言支持不再是可选项。 所有问题的解决方案是Unicode。外面有许多对Unicode的误解。它不是一个字符集,不是一个代码页,不是一个文件格式,并且它和加密也没有任何关系。探索Unicode是如何工作的很让人着迷的事,但是这个超出了本文的范围,我打心底里推荐你Google它并且试试几个例子。 Unicode对应的重要的数据库功能如下:
PostgresSQL支持 UTF-8 。默认情况下,它的 CHAR 、 VARCHAR 、 TEXT 类型采用 UTF-8 格式,这意味着这些类型仅接受 UTF-8 数据和适用于 UTF-8 格式的所有转换,从字符串级联到使用正则表达式搜索,这些都是显示的 UTF-8 格式。上面这些都是有效的。 MS SQL Server 2008 不支持 UTF-16;但它支持 UCS-2 -- UTF-16 的一个过时的子集(a deprecated subset)。多数情况下,不会有问题. 但是, 偶尔会损坏数据。因为,它把文本当成宽字符(如 2 个字节)处理,所以遇到 UTF-16 的 4-字节字符时,会毫不犹豫地切掉一半。轻者,数据损坏。严重的时候,会导致你的工具链中某些东西出现问题,后果非常严重。那些替微软辩护的人会立刻反驳:这是不可能的。因为,在 Unicode 的基本多文平面(basic multilingual plane)外面,还包含其他东西。这种说法实在是荒谬。数据库就是用来存储,读取和修改数据而已。 一个数据库,如果因为存入错误的数据而出问题,那不是跟下载错误的文件会导致路由器崩溃一样荒唐? 2012年后MS SQL Server版本都支持UTF-16,如果你确定你为数据库设置了兼容UTF-16的校验规则。 这在2012年后的版本中是一个莫名其妙的功能。不过,迟到总比不到好。 1.8. 可以正常使用的数据类型一个普遍误解的概念是所有的数据库有相同的数据类型 – INT、 CHAR、 DATE等等。 不是这样的。 PostgresSQL的数据类型系统非常有用、直观、没有 bug或效率低下的烦恼,显然数据类型的设计使用生产效率为核心。 相比之下,MS SQL服务器的类型识别系统就像是Beta版的测试软件。它不具有PostgreSQL类型识别系统所具有的功能集,而且由于诸多陷阱使得用户异常困惑,从而让粗心的用户掉入缺陷网中。我们仔细对比一下:
SELECT CONVERT(datetime, '2001-02-03T12:34:56.789', 126); --这条语句会生成datetime值: 2001-02-03 12:34:56:789 就是这样-你只要知道“126”是把字符串转换为某种格式的datetime的编码即可。MSDN给出与这些奇奇怪怪数字对应的表。我没有给出与PostgreSQL相同的例子,这是因为我没有找到与格式"Saturday 03 Feb 200"相对应的奇怪的数字。如果某人给出的数据含有这个日期类型,那么我猜你将不得不做一些字符串处理的工作了(很遗憾,在MS SQL服务器里几乎没有字符串处理功能。) INTERVAL
PostgreSQL:INTERVAL类型表示一个时间段,如“30微秒”或者“50年”。它也可以是负数,这看起来有些不合常理,如果你知道一个单词“以前(ago)”存在的话就不会了。PostgreSQL也知道“ago”,事实上它也接受类似‘一天前(1 day ago)’字符串作为interval值(这个值在内部用-1天的时间段表示)。interva让你有一个直观的日期计算,并且作为第一类的数据类型来存储持续时间。它们像你期望的那样准确,并且可以自由的改造和转换成任何有意义的数据,也可以由任何有意义的数据转换而来。 MS SQL Server:不支持interval数据类型。
SELECT akeys(hstore(my_array, my_array)) FROM my_table; 即把数组放入到HSTORE的键值对里,这样就会强制删除重复的项(因为不允许键重复),然后再从HSTORE中提取键就可以了。这再一次体现了PostgreSQL的功能多样性。 MS SQL服务器:不支持键值对存储。
1.9. 脚本化PostgreSQL 完全可以由命令来操作. 因为它在操作系统中就是这么用的 (Windows 操作系统是个例外). 这种方式既高效, 又安全. 如果有需要, 你甚至可以在手机上, 通过 SSH 登录服务器配置 PostgreSQL(这种事, 本人干过几次). 通过脚本, 能执行诸如: 自动部署, 性能调节, 安全, 管理 和分析任务等操作. 跟图形用户界面不一样, 脚本能被复制, 版本控制, 文档化, 自动化, 审查化(Reviewed), 批量化, 以及差异化(Diffed). 对于重要的工作来说, 文本编辑器和命令行才是王道. MS SQL Server 通过图形用户界面(GUI)操作. 就算加上 Powershell 的辅助, 我也不知道它能在多大程度上实现自动化; 如果你在 Google 上搜 MS SQL Server 的用法, 得到的答案会基本上是 "在数据库上点右键, 然后选 任务...(Tasks...)". 在速度慢或者高延时的网络连接中, 使用文本命令行的效果, 远比用图形用户界面好的多. 在写这篇文章的时候, 我正准备通过 VPN, 登录一台位于 3,500 英里外的服务器, 执行管理操作. 这里的 WiFi, 信号相当不稳定. 谢天谢地, 我用的是 Ubuntu/PostgreSQL. (真的有地球人通过图形用户界面管理服务器吗?) 1.10.很好地整合了外部语言由编程环境连接并使用PostgreSQL非常、非常简单,这是因为libpq,即PostgreSQL的外部应用程序接口(API),设计的非常完美而且文档也非常完备。这就意味着编写嵌入到PostgreSQL里的应用将非常简单方便,这也使得PostgreSQL功能更多,更适合于应用在数据分析上。我曾多次用C或者C++编写了简短的程序,它可进行PostgreSQL连接,获取数据以及对获取到的数据进行大量计算,其中用到了多线程或者特殊的CPU指令-不过不适合对数据库本身进行数据填入。我还写过这样的C程序:它使用了setuid,从而允许在PostgreSQL里以普通用户执行某些管理员才能完成的任务。快速而且简练地做到这些真的很方便。 MS SQL服务器整合的外部语言的方法各有不同。有时候你需要安装其他驱动。有时候你需要创建类来存储你所查询的数据,这种情况下就意味着你在编译时就要知道数据是什么样子。最为重要的是,它的文档让人困惑、一团糟,要做成一件事就要 耗费不必要的时间,而且非常痛苦。 1.11 文档数据分析基本上意味着你得是一个“万事通”。我们使用各种广泛的编程语言和工具。(在我的脑子里,我工作中使用的编程/脚本语言有PHP、JavaScript、Python、R、C、C++、Go、三种SQL方言、PL/PGSQL和Bash。)不要期望你可以预先学习所有你需要的东西。干好工作经常依赖于阅读文档。一个有良好文档的工具更有用,它使得分析师更高产并且完成高质量的工作。 PostgreSQL的文档非常优秀。它涵盖了所欲的东西,但是又不只是一个参考手册,其中有很多例子、提示、有用的建议和指南。如果你是一个高级程序员并且想要真正的深入,你可以很容易的阅读PostgreSQL的源代码,所有这些都是开放的并且可以自由获取。这个文档也很有幽默感: 第一个世纪开始于公元0001-01-01 00:00:00 ,虽然当时他们并不知道。这个定义在所有使用公历的国家使用。没有世纪编号为0的,直接从-1世纪跳到了1世纪。如果你对此不赞同的话,请写下你的抱怨到这个地址:罗马教廷圣彼得大教堂教皇收。 MS SQL服务器的文档都在MSDN上,而且很不友好、庞大、烦乱。由于微软是个大企业,而且其客户基本很保守、缺乏幽默感,因此这样的文档就很“适合商务”-即啰啰嗦嗦、令人厌烦和枯燥。它不但在开发日期算法的时候没有参考天主教的历史,而且还异常乏味,藏匿在不必要的分类以及炫耀式的官方术语之下,难以理解。试试这个:进入MS SQL服务器2012的 产品文档页面,试试能从这里获取一些有用的信息。或者阅读下面摘录的部分(我承诺,绝不是精心挑选的): 部分report定义就是XML格式的report定义文件的一部分。在可以通过创建report定义来创建部分report,然后在这个report里选择report项,把它们做为多个部分report单独进行发布。 是不是一开始就不知道“report"是究竟是什么? 1.12.日志记录确实有用MS SQL服务器的日志分散在几个地方-错误日志、Windows事件日志、分析器日志、代理日志和安装日志。要实现对这些日志的访问,你还需要各种级别的权限,而且还需要使用多个工具,其中一些工具是只有图形用户界面下才可以运行的。也许像Splunk这样的软件能帮助你对这些日志进行自动收集和解析。我没有试过,我也不知道别人有没有试过。有关这个问题的谷歌搜索结果得到的信息少的让人吃惊,几乎没有什么用处。 默认情况下PostgreSQL的所有日志是存储在一个地方。你可以通过更改文本文件的几个设置,让数据库记录日志记录为CSV文件(由于我们现在正在讨论的是PostgreSQL,因此这儿的CSV是正常的,而不是非正常的)。你很容易设置日志级别为任何级别:由“不记录任何日志”到“全面记录分析和调试的输出”。日志文档甚至包含CSV格式的日志文件导入的目的表的DDL语句。你还可以把日志记录到标准错误或者系统日志或者Windows事件日志里(当然,假设你正在Windows系统上运行PostgreSQL)。 日志本身即是人可阅读的,也是机器可阅读的,而且包含的数据可能是系统管理员非常关注的。谁在什么地点,什么时间登入和退出?正在执行哪一条查询语句,是由谁来执行的?他们使用了多长时间?每一次批处理里提交了多少个查询?由于数据是以非常完善的CSV格式存储的,因此在R或者PostgreSQL自身或者Python的matplotlib或者其他你喜欢的软件里,对其进行可视化和分析都非常容易。像top,iotop和iostat这些Linux应用所提供的丰富的信息远超过日志提供的信息,因此你可以非常容易、可靠地使用你可能需要的所有服务器远端测控技术。 1.13支持PostgreSQL该如何赢得这一局呢?每个人都知道大型商业公司为昂贵的旗舰企业级产品提供难以置信的技术支持,而同时免费软件则一点也没有。 当然,这都是废话。商业产品当然为支持它们的人民提供支持,因为它们花了钱的。在满足SLA条款时他们总是做到最少。在我敲这篇文章时,我知道有几个IT专家正在等待一个主要硬件供应商来帮助它们解决一个 £40,000服务器的性能问题。它们已经和供应商谈了数周时间。应供应商的要求,他们花费时间和精力来运行扩展测试和基准测试。目前,供应商的脸上混合着无能、低效和淡漠。而那个£40,000服务器正坐在那非常非常慢的运行着,它的用户每周工作70小时以试图保持进度。
每一次都发生同样的事情:最终用户混合着血、汗水、泪水、Google和熬夜将问题解决。我从未见过供应商赶来救急并将一切都搞定。 那么PostgreSQL的支持是什么样的呢?有两次我向PostgreSQL邮件列表请求帮助,在24小时内我从 Tom Lane那收到了回复。花了点时间点开链接并阅读wiki,那哥们不只是PostgreSQL的首席开发者,还是一个知名得计算机程序员。没啥说的,他的建议就是好的建议。其中一次,我问了一个关于实现跨函数调用持久内存分配的最好方法的问题,Lane用我应该学习的PostgreSQL的特性回复了我,并且给我的问题提出解决方案,另外他就我的试验性解决方案(一个C静态变量)为什么是垃圾这个问题,给我列出了一份非常好的原因清单。这种支持你是买不到的,但是你可以从热情的开源开发者社区取得支持。(⊙o⊙)哦,我有没有提到那个数据库软件,还有那些来自于广受好评的程序员的充满帮助的忠告和建议总共花费了 £0.00? 我说的支持, 是指技术上真正解决问题的支持. 有些人(一般都是那些没有过这些产品的) 一提到技术支持合同, 想到更多的是法律方面的问题 – 他们并不关心是不是会真的获得帮助. 纯粹就是想找人臭骂几句, 发泄一下. 我在这里有讨论. (如果你真的想花钱购买技术支持, PostgreSQL 有许多提供专业技术支持的机构可以选择. 跟那些以销售商业软件为主, 提供技术支持为辅的供应商不同. 这些机构提供技术支持的质量决定了他们的生死存亡. 所以这方面没什么好担心的.) 1.14灵活的,可脚本化的数据库转储我已经谈论过可脚本化,不过数据库转储是如此重要,所以他们在本文中占有一席之地。PostgreSQL的数据库转储特别灵活,采用命令行驱动方式(使得它很容易实现自动化和脚本化)并且记录良好(与PostgreSQL其他部分一样)。这使得数据库迁移、复制和备份这三种重要和吓人的任务可控、可靠和可配置。而且,备份可以以空间压缩的格式或者纯文本的SQL来处理完整的数据,两者都是人类可读并且可执行。可以备份单个表或整个数据库集群。用户可以按他喜欢的方式去做。只需要一点点工作和小心的选择几个选项,甚至可以生成一个仅有DDL纯文本的SQL语言的PostgreSQL备份,该备份可在不同的RDBMS中执行。 而MS SQL Server的备份则是以一个专有的、无记录的、不透明的二进制格式进行。 1.15可靠性无论是 PostgreSQL 还是 MS SQL Server 都不希望发生意外,不过MS SQL Server有一个奇怪的失败模式,我遇到过不止一次:它的事物日志变的巨大并且阻止了数据库正常工作。理论上日志可以被截断或删除,但是文档中对此类动作又充满了可怕的警告。 而PostgreSQL只是坐在那里并且将工作做好。在日常使用中我从来没有遇到过一次PostgreSQL数据库意外。 1.16 易于安装和更新这个有什么关系吗?当然有。基础设施的灵活性比以往任何时候都要重要,并且这个趋势只会继续下去。多年稳坐不动的胖服务器安装的日子已经一去不复返。现在全部都是关于快速、可靠、灵活的配置和跟上尖端技术。常言道,时间就是金钱。 我装过MS SQL Server几次。我已经记不清自己到底安装PostgreSQL多少次了,很可能最少有50次了。 安装MS SQL Server非常的慢。它需要下载大量数据(现在还有谁使用物理媒介进行安装?)而且臭长,只有死板的进度条说明这货还活着。如果你没有安装正确版本的.NET或者正确的Windows服务包的话,你有可能安装失败。这些都需要你的系统管理员找一整块时间来做。 安装PostgreSQL的canonical 方法是简单至只敲一条命令(从一个Linux仓库),就像这样:
这需要花费多长时间?我只是通过在云中运行一个廉价的虚拟机,然后用上面的命令安装PostgreSQL来进行测试。只花了 16秒。这是下载和安装的全部时间。 至于更新,任何软件支持的Linux repo是非常容易从repo更新补丁。因为repo很聪明,PostgreSQL不太臃肿,下载的更新和应用,都是小而快的,并且是有效的。 我不知道怎么样容易地让MS SQL Server更新。我知道,很多在生产中的MS SQL Server在某些组织的版本还是2008 R2... 1.17.构建软件捐赠模块貌似PostgreSQL这一大堆的设置还不够,它又弄了一堆叫做构建软件捐赠模块的扩展。里面有一些函数,类型以及对服务器核心设置元素不那么重要的的实用功能的库。有模糊串匹配,快速整形数组处理,外部数据库链接,密码,UUIO生成,树形数据类型和负载的库。还有一些模块甚至什么也不做,只是为了让开发者和高级用户开发自己的扩展和功能。 当然,这些扩展安装十分琐碎。比如安装fuzzystrmatch的扩展,需要这么做:
1.18. 自由与免费PostgreSQL 既自由又免费, 这两样都很重要。 首先,PostgreSQL 是个开源软件, 在授权方面很自由。也就是说,你可以随心所欲地使用和修改它。包括发布包含或基于它的软件。 不论何时, 何地, 想怎么用就怎么用。 免费包含两个重要方面。 首先, 如果你也像我一样,在大机构中就职,花公家的钱,就会牵扯到许多繁文缛节。各种繁杂手续的拖延, 耗尽精力和激情; 抵制了创新。其次, 由于 PostgreSQL 是免费的, 许多开发人员, 实验人员,黑客,学生, 发明家, 科学家等等 (基本上都是穷书生)都在使用。慢慢地发展成为一个强大的社区。来自这群精英们的支持和贡献不断增长。 结果越做越好, 创新能力越来越强, 各种问题的解决方案也越来越多。更多的时间和精力用来解决更重要的问题。 2. 反驳让我不解的是, 大家经常无视上面的论点和论据, 用一些错误的, 奇怪的, 甚至荒唐透顶的观点来反驳 PostgreSQL 。 比如: 2.1. 不是说大牌厂商更可靠么!绝对不是。这就好比说 "没人会因为购买 IBM 而被炒鱿鱼"。 搞笑的是, 如果你谷歌下, 就会发现,排在第一的是 Wikipedia 的这篇文章, 恐惧,不确定,怀疑 。 最搞的是, 里面第一个提到的就是微软。我发誓我没动过 Wikipedia 那篇文章,我看到的时候, 它就是这么写的。 在给客户提供服务的数据分析领域(client-serving data analytics),容不下半点差错。如果你因为搞砸了一份工作而损害了自己的名声,别指望软件供应商能帮你挽回。如果被起诉, 倒是有可能从他们那里得到一些赔偿, 前提是, 他们确实有错。 MS SQL Server 在技术上倒是没有什么错。他们不过是发布了一件垃圾产品,然后坦白的在文档里告诉你,这件产品有多烂。它运行起来就像最初设计时期望的那样。 问题是它的设计本来就很烂。不能因为你挑选数据库的时候, 不够尽职尽责, 就去控告微软。 就算你成功地让供应商背上黑锅,已经搞砸的工作和愤怒的客户, 是不可逆转的。他们才不管是不是 MS SQL Server's 错误地把 UTF-16 当成 UCS-2 处理, 导致在进行子字符串处理的时候,代理对(surrogate pair) 被截断。结果无法识别引起错误的关键字(incriminating keyword)。轻者,他们依然想要分析结果(也许还要给他们些折扣)。严重的,他们说你做的东西不能用,直接不要了。当他们的文档没有半点歉意的告诉你,你的数据可能会被悄无声息的破坏掉,而你却把全部的希望都寄托在他们的数据库上。一旦出问题, 你觉得你能怪他们吗? 降低风险的最好办法就是把事做对。优秀的工具能帮你轻松做到这一点。优秀的工具, 我指的是 PostgreSQL 啦。 2.2 不过,如果PostgreSQL的作者挂了怎么办?假如MS SQL Server的作者同样屎掉了会发生什么——结果是一点事没有。当然了,没啥说的“PostgreSQL的作者”和“MS SQL Server作者”一样毫无意义。根本就没有这回事。 有个前辈,是一个IT基础设施监管人到是问过我这个问题(是关于Hadoop,不是PostgreSQL)。大家好像对所有的开源软件的认识都有误区,就好像这些软件是躲在妈妈的地下室的独行侠写的一样。这显然不是真的。大型开源项目如PostgreSQL和Hadoop是由拥有高级技能的开发者团队所写,他们经常受到商业赞助。在它们的核心,PostgreSQL的开发模式就像MS SQL Server的开发模式一样:有某个组织向一个大型程序员团队支付报酬。不会有单点失效的问题。 但是两者至少有一个重要的差异: PostgresSQL的源码是开放的,因此大批高级程序员能够进行代码走查、代码优化、贡献代码、提高代码的质量并理解代码的逻辑。 这是PostgresSQL为什么比MS SQL Server更好的一个原因。 关键一点,由于开源软件往往由那些非常关心代码质量的人编写(经常是由于他们打赌他们可以保证软件尽可能好用),因此软件开发通常采用最高的标准( PostgreSQL, Linux, MySQL, XBMC, Hadoop, Android, VLC, Neo4JS, Redis, 7Zip, FreeBSD, golang, PHP, Python, R, Nginx, Apache, node.js, Chrome, Firefox...)。 另一方面,商业软件通常由某一委员会设计,在公司的格子间里开发,并且编码的时候通常没有适当的指导和灵感( Microsoft BOB, RealPlayer, Internet Explorer 6, iOS Maps, Lotus Notes, Windows ME, Windows Vista, QuickTime, SharePoint...)。 2.3 但是开源软件不安全、不稳定、不值得信任、不适用于企业级生产等等!这些东西都没法说。说这些的人都是些很无知的人,你应该忽视他们,或者你自我认为很大方,你可以教育教育他们。好吧,我认为我是一个大方的人: 安全:一个旧的误解是闭源软件更安全,我会简要总结几个好的原因(读一读这个链接吧,很棒):保密不意味着安全;开源审查相比闭源来说更有可能找到弱点;正确的审查开源软件很难或不可能在其中构建一个后门。如果你喜欢轶事、逻辑论证什么的,想想Microsoft Internet Explorer 6,一个曾经的企业级闭源商业软件,被广泛的认为是有史以来最不安全的软件。Rijndael算法,作为AES背后的算法,世界上的政府用来保护顶级秘密信息,是一个开放标准。在任何案例中,关系型数据库不是安全软件。在IT世界里,“安全”有点像美国的“支持我们的军队(support our troops)”,或纸牌中的王牌“想想孩子(think of the children)”,它可以否决其他所有,包括常识和证据。注意别上当。
2.4. 可是 MS SQL Server 能利用多个 CPU 内核处理单条查询!当你的查询语句运行时, 性能受限于 CPU 而不是 IO,那么 MS SQL Server 就比较有优势。但是在现实的数据分析中, 这种情况几百年也难得见一回。当这种少见,又特殊的情况使得 CPU 变成性能瓶颈的时候。依靠数据库系统是解决不了问题的。他们又不擅长数字密集运算。 当服务器需要同时处理多个任务的时候(服务器基本上都这样) MS SQL Server 就没有什么优势了。PostgreSQL 用的是多进程模式 -- 一个进程负责处理一个数据库链接,也就是说,它也用了多个 CPU 内核。当然, 具体怎么分配, 那是操作系统的事。 我怀疑,MS SQL Server 的自定义聚集程序集(custom aggregate assemblies) 用的也是这种并行查询机制。把聚集操作分配到多个线程中计算, 然后再将结果合并到一起,有点类似 MapReduce 的作风。 我还怀疑, 这就是为什么MS SQL Server 的聚集语句不能使用 ORDER BY 子句的原因。所以, 恭喜,PostgreSQL 也是可以利用多个 CPU 内核的。只是你不能使用基本字符串汇总(basic string roll-up)。 2.5. 我只会 MS SQL Server , 没用过 PostgreSQL!如果你宁愿继续使用那个臃肿, 笨拙, 不稳定的系统, 也不愿意花点时间, 学一门稍微有些区别, 但是又比较简单查的询语言. 那就求神拜佛, 别在下次面试的时候遇到我. 2.6. 难道数以亿计的 Microsoft 用户都错了?!这是以前和我一起工作过的一名资深的数据分析师问的问题. 我的回答是 "这世上有 1.5 亿 穆斯林教徒, 1.2 亿 天主教徒. 不见得他们全都对". 所以, 就算一亿个人都错了, 也没什么奇怪的. (这里指的是 2.7 亿个人都错了.) 2.7. 真要这么好, 怎么可能会免费!大家都喜欢这么说。 真是替他们感到可惜, 因为他们无法说服别人不为钱做事。 就当他们不知道,这世上还有慈善机构, 自愿者,和其他纯粹就是做点贡献的人存在好了。 这个观点, 还建立在另外一个荒唐的假设上--开源软件开发无利可图。 大型企业开之所以开放源代码,花钱请人开发和维护这些代码, 无非是能从中收益。设想下,如果你把代码开源给他人使用,别人就会给你软件免费修改 Bug,添加新功能, 审查代码,测试, 甚至宣传。如果你的产品做的足够好, 用的人也就会越来越多,自然就会形成被业界广为接受的标准。作为支持和发布该软件的供应商,你当然会在市场上占据相当有利的地位。 就算你是个利己主义者, 开源也是个明智的选择。比如说,我现在就自己花钱做网站,替 PostgreSQL 做宣传。可能 Teradata 或 Oracle 也不错。但是他们太贵了, 我用不起, 所以也就没有给他们宣传。 2.8 但是你存在偏见!好吧,我确实偏向于更好的数据库。本文的目的是演示,用事实说话。偏见是有理由的,或者更确切的说,这根本不是偏见,而是偏好。在任何案例中,PostgreSQL都是免费软件,所以我没有经济上的动机。我也没有给它写过什么(除了我提交过一次bug修复),所以这也不是我个人的问题。并且和我关系近的人中也没有一个参与PostgreSQL的开发与支持。我只是想用好的工具来把我的工作尽可能的干好。为什么会有如此多的疑问呢?? 2.9. 但是“PostgreSQL"是个愚蠢的名字!这是可以证明的;它相当的尴尬。容易发错音并且也经常被不正确的大写书写。人们选择工业软件时对”二逼名字“不格外顾虑倒不妨它是一份干得漂亮的活。 尽管如此,对SQL服务器来说,MS SQL Server是微软选择的所有可能名字中最没劲的一个。无论哪个词都有6到8个音节,这取决于你是否将"Microsoft"缩写和你是否将它念做“sequel"或"ess queue ell",一个产品的名字这也太长了点。虽然微软有一个非常非常长名字的产品-或许这是它一直以来最伟大的成就来了 Microsoft® WinFX™ Software Development Kit for Microsoft® Pre-Release Windows Operating System Code-Named "Longhorn", Beta 1 Web Setup 我数了数有38个音节。哇靠。 2.10.但是SSMS比PGAdmin要好点!它更流畅,必须的嘛。它也更好。它有代码自动完成功能—虽然我总是把这个功能关掉因为这个功能总是坏我事—而且每次它让我走出段名或表名的困局的时候,至少有一件它做的好的事,例如自动-”纠正“一个普通的SQL关键词”table"为一个微软的奇怪的玩意“TABULATION_NONTRIVIAL_DISCOMBOBULATED_MACHIAVELLIAN_GANGLYON_ID”或别的什么东西 事实上中止SQL并且看看GUI中的结果,PGAdmin很不错。它只是不华丽而已。 还有另外一个东西:psql。它是PostgreSQL的命令行SQL接口。它是真的真的非常好。它有大量有用的目录查询功能。它可以聪明的显示扁平化的数据。它还有tab键补齐功能,不像SSMS的代码补齐哪有,它确实有用,因为它是根据上下文感知的。打个比方,如果你键入 DROP SCHEMA t 并且按下tab键,它将会给你提供名称以“t”开头的schema(如果只有一个的话,就会自动补齐)。它也可以让你在文件系统中来回跳转,也可以使用像内联的vim那样特别强大的文本编辑器。它自动保留了已执行命令的列表。它还提供了方便的有用的数据导入导出功能,包括"COPY TO PROGRAM"这样的特性,利用管道和命令行提供了另一个级别的灵活性和数据控制能力。它灵活的使用屏幕空间。快速并且方便。你能够通过一个SSH链接甚至是较慢的链接来使用它。 唯一严重的问题是,对于那些害怕命令行和敲键盘,还想成为数据分析师的人来说有点不合适。 2.11MS SQL Server可以直接从Excel导入!是的。那又怎样?Excel可以输出到CSV文件(比较难得的是,微软Excel的CSV导出代码工作的挺好),PostgreSQL可以从CSV导入。当然了,多了一步。在分析平台中,能够直接从Excel导入是一个很重要的特性吗? 2.12PostgreSQL比MS SQL Server要慢!更确切的说应该是“MS SQL Server稍微更宽容,如果你不知道你在做什么的话”。 对于某些操作,PostgreSQL确实要比MS SQL Server慢,最简单的例子可能就是COUNT(*)了,在MS SQL Server中就是一瞬间的事(我是这么想的),在PostgreSQL中就需要全表扫描(这是由于它们使用的是不同的并发模型)。PostgreSQL是一个慢开箱即用产品,因为它默认配置是使用少量系统资源,不过对于任一系统都已经被调整用于处理大量工作,所以天生的开箱即用性能不是一个值得争论的事情。 我曾经看到过PostgreSQL因为慢而被批评,因为它在一个大型表中需要花很长时间来做一些巨大的、复杂的正则表达式操作。不过每个人都知道,正则表达式操作是一种非常昂贵的计算。在任一案例中,PostgreSQL的什么被用来做比较呢?当然不是MS SQL Server了,因为它做不了正则操作。 PostgreSQL支持非常聪明的索引操作,比如范围型索引和trigram索引,对于某一类操作来说比MS SQL Server有数量级的速度。不过只有你知道如何合适的使用这些特性才行。 你从最伟大的程序语言那里得到了巨大的灵活性支持,并且聪明的数据类型允许面向基于PostgreSQL的解决方案,它胜过基于MS SQL Server的解决方案好几个数量级。 查看我更早的例子。 无论如何,关于速度的争论不仅仅限于计算机的时间(执行时间); 开发人员的时间也是一样。 这就是为什么像PHP或者Python这么流行的原因, 尽管实际上C的执行速度比他们快。 虽然他们运行慢,但是他们开发更快速。 你要花一个小时编写可维护的,优雅的SQL就被允许运行一个小时, 还是花费三天写一个多bug的程序, 尽管它的工作时间只有45分钟?
|