数据存储区查询将返回零个或多个单一类别的实体。它也可以只是返回查询所得的实体的键。查询不仅可以根据条件(必须匹配实体属性的值)进行过滤,还可以根据属性值对返回的实体进行排序。查询也可以通过键来进行筛选和排序。
在传统的关系型数据库中,查询会实时地根据数据表(由开发人员决定如何对其进行存储)进行计划和执行。开发人员还可以让数据库在指定的列上创建和维护索引以提高相关查询的执行速度。
App Engine的做法与此大不相同。在App Engine中,每个查询都有一个与之对应的由数据存储区维护的索引。当应用程序执行查询时,数据存储区将会找出该查询的索引,扫描并找到第一个与之匹配的行,然后逐行返回索引中的实体,直到发现与查询不匹配的行为止。
当然了,这需要App Engine预先掌握应用程序将要执行哪个查询才行。虽然它无须预先知道具体的筛选条件,不过却需要知道查询中实体的类别、用于筛选或排序的属性、筛选器的操作符以及排列顺序等。
默认情况下,App Engine会根据各类实体的既有属性为简单查询提供一组索引。为了执行更复杂的查询,应用程序必须在其配置文件中添加索引声明。当你在本地计算机上利用App Engine SDK所提供的那个开发版Web服务器测试应用程序时,App Engine SDK会监视所执行的查询并帮你生成一份配置文件。在你上传应用程序的时候,数据存储区就会自动地为测试时执行过的每条查询生成索引,你也可以手工编辑索引配置文件。
当应用程序创建了新实体或是更新了现有实体时,数据存储区会更新相应的索引。这也就使得查询变得非常快(每个查询都是一个简单的表扫描译注1),而实体的更新操作则反之(一个小小的修改就可能会使很多表译注2都需要更新)。事实上,基于索引的查询性能并不受数据存储区中实体数量的影响,而只会受到结果集大小的影响。
索引是值得关注的,因为它们会占用空间,而且会增加实体更新操作所需的时间。我们将在第5章中详细讨论索引。
译注1: 其实这里用“索引扫描”来比喻会更加贴切(我不知道GAE中索引的具体组织形式,虽然本书有所提及,但我始终认为G公司应该不会把索引做得如此简单,毕竟系统IO的速度在那摆着)。
译注2: 这里指定的应该是“索引”或“索引表”。同上,索引和表这两个概念也不一样。
Continue reading →