【IT168 专稿】在过去几年中,SQL与NoSQL之间的对抗可谓你来我往,双方都希望证明自身才是适合现代需求、符合向外扩展部署的非常好的模式。而在围绕这一问题展开的诸多讨论当中,我们已经忽视了其核心问题,即SQL存在的原因以及不同模式与实施方案之间的差别。随着新兴架构的崛起,如今面临的新问题是:为什么SQL仍然顽强生存、为什么时至今日我们依然对它充满兴趣?
SQL的故事
1970年,Edgar Codd将自己对关系类逻辑的思路发表在一份论文当中,并在文中列出了数据结构及查询的相关规则。十年之后,结构化查询语言(简称SQL)开始兴起。尽管SQL并没有完全遵循Codd当初提出的规则,但它仍然成为一款总体具备关系功能的声明语言,有效帮助我们解决了日益扩展的数据总量所带来的管理难题。
在接下来的三十年中,SQL逐渐进化成一种规范的数据管理语言,这在很大程度上要归功于其底层模型与事务保障机制所具备的明确性与高性能。在当时,大部分部署工作的主要核心在于规模扩展或者“垂直”架构,也就是说新增容量需要由更大规模的独立系统来提供。不出所料,这也是大部分SQL实施方案所采取的设计思路。
“NoSQL”这一术语诞生于1998年,当时的它还只是一套提供关系逻辑但回避了SQL的数据库方案。直到2009年,这个名词才真正迎来腾飞并彻底脱离了“非ACID”这层单纯的含义。自那时起,典型部署任务开始逐渐转为scale-out或者“横向”模式。回顾当时的情景,由于SQL无法提供scale-out能力,因此新型非SQL编程模型才开始成为人们的首选。
快到2013年,经过一段时间的下滑、SQL如今开始重新凭借NewSQL实施方案再次汇聚人气。可以说,SQL从来没有真正失去人气(市场估值约为300亿美元且仍在上涨),它只是变换了一种风格。无论如何,目前的新生代系统正回顾过往的四十年历程并意识到关系逻辑在scale-out部署需求中带来的巨大力量。
为什么会选择SQL?
SQL在解决具体总量的过程中一步步演变成了一种语言。关系模式的建立目的在于捕捉现实世界中的数据流。当采购操作发生时,它会将特定客户与产品关联起来。当某首歌曲进行播放时,歌曲本身将与专辑、艺术家以及风格流派等信息实现对接。通过定义这些关系,程序员们能够掌握数据的工作方式,系统也能了解如何对此类查询进行优化。当这些关系被确立之后,其它数据使用形式(例如审计以及治理等)就会变得更加便捷。
位于模式之上的是事务层。事务本身具备明确界限,从而保证程序员以数据库一致性视角出发将不同事务加以分别执行、同时在两项事务的变化存在彼此冲突时提供清晰的活动轨迹。这也就是ACID当中的A(原子性)、C(一致性)以及I(隔离性)。当说到一项事务已经提交完成,这意味着其同时符合以上几项规则,而且任何变更都以持久性(也就是ACID中的D)方式完成。
事务的引入代表着一种简化趋势。事务帮助开发人员避免把太多精力耗费在思考并发访问、锁定或者变更是否会被记录等总量身上。通过这种模式,一项多线程服务能够被作为单线程对象进行编程处理。这样的编程简化效果对于单独服务器而言极为重要。当扩展需要跨越一整套分布式环境时,这样的简化效果更是起到了决定性作用。
在这些固有特性的帮助下,使用SQL的开发人员能够在提升自身生产力的同时将注意力集中在应用程序方面。其中尤为重要的就是一致性。很多NoSQL系统会为了追求可扩展性而牺牲一致性,从而将负担转嫁给了应用程序开发人员。这种权衡使我们能够更轻松地创建一套对外规模数据库,但却往往会让开发人员陷于规模与事务一致性的两难选择当中。
为什么不选择SQL?
大家肯定很自然地要问,为什么SQL会被视为一套无法与向外扩展相匹配的架构,而答案则分为几个方面。首先,传统SQL实施方案在进行横向扩展时存在总量。正因为如此,技术人员有针对性地推出了分片式、被动复制以及共享磁盘集群等几种解决办法。局限性的出现主要由于SQL当中并未直接提供针对直接磁盘交互的功能,主内存容量也存在限制。
第二大问题在于结构。很多NoSQL系统大力宣扬彻底脱离(或者仅采用受限)架构的优势。在实践中,开发人员仍然需要保证某些数据对接的有效性。这就对灵活性提出了要求,即需要一套简单高效的方式,保证在应用程序的演变过程中随之做出结构与类型变更。业界普遍认为SQL无法提供这样的灵活性,但需要再次强调,这是实施方案本身的功能性限制。当表式结构与磁盘保存形式相结合,对结构进行变更将带来相当高昂的成本;相比之下,Codd提出的逻辑则不会让column的添加与重命名产生过高成本。
最后,有些人认为SQL本身对于当今的程序员们来说是一种非常复杂的语言。尽管这一话题引发的两种结论都有些主观,但事实上SQL是一种被程序员群体所广泛使用的语言,同时也尤为众多任务处理工具的基础,例如创建、备份以及分析等等。大部分NewSQL系统都会在全面支持SQL的前提下提供更简单的语言作为分层,旨在帮助我们弥合NoSQL与SQL系统之间的技能鸿沟。二者拥有各自的效用,也都能够在现代环境中使用。然而对于大多数开发人员而言,能够在向外扩展数据库领域重复使用自己所熟悉的工具与经验意味着他们不必再艰难地从规模与一致性之间做出非黑即白的选择。
未来将向何处去?
在过去几年中,我们已经看到SQL焕发出的令人兴奋的新光芒。新近崛起的NewSQL系统既支持事务型SQL,又通过自身的原始创建架构解决了向外扩展的难题。这些系统的出现证明了,只要设计方式合理、事务与SQL同样能够实现扩展目标。举例来说,谷歌公司开发F1的理由就在于其意识到SQL正是满足并发性、一致性以及持久性需求的理想方案。F1只针对谷歌架构,但它证明SQL完全有能力实现扩展而且其编程模式在今天的数据中心内仍然有能力解决关键性问题。
不仅如此,NewSQL还显示出令人印象深刻的规模化、架构灵活性以及易用性。有趣的是,很多NoSQL及分析系统如今开始在发展路线图中引入受限事务支持或者更多查询语言,希望借此填补由ACID以及声明式编程机制所带来的空白地带。这些系统的最终发展效果还有待观察,但很明显,Codd创造的模式在经历了43年的变迁之后依然如往昔那般强大而有效。