作用和代价
上文介绍了关系型数据库里的索引。Notes数据库里的索引隐藏在视图概念里(本文的讨论只针对Notes的视图索引,不包含全文索引。)。开发人员创建的视图仅仅是存放在数据库里的一条设计文档,数据库引擎会依据它创建和更新索引。关系型数据库里的索引是从记录中抽取的数据排序而组成的数据结构(主要是B树),Notes视图的索引还包括未排序的列、计算值、分类、总计等等数据(数据结构仍然是B树,如果运气足够好的话,你会遇到Notes报出B-tree structure is invalid的错误)。用户在客户端里看到的视图就是索引的数据,再加上外观的设置。这样的区别缘于两类数据库底层设计的差异。
关系型数据库里的索引是为了查询而建的。SELECT NAME, JOB FROM PERSON WHERE COUNTRY='China'这样一个简单的查询语句,会因为PERSON表的COUNTRY列建有索引而大大提高速度。而对SELECT * FROM PERSON这样无选择的查询语句,是否有索引则没有区别。作为文档型数据库的Notes,情况略有不同。文档型数据库里作为存储数据单元的文档,与关系型数据库里对应的记录相比最大的差异就是,文档没有记录受到的所在表定义的约束,例如一条记录有多少列,列的名称和数据类型是什么,长度几何等等。每条文档都可以有任意数量、名称和数据类型的字段。如果说某个表里的每条记录都有一个共同的schema,那么可以说每条文档都有自己的schema。在有些文档型数据库里,如大热的MongoDB,文档还被归类在表示同一种实体的collection里,有类似table的含义和用途。而在Notes数据库和另一热门CouchDB里,连这样的容器都没有,所有的文档,无论内容和用途是什么,都直接处于数据库这一级别之下(CouchDB与Notes数据库的相似之处还不仅这一点,考虑到它的最初作者Damien Katz就是来自Notes开发核心团队就一点都不奇怪了)。如此一来,即使是SELECT * FROM PERSON这样查询表格内所有数据的语句,在Notes里也没有直接的对应物了。这也意味着在Notes数据库里任何有意义的查询(也就是按文档的id查询之外)都必须藉助于视图这一概念。
由此可见,Notes视图索引的第一个作用是从数据库里选择某些文档,提取字段的值作为或计算列值,从而提供一个类似table的数据集合或接口。当我们在LotusScript或Java使用NotesView对象访问其中的NotesViewEntry时,读取的就是索引。同时,文档的响应层次、分类、求和、平均值等功能又使得视图承担了关系型数据库里依靠SQL和其他方法实现的报表功能。
Notes视图索引第二个作用就是便于查找文档。常用的NotesView.GetAllDocumentsByKey和GetDocumentByKey的实质都是在索引里找到条目,再返回对应的文档。用户在客户端展现的视图里排序、折叠展开分类以及按开头搜索,也都是利用索引完成的。
Notes视图索引的代价和关系型数据库里讨论的一样,都是占据存储空间和消耗计算资源。
更新的时间
索引是何时建立的?又是何时更新的?从上一节对索引作用的讨论可知,展现文档集合和使用户能够快速查找文档,这两个至关重要的用途都要求索引的数据是最新的,也就是与它所基于的文档的数据是一致的。在上一篇文章里,我们提到理论上更新索引在时间上有三种选择,一是与文档修改(新增、修改和删除)同时,二是延迟至索引被读取时才检查是否需要更新,三是定时更新。选项一保证了索引与文档始终是一致的,但是加大了文档修改时数据库的负担。选项二也能保证每次读取的索引是最新的。与选项一相比优点是,在索引被读取前,相关的文档可能已经过多次修改。不同用户修改不同文档,单个用户多次修改某个文档,等等各种情况都会发生。采用第一种方案时每次修改索引都需要更新,而方案二使得对索引两次被读取之间的所有修改(如果有),只需进行一次批量更新,从而减少开销。缺点是如果读取时发现索引需要更新,就增加了等待时间。第三种方案实际是对第二种方案的补充,理念同样是批量更新,目的是减少读取索引时需要更新的次数和文档数量。
综合以上分析可见,采用方案一时用户访问索引的速度是最快的,代价是所需系统资源也最多。方案二和三的延迟思路,节省了系统资源,但用户有时需忍受延时。关系型数据库基本上都采用第一种方案。文档型数据库则选择各异。MongoDB采用方案一,CouchDB采用方案二,Notes则混合使用方案二和三。
更新的过程
定时更新
我们先来看Notes视图的定时更新。这由服务器运行的Update和Updall两个任务来完成。两者的运行时间都可以在notes.ini里设置,默认情况下Update持续运行,Updall则在每天凌晨两点运行一次。Update维护两个队列(queue),一个是即时队列(immediate queue),另一个是延迟队列(deferred queue)。队列里保存的是一条条某个数据库索引需更新的请求。请求的来源有几类:复制器(replicator)复制后如果某个副本的文档有变动,就会发送一条请求到队列。邮件路由器(router)将新消息派送到某个邮箱后也会发送一条请求。最频繁的则是一个用户在某个数据库里创建、修改或删除了文档,当他退出该数据库时,会发送一条请求到队列。复制和用户修改产生的请求都被发送到延迟队列,特殊的例如触发数据库全文索引及时更新的操作会发送一条请求到即时队列。Update每隔五秒(可以通过notes.ini的UPDATE_IDLE_TIME和UPDATE_IDLE_TIME_MS设置修改此默认值,下同)检查两个队列,对即时队列里的请求马上处理,对延迟队列里的则会比较同一个数据库的请求,最先到达的请求之后的十五分钟(Update_Suppression_Time)内所有的请求都会被忽略,这样做还是为了减少资源的消耗,十五分钟以内对某个数据库的修改只会触发Update更新其索引一次。
请求只记录数据库的路径,Update在处理时先要判断对那些视图的索引进行更新。此时Notes再次显示了尽量节省资源的特性。首先过去七天(UPDATE_ACCESS_FREQUENCY)内未被打开过的视图被忽略。接着根据索引上次更新时间和视图的选择条件搜索最近发生更改过的并且包含在该视图中的文档,如果数量少于二十(UPDATE_NOTE_MINIMUM),也不做更新。
Updall任务因为是在凌晨进行,Notes显得大方一些。它不管队列,而是检查所有数据库的所有视图,需要更新的更新,需要重建的重建。
打开时更新
定时更新不能保证索引被访问时数据是最新的,只能尽最大限度减少那时更新的负担。用户通过客户端界面或程序访问视图时,会调用Notes API的NIFOpenCollection()函数打开索引(NIF意为Notes Indexing Facility,就是Notes索引部分的组件),如果索引数据不是最新的,NIFOpenCollection()就会调用NIFUpdateCollection()更新索引。我们每次在客户端里打开一个视图时,都会发生这个过程(除非以下说明的特殊情况)。如果距离上次Update更新该视图索引,发生更改的文档不多,这个过程就很快能完成。而如果这期间有大量文档发生改动,甚至该视图的索引不存在,就需要等待很长时间。自R7后,Notes会在单独的后台线程中进行索引更新,用户界面因而不会被卡住,用户还能进行其他操作。
为了提高视图打开的速度,或者说最大程度地减少索引更新的次数,Notes视图里还有控制打开时是否更新的选项。

