至此,你已经看到了一些可插拔子系统是如何配置的,你还简要地回顾了各种不同的提供快速匿名页面服务的解决方案。仅通过采用上述解决方案,你就可以使你的站点在性能方面(感谢memcached)和对匿名访客规模化方面(感谢Varnish)有良好的表现。然而,如今是社会化网站的天下,它们需要的是服务已登录用户。问题变得棘手起来。虽然memcached确实为你赢得一些性能,还是有很多问题需要克服。你需要退回一步,去了解网站是如何操作、存储和读取数据,所遭遇的问题,以及解决这些互相之间不太相关问题的全新解决方案。
从更高的层面看,多数网站都执行着相同的动作:收集数据(要么是用户或管理员通过浏览器表单输入的,要么是从另一个网站聚合来的),存储数据到数据库,然后再把数据显示给用户。显示和更改数据的操作通常称为创建(Create)、读取(Read)、更新(Update)和删除(Delete)四大操作,简称CRUD。一个典型的网站会使用某种SQL数据库,并在其上执行这些操作。
正如你马上将要看到的那样,对于一个网站所面临的诸多问题,SQL,特别是目前流行的各种SQL实现(包括MySQL/MariaDB/Drizzle、PostgreSQL、Oracle和微软的SQL Server),并不一定是最适用的。可是既然SQL不是最优的,为什么它却如此流行呢?同样,既然SQL如此流行和管用,另辟蹊径真的是个好主意吗?简而言之,大家一直在用这些SQL数据库,何必大惊小怪?
问得好。我们就来看看所谓的“一直”到底有多久。今天所用的大部分数据库都起源于上世纪七十年代末。确实,像MySQL或PostgreSQL这样的数据库或许并没有多少UNIREG(MySQL的祖先)、Postgres甚至INGRES(PostgreSQL的祖先)的遗留代码。就像亚伯拉罕·林肯用的斧子的传说,光荣地承载着一段家族通过使用而赋予的历史。几个世纪过去,斧柄被换了五次,斧头被换了三次。SQL数据库的设计初衷及其导致的局限性却不像更改代码一样那么容易。亚伯拉罕·林肯的斧子仍然是一把斧子。(此段中的比喻源自蒂姆·波顿电影《吸血鬼猎人林肯》——译者注。)
从这些数据库被构造的年代至今,像CUP速度、可用内存及可用磁盘空间这类因素已经增长了百万倍,磁盘速度却并未紧跟上来。并且,尽管任务也同时在增长,却没有几个增长了百万倍。最后,操作系统也变得更加复杂起来。
所有这些都意味着一些新的、以前不可想象的设计方案是必不可少的,并且具有重大意义。因为现在磁盘空间丰富而磁盘速度是制约因素,你可以把注意力集中在让数据库变得更快而不是更小。当有如此之多的廉价存储可用时,牺牲磁盘空间来获取性能看上去是个绝好的买卖。你可以假定内存能满足整个数据库,如果不能,问题由操作系统处理。这种设计方案影响的不仅仅是数据库:比方说,Varnish就引入了这些先进的编程范式,这也是它如此快的原因之一。
内存记忆
第一块个人电脑硬盘是希捷科技公司于1980年生产的ST-506(希捷科技公司,原文为“Shugart Technologies”,此处为原文错误。希捷科技的创始人虽然姓Shugart,但公司名称一直都是“Seagate Technology”,并未使用过“Shugart Technologies”这个名字。——译者注),它有5MB空间,和今天的DVD驱动器一样大,价值1500美元。所以,按1980年的美元市值计,1GB价值30万美元;按今天的美元市值计,已将近一百万。今天最快的硬盘可以存储300GB,价值不到300美元(这样1GB不到1美元),并且就像典型的笔记本电脑硬盘一样小。慢些的硬盘可大到3000GB(3TB),按照有些2TB的硬盘售价为80美元来算,当前硬盘每GB的最低价大约为0.04美分。
然而,不是每个方面的改变都如此之大:ST-506的寻道时间为170毫秒,1981年生产的ST-412的寻道时间为85毫秒,而今天一般硬盘的寻道时间为8到10毫秒,绝对最快的硬盘的寻道时间为3毫秒——连百倍的增长都不到。(寻道时间是指驱动器到达数据存储位置所耗费的时间。)一旦有的话,ST-506每秒读取半兆字节,而今天的典型硬盘则可能每秒读取一百多兆字节——速度仅提高了区区200倍。
快速闪存设备通过消除寻道时间,并让纯读取速度增加大约两倍,使得这一现状得以改善。对这些新设备来说,前面的路还很长:它们的可靠性还不能与硬盘相匹敌,而它们仍然比主要的内存要慢大约一百倍。
在1980年,64K内存对个人电脑来说是最大的,且价值400美元,这使得每兆字节价值6200美元(以1980年美元市值计)。今天,64G(100万倍)的服务器内存价值不到2000美元,这样每兆字节价值大约3美分,便宜了大约100百倍。
1980年最快的微处理器每秒运行一到两百万条指令(英特尔iAPX423,摩托罗拉68000)。今天,速度纪录高于万亿次浮点运算(IBM POWER7)——提高了一百万倍。商品化的处理器刚出现时价值200到350美元,如今仍在这个价格范围。
|
除了在磁盘空间和内存变得廉价充足之前所做的设计方案之外,SQL的基础知识也同样举足轻重。SQL基于数据表,数据表有列。比方说,你可能有一个用户资料的数据表,包含一个名字的列和一个姓氏的列,这意味着每一个用户资料将拥有一个名字和一个姓氏——每列都是精确的一个。即使只是在西方文化中,这种严格结构的不足之处也不难发现。例如,有个名叫Hillary Diane Rodham Clinton的人想要注册该怎么办呢?或是某人用他的网名作为合法名字,因此只有名字而没有姓呢?更好的存储方式是,你可能还需要一个用户名字的数据表,它有一个用户资料ID的列和一个名字的列,从而让存储任意多个你想要的名字成为可能。你马上将会看到这种方法的弊端。在Drupal 7中,你可以轻松地让一个“名字”字段变成多值文本域(multiple-value text field),不过这种作法并不漂亮,尽管Drupal把丑陋都藏起来了。
名字有上述问题大家都知道了,而要找出几乎每种数据的问题也并不难。例如,假设你在描述汽车,那么你有一个叫作汽车的数据表,并且有一个叫作马力的列,存储数字类型,一个叫作变速箱级数的列,也存储数字,一个叫作颜色的列,存储字符串。总之,汽车有一个固定马力的引擎,对吗?(哦,不一定,有的汽车既有汽油发动机又有电力发动机,它们当然有不同的马力级别,可记住,你只能输入一个数字。)对于变速箱级数,无级变速箱就不太好用数字来存储了。而对于颜色,列表是无穷尽的:两种颜色的小汽车普遍存在,还有遇热变色的喷漆可以让你的汽车变成一个变色龙。这个问题可以通过存储复杂的数据结构而非单个字符串或数字来解决。
所有这些都表明,你不能把所有数据都用SQL存储在一个单独的数据表中。可这又有什么大不了的呢?要回答这个问题,让我们来看看数据库是如何找到数据的。