分别是:1. 自动,初次使用后。2. 自动。3. 手动。4. 自动,最多每n小时更新一次。手动意为打开视图时索引不自动更新,需按F9更新。三种自动的区别在于,设为1或4时,如果一个视图未被打开过没有索引,Update和Updall运行时不会创建索引;设为2时则会;设为4时,如果索引在设置的最近n小时内被更新过,表现得就和设为3时一样。
索引在数据库里占据的空间不可小觑,数据库里如果视图多且复杂(列多,分类和排序多),索引占据的空间甚至会超过文档的空间。所以视图里又有丢弃索引的设置,可以设为数据库关闭后或者未被访问超过一定天数后丢弃。如果符合设置的条件,Updall任务负责删除索引。
所以,我们在设计视图时要……
每个视图包含的索引有三类:
1.    按照NotesID排序的默认索引。
2.    按照某列排序的索引。
3.    父文档和子文档关系的索引。
每增加一个列排序(包括分类),就新增一个索引。多级分类比同样数量的排序需要的计算更多。
我们已经从上面的讨论看到Notes是如何挖空心思地减少索引更新的次数,因为这是很消耗计算资源的动作。在设计视图时,如果罔顾Notes的苦心,建一大堆用途不大的视图,又加上用户很少使用的排序和必要性不大的分类,不但会导致Domino服务器上Update任务不堪重负,也会吞下视图打开缓慢的苦果。
以前我曾提到,XPages视图层和数据层分开的好处之一就是使视图可以仅仅作为数据集合,不同的展示需要,比如外观、列和文档的进一步筛选都可以利用XPages的视图控件实现,为减少视图数量提供了可能,从而也就减少了索引的数量,提高了性能和可维护性。
Notes帮助里有用的参考文章:
Notes Help - Refreshing view indexes
Administrator help - Indexer tasks: Update and Updall

从视图索引说Notes数据库相关推荐

  1. rds mysql 视图 索引_数据库 视图 索引

    SQL2K数据库开发二十二之索引操作在视图上创建索引 1.在企业管理器中,右击要创建索引的视图,在弹出的菜单中选择"设计视图"命令进入视图设计器. 2.在视图设计器中显示了视图所包 ...

  2. Linux || 数据库事务 视图 索引

    文章目录 事务 什么是事务 事务四大特性 ACID 隔离级别 事务命令 视图 定义视图 使用视图 更新视图 索引 定义 创建索引 联合索引(复合索引) 最左原则 聚簇索引 innoDB表的聚簇索引 非 ...

  3. notes获取计算机名,在Lotus Notes数据库中获取最近读取的文档(Get recently read document in Lotus Notes Database)...

    在Lotus Notes数据库中获取最近读取的文档(Get recently read document in Lotus Notes Database) 我正在使用LotusScript和Lotus ...

  4. 视图插入数据_数据库DQL、DML、DDL、DCL 详解

    SQL(Structure Query Language)语言是数据库的核心语言. SQL是一个标准的数据库语言,是面向集合的描述性非过程化语言. SQL语言共分为四大类:数据查询语言DQL,数据操纵 ...

  5. 超详细图解!【MySQL进阶篇】存储过程,视图,索引,函数,触发器

    超详细图解![MySQL进阶篇]存储过程,视图,索引,函数,触发器 1.1 下载Linux 安装包 1.2 安装MySQL 1.3 启动 MySQL 服务 1.4 登录MySQL 2\. 索引 2.1 ...

  6. Oracle 快速入门 同义词序列视图索引

    目录 一.数据库对象 二.同义词synonym 三.序列 四.视图 五.索引 六.综合代码 1.同义词部分: 2.序列: 3.视图和索引 一.数据库对象 1.数据库对象         2.同义词   ...

  7. mysql之视图索引

    一.视图 1.什么是视图 1) 视图是一种虚拟的表,是从数据库中一个或多个表中导出来的表. 2) 数据库中存放了视图的定义,而并没有存放视图中的数据,这些数据存放在原来的表中. 3) 使用视图查询数据 ...

  8. Oracle 视图索引

    第五章 视图索引的操作 5.1 视图的功能 一个视图实际上就是封装了一条复杂的查询语句 注:为了在当前用户模式中创建视图,要求数据库用户必须有create any view(创建任何视图)的权限. 5 ...

  9. oracle视图如何创建索引,ORACLE 创建视图索引序列

    /* 视图View 视图是从若干基本表和(或)其他视图构造出来的表 视图存放的都是查询语句,并没有真实的数据 虚表 作用 限制对数据的操作 复杂查询变简单 提供相同数据的不同显示 UNION ALL ...

最新文章

  1. hanlp java_HanLP-实词分词器详解
  2. JAVA偏向锁的什么时候释放_Java中的偏向锁
  3. C语言 - sizeof和strlen的区别
  4. python计算机基础_python计算机基础
  5. linux fedora安装flameshot火焰截图
  6. 栈,堆,值类型,引用类型,装箱,拆箱 .NET中 6个重要的概念
  7. Delphi编译报错对照表
  8. mysql数据库连接关闭_解决mysql数据库连接自动关闭问题
  9. Qt利用avilib实现录屏功能_openlayers6结合geoserver利用WFS服务实现图层编辑功能(附源码下载)...
  10. arraylist线程安全吗_Java的线程安全、单例模式、JVM内存结构等知识梳理
  11. sht-11c语言程序,温湿度传感器SHT11数据手册(中文)版.pdf
  12. iframe标签里面的页面元素只读
  13. 谈谈Android 6.0运行时权限理解
  14. adc分辨率和精度的区别_STM32学习笔记—ADC采集数据常见问题
  15. Android studio 教程入门
  16. linux virbr0是什么意思
  17. 在线博客系统——注册
  18. 2020年计算机组装行业,组装电脑已成夕阳产业?DIY装机发展的道路在何方?
  19. VMware Workstation 虚拟机下载及安装的详细步骤
  20. 01 Spark组件 —— Scala导言

热门文章

  1. Java WORD转换PDF 并添加水印 (附赠jar提取链接)
  2. any, never, unknown的区别
  3. HTTP请求,出现Status Code: 405
  4. 洛谷 P1361 小猫爬山
  5. OSI七层模型基础知识及各层常见应用
  6. python中的pip命令在cmd下用不了?
  7. windows2012装sql 2000 sql 2005 vs2005的解决办法
  8. Python当中reverse()函数
  9. 书签 自动更新浏览器的书签_最有用的书签,可增强您的浏览体验
  10. CAD好用的是哪个版本?分享一个在线转换版本的方法