Electronic Joint Business

Solution for E-Business

数据存储

基于 MYSQL 存储引擎实现虚拟数据表查询 (二)

在上一篇文章中,我阐述了如何基于 MYSQL 存储引擎从 API 中检索数据,并回馈给 MYSQL。特别是我需要从 MySQL 控制台上获得最新的系统进程列表。本文是对上一篇文章的改进,你将看到我们无须对 MySQL 解析器做任何修改就可以解决同样的问题。1

ProcessInfoEngine
这里的存储引擎不同于常见的 MyISAM 或者 InnoDB 等存储引擎,它从 Windows 进程 API 中检索数据并回馈给 MySQL。为此我们创建数据表 runningprocesslist ,其存储引擎是 ProcessInfoEngine。

`PROCESSNAME` varchar(2048) DEFAULT NULL,
  `ProcessID` int(11) DEFAULT NULL,
  `Threadcount` int(11) DEFAULT NULL,
  `ParentprocessID` int(11) DEFAULT NULL,
  `Priorityclass` int(11) DEFAULT NULL
) ENGINE= ProcessInfoEngine

当用户在 runningprocesslist 数据表上执行 select 查询时,控制权被交给 ProcessInfoEngine 的 rnd_init 方法。该方法会检查数据表名称是否真的为 “RunningProcessList”,然后再检查 where 子句解析树是否存在。如果存在,where 子句解析树将被遍历以便转换成 OpenProcess 调用。如果不存在 where 子句,那么我们将创建进程快照,并将所有进程的信息回馈给 MySQL。

int ha_example::rnd_init(bool scan)
{
        DBUG_ENTER("ha_example::rnd_init");
       
        if(_stricmp(table_share->table_name.str,"RunningProcessList")==0)
        {
                THD *thd=this->ha_thd();
                SELECT_LEX *select_lex=&thd->lex->select_lex;
                m_processListIndex=0;

                if(select_lex->where==0)
                {
                        GetAllProcessList(m_processList);
                }
                else
                {
                        stack<parsestackelement> parseStack;
                        select_lex->where->traverse_cond(My_Cond_traverser,(void*)&parseStack,Item::traverse_order::POSTFIX);
                        if(!parseStack.empty()&&parseStack.size()==1)
                        {
                                GetProcessListSpecifiedInWhereClause(m_processList,parseStack.top().setOfProcessIds);
                        }
                        else
                        {
                                GetAllProcessList(m_processList);
                        }
                }
        }
        DBUG_RETURN(0);
}

在后序遍历 Where 子句解析树时, 我们创建并维护了名为 ParseStackElement 这样一个栈结构。

>>> 阅读全文

 

,

基于 MYSQL 存储引擎实现虚拟数据表查询 (一)

文章评价:
MySQL 支持多种可用于存储管理与检索的存储引擎,最常见的是 MyISAM 和 InnoDB 。创建数据表时可以指定存储引擎。最简单的存储引擎只能读取数据表。大多数引擎支持从文件读取数据并回馈给 MySQL。所以,我设想调用 API 来检索数据并将数据直接回馈给 MySQL。在此之上,我们可以利用 SQL 语句对检索到的数据进行复杂分析。为此我需要在相关 API 之上编写一个引擎,不过我并不打算从头开始编写新引擎,而是打算构建一个通用的组件让所有存储引擎调用,这将大大简化编写引擎的工作。1

背景
我希望透过 MySQL 对系统中的进程进行分析,通过 MySQL 控制台上获得运行中的进程的列表,进而执行复杂分析,比如说查询某个进程所包含的模块。为了提供简单的视图,我希望将这些以数据表的形式呈现,由存储引擎来调用相关 API 检索数据。API 是操作系统中现成的。对于其他部分,传统办法是创建数据表,每当有新进程启动就插入新的数据行,有进程终止时就删除数据行。

显然这种方法有很多缺点:

  • 插入删除数据行都是系统开销。
  • 在查询数据表前,你需要触发负责插入或删除数据行的日志程序。
  • 即便只需查看单一进程,数据表中还是需要维护所有进程的信息。
  • 一旦进程终止它的进程 ID 又为新进程所用,这时如旧数据行未删除就插入新数据行会产生 ID 冲突。
  • 插入或删除需要表锁定,可能会是整个检索单元的性能瓶颈。

因此新的构思应当解决这些问题:

  • 无需插入或删除数据行
  • 查询数据表之前无需触发日志应用
  • 如只查询单一进程则不用读取所有进程的消息
  • 无进程 ID 的不一致性,因为该数据表只是系统的状态快照
  • 无性能瓶颈,因为没有插入或删除操作

好处
新构想比传统方法更好地解决了一个具体问题:即表中的数据可以有时间轴。当表的大小达到一定限度时,可以创建新表。这也是使用 Tableau 商业智能工具进行分析时的要求。Tableau 可以生成 SQL 查询。为方便起见,要求使用单个表而在背后维护多表间的关系。我们可以生成编程式查询来检索某时间段内的数据并显示在 web 页面上,但 Tableau 无法使用这些程序。一种传统技术是将数据复制到单个表中,但同时我们所维护多表的关联就会失效。另一种传统技术是使用视图,但是在视图背后使用编程式查询会导致视图失效。我所构想的是只公开单个数据表,利用 API 从多个表中检索数据。编写存储引擎可以提供解决方法。最简单的引擎会回馈所有的数据让 MySQL 筛选,但这非常低效。而我所构想的存储引擎将利用 MySQL 查询分析器的强大能力。在 MySQL 查询期间 where 子句会被转换为对函数和 API 的调用,这样某种程度上我们只要检索所需的数据。这个构想广义上可以推广到任何 API,无需重写生成 API 调用等核心逻辑。

>>> 阅读全文

 

, , ,

MVCC (一)概述

本文的作者是 Trek Palmer,他是 NuoDB 的工程师,负责实现及调试 NuoDB 的 Atom 层。在过去的一年中, Palmer 一直致力于分布式事务一致性方面的研究。在与客户的沟通中, Palmer 发现最常被问起的问题之一就是:如何在接受众多节点的更新的同时保持一致性。答案就是:分布式上下文中多版本并发控制(MVCC) 的实现。想要理解这一点,你必须对 MVCC 有相当的了解。Palmer 是并发方面的专家,也当过教师,所以他在博客上对 MVCC 做了一系列的详细的技术解释。1 2

MVCC 剑指何方?
数据库的设计思想很纯粹:攫取数据、保存数据、并按所需的格式返回数据。出于实用性考虑,任何数据库都应能同时处理尽可能多的请求。 SQL 是一种声明性语言。也就是说,像 average 这样的 SQL 语句并未规定它该如何执行,只是罗列了数据库执行语句时要操作的参数。当程序员与数据库交互时,细节部分被转交给了数据库本身。这是好事,意味着应用逻辑和数据存储的细节的分离。这样做的后果之一是,数据库本身要能管理多个并发客户端。特别是,数据库需要处理在不同事务(来自多个客户端)同时读取和写入同一数据片的情况。

如果你看过传统的并行代码,可能会问“为什么不使用读/写锁?”。这种想法是合理的,而且多年来也一直为一些数据库所使用。然而,它有个严重的问题。简单地说,读阻塞写,写阻塞读。读/写锁的语义本身就是如此,没什么特别惊讶的。然而,这些语义对任何事务型数据库的性能都会产生严重的不良影响。

思考一下,假如系统中有两种事务:一种是只读的长事务,用于创建报告或者数据分析。一般只有一两个并发用户。而另一些是与用户进行交互的短事务,比如说在线下单,这类交互通常包括两读和一写(或两写)。并发用户可能有成千上万。读/写锁的问题是,如果短事务的写操作与长事务的读操作之间有任何数据重叠,短事务会被阻塞,直到长事务完成。对习惯互联网消费的人来说,哪怕长事务只是造成订单延迟几秒钟,也是不能接受的。问题在于如何同时保证合理延迟和最高并发性。理想情况下,阻塞只应在事务真的影响另一事务更新数据行时才发生(实际上,阻塞只是可用的数据库并发控制机制之一) 。拿上面的例子来评估,情况应该是:长事务永远不应造成短事务阻塞;短事务之间除非更新到同一行,否则不应互相影响或阻塞。当读/写锁力不从心时,这一壮举该如何完成?对 NuoDB 和许多现代数据库来说, 答案是:多版本并发控制。

什么是 MVCC?
你可能会说,“很好,我了解 MVCC 要解决什么问题了,不过是如何解决的呢?” 答案就在它的名字中。对非 MVCC 数据库来说,每条既定记录都有其固定存储点,并在该存储点上进行着各种花销的锁,而 MVCC 数据库允许既定记录同时拥有多个版本。每次对数据行进行更新都会产生一个新版本。因此,写操作竞争的是往数据行最高版本之上添加新版本的权利,而读操作则可以读取任何可见版本。对上面的例子来说,这意味着只读的长事务永远不会锁定数据行。因此不会导致短事务被阻塞。而且,只有两个(或更多)短事务争相获得某个数据行版本的更新权利时,才会彼此干扰。如果在维护事务中的可见性信息的同时找出可见的数据行版本,MVCC 就可以实现数据库快照。实际上,当事务开始时,它会“冻结”一揽子数据记录版本作为其可见数据集。对这些版本进行更新逻辑上发生在事务读取该数据集之后(哪怕执行事务的线程没有实际读取该数据行版本) 。要支持 MVCC 语义你需要的是:记录存储系统,可以为同一记录保存不同版本;某种锁定系统,可以让其它事务知道记录被同步更新了;以及将记录版本号翻译为事务ID 的机制,以进行可见性计算。

>>> 阅读全文

 

,

NuoDB 数据库的架构

一直以来,关系型数据库被设计成向上扩容(scale-up) 的架构。换句话说,要处理更多的负载,就需要更强大的计算机。这意味着,如果在几年前想要支持水平扩容(scale-out)的架构,你要嘛得放弃 SQL,要嘛得用上分区(sharding)、Active-Passive 复制等技巧。想在一个弹性的逻辑数据库上实现真正的 ACID 编程模型是不太可能的。这个矛盾正是 NewSQL 运动的矛头所向,也是 NuoDB 的灵魂所在。1

NuoDB 是为云扩展而设计的关系型数据库。这句话该怎么理解呢?NuoDB 是真正的 SQL 服务:它拥有 ACID 事务的所有属性、标准的SQL 语言、以及真正的关系型逻辑,这一切都深受用户喜欢。最重要的是,从最初的设计开始,NuoDB 就能按云服务的方式进行伸缩。

关于“云扩展”的定义有点老生常谈。如果感兴趣,你可以到我们的技术博客上了解什么是云扩展。简单来说,除了支持水平扩容的模型外,我觉得它还应包括敏捷、易用、可自动化、安全以及高可用性。本文就是从这个观点出发的.。2

请注意,NuoDB “只是”个软件。它能够运行在 Linux、Mac 或者 Windows 上,无论这些系统被安装在笔记本、私有云或公有云上。NuoDB 可以部署在 Amazon Web Services 或 Google Compute Engine 上,或者可以集成 OpenStack 一起使用,或者就在笔记本上作为本地 Windows 服务运行。NuoDB 十分灵活,你可以随心所欲地进行测试、开发,之后再部署到你想要的地方。

本文将重点要介绍什么是 NuoDB,它采用了什么架构来应对现今世界的挑战,以及你可用 NuoDB 来解决什么问题。阅读完本文,你应该可以对 NuoDB 的关键概念和架构的不同之处有所了解。你也可以了解到一些实际部署和管理的特性,并对自己的 NuoDB 数据库进行伸缩。

>>> 阅读全文

 

, , , , ,

Oracle 启动过程

通常所说的 Oracle 服务器主要由两个部分组成: 数据库实例 Instance 和数据库 Database。数据库实例是指一组后台进程(在 Windows 上是一组线程)和一块共享内存区域;数据库是指存储在磁盘上的一组物理文件。通过 Instance 与 Database 协同,Oracle 数据库服务器才能形成一个动态的可访问关系型数据库系统。

数据库管理员最常见的工作之一就是启动或者停止 Oracle 数据库。通常来说,我们并不希望经常让数据库停机,因为:

  • * 会给用户群造成不便
  • * 每次重启数据库,就得冒它无法启动的风险
  • * 关闭数据库会清空 Oracle 内存区域,比如数据库缓冲 cache

重启之后的数据库的性能总会慢一点,这种状况会持续到数据库内存区域被“预热”了。不过有时候我们不得不关闭数据库,例如:

  • * 需要打补丁或者升级
  • * 进行某些应用维护
  • * 进行离线数据库备份-冷备份 (通常推荐热备份这样可以避免关闭数据库)
  • * Oracle 软件存在的某个 bug 要求在某些情况下重启数据库

当需要再次启动数据库的时候(使用 shutdown 和 startup 命令),我们用 SQL*Plus 来发出这些指令。下面详细了解一下这些命令。

Oracle Startup 命令
用 startup 命令可以启动 Oracle 数据库。首先要用有 sysdba 或 sysoper 权限的帐号登录,比如 SYS 用户。下面的例子演示了 DBA 是如何连接到数据据库,并启动 instance :

>>> 阅读全文

 

, , ,

Redhat 6 下安装 Oracle 11G R2

文章评分:
Oracle 数据库 11g(构建在 Oracle 独有的网格计算能力上)使 Oracle 客户能够更快地响应不断变化的业务状况,通过技术创新获得竞争优势,同时降低成本。

使用 Oracle 数据库 11g,您可以:

  • * 利用 Real Application Testing 使得新技术更快得以采用
  • * 先进的 Oracle 数据压缩和分区技术(Partitioning) 能够以更少存储空间管理更多的数据
  • * 利用 Oracle SecureFiles 将所有数据存储在 Oracle 数据库中从而简化系统
  • * 利用 Oracle Active Data Guard 使灾难资源恢复的投资回报率 (ROI) 最大化
  • * 通过管理自动化使关键人员能将精力投入到战略性任务中
  • * 等等..

在 Linux 系统上部署 Oracle
我们选用 Redhat 企业版来作为 Oracle 的操作系统。目前最新的版本是 RedHat 6.1,你可以根据 CPU 的架构选择32位或者64位的 Linux,通常来说64位版本可以管理更大的内存和硬盘空间,应该作为企业应用的首选。

Oracle 11g R2数据库安装硬件配置要求:

  • * 至少要有 1GB 以上的内存。
  • * 企业版要求 3.95 GB 的硬盘空间,同时需预留至少 1.7G 的空间来保存数据文件。

根据系统内存的大小,你需要合理设置交换分区的大小:内存为256-512M的时候 交换分区大小应该为内存2倍; 512-2G的时候, 交换分区大小应该为内存1.5倍;2-8G时, 交换分区大小和内存相同;8G以上,交换分区是内存大小的0.75倍。此外还需预留 10GB 左右的硬盘空间给操作系统,建议硬盘空间至少有 20GB 以上的剩余空间。

>>> 阅读全文

 

, ,

数据库与事务处理

介绍
数据库是与某一企业相关的数据项的集合,通常存储描述企业当前状态的信息,例如,一家银行的数据库存储每个储户当前的账户余额。当现实世界中的某一事件改变了企业的状态,存储在数据库中的信息必须做相应的改变,这些改变通常由称为事务(transaction)的程序实时地实现。事务管理是对企业应用最紧要的要求之一。在贸易、金融和电子商业领域中,多数大的企业应用依赖于递送它们的商务的事务处理功能。 鉴于当今商务对灵活性的要求,在构造、部署和维护企业级别的分布式应用中,事务处理占据的是其中最复杂的部分之一。

本文把以下内容介绍给读者:

  • 什么是事务? 什么是 ACID?
  • 建造一个事务应用的要点是什么? 事务管理中间件为什么很重要?
  • 事务处理应用的典型的体系是怎样的? 体系中的各种构件的职责是什么?
  • 事务处理系统涉及哪些概念?
  • 事务管理领域中有哪些标准和技术?

本文不特定于任何产品,力图在描述各种要点和概念时保持普遍性。本文不打算比较各种事务处理的技术/标准,只是提供对此的一个讨论。

什么是事务?
为了完成对数据的操作,企业应用经常要求并发访问在多个构件之间共享的数据。这些应用在下列条件下应该维护数据的完整性(由应用的商务规则来定义):分布式访问一个单独的数据资源,以及从一个单独的应用构件访问分布式资源。

在这种情况,可能要求在(分布式)资源上的一组操作被当作一个工作单元(unit)。在一个工作单元中, 操作的所有部分一起成功或失败并恢复。在下面的情况下这个问题更加复杂:通过一组分布式的、访问多个资源的数据的构件实现一个工作单元,和/或部分操作是被顺序执行的或在要求协调和/或同步的并行线程中。

>>> 阅读全文

 

, ,

使用Azure和CloundDrive运行MongoDB

Running MongoDb on Microsoft Windows Azure with CloudDrive
I’ve been playing around with the whole CQRS approach and think MongoDb works really well for the query side of things. I also figured it was time I tried Azure so I had a look round the web to see if there we’re instructions on how to run MongoDb on Microsoft’s Azure cloud. It turned out there were only a few mentions of it or a general approach that should work but no detailed instructions on how to do it. So, I figured I’d give it a go and for a total-Azure-newbie it didn’t turn out to be too difficult.

Obviously you’ll need an Azure account which you may get with MSDN or you can sign-up for their ‘free’ account which has a limited number of hours included before you have to start paying. One thing to be REALLY careful of though – just deploying an app to Azure starts the clock running and leaving it deployed but turned off counts as hours so be sure to delete any experimental deployments you make after trying things out!!

First of all though it’s important to understand where MongoDb would fit with Azure. Each web or worker role runs as a virtual machine which has an amount of local storage included depending on the size of the VM, currently the four pre-defined VMs are:

•Small: 1 core processor, 1.7GB RAM, 250GB hard disk
•Medium: 2 core processors, 3.5GB RAM, 500GB hard disk
•Large: 4 core processors, 7GB RAM, 1000GB hard disk
•Extra Large: 8 core processors, 15GB RAM, 2000GB hard disk
This local storage is only temporary though and while it can be used for processing by the role instance running it isn’t available to any others and when the instance is moved, upgraded or recycled then it is lost forever (as in, gone for good).

For permanent storage Azure offers SQL-type databases (which we’re not interested in), Table storage (which would be an alternative to MongoDb but harder to query and with more limitations) and Blob storage.

>>> 阅读全文

 

, ,

在Azure中运行MySQL

由于不同的原因,我手头的许多Azure应用都必须依赖于MySQL。例如,我手头的Joomla开发就完全依赖于MySQL。大部分情况下,这是因为在应用中使用了MySQL的原生驱动,而未不是设计一个数据库独立层,类似.NET中的ADO.NET或者PHP中的PDO,或者裁剪掉那些MySQL特有特性。基于上述的理由,要在Windows Azure中运行这些应用,不得不想方设法让MySQL在Azure中运行。

这其实没有想象的困难,在此过程中,我可以重用许多二进制可执行文件。

想法与建议
在深入让MySQL运行起来的技术细节之前,我想先分享一下个人对于在Azure中运行MySQL的观点,在我告诉你别这么做之前,你可以节约阅读这篇文章的时间,

现实是即使你能在Windows Azure中运行MySQL,这么做也不太实际。我的建议是把它保留做你最后的法宝或者权宜之计直到Sql Server能够支持你的应用。我这么说是有许多原因的,有些是技术方面的,有些是财务方面的。因此,本文更多是关注在Azure运行和管理MySQL的过程,而不是非要这么做。

现在,让我们来深入技术问题。在Azure中运行MySQL的方法是创建一个Worker Role,它会作为二进制文件的实际宿主。你只要拷贝出可执行文件,然后编写简单的Windows Azure相关代码来实际执行应用,并传递请求给它。事实上,任何可执行文件只要可以通过xcopy发布而且无休止运行的都可以通过这个方法来实现。这对于进行分布式计算之类的事情是相当棒的。

>>> 阅读全文

 

, , , ,

面向文档数据库CouchDB (五) 高级话题

权限控制与安全

CouchDB 目前只支持一种角色,即“系统管理员”。“系统管理员”可以执行任意的 HTTP REST API 对数据库进行任意的修改。可以在 CouchDB 的配置文件中添加系统管理员的帐号和密码。 CouchDB 也自带对 HTTP 基本认证的支持,同样可以在配置文件中启用这一认证方式。

由于目前 CouchDB 对于权限控制功能比较弱,一种比较好的做法是用 Apache HTTP 服务器作为 CouchDB 的反向代理,由 Apache HTTP 服务器来处理访问控制。关于配置 Apache HTTP 服务器,见参考资料。

文档更新校验

CouchDB 允许文档在创建和更新之前先进行校验。只有校验通过的文档才能被保存在数据库中。校验方法是由设计文档中的validate_doc_update字段来表示的。所有的文档更新都会调用该方法,如果该方法抛出异常,则说明校验失败,CouchDB 会返回异常中的错误信息给客户端。

>>> 阅读全文

 

, , ,

面向文档的数据库 CouchDB (四) 视图

视图是 CouchDB 中用来查询和呈现文档的。完成视图的定义之后,视图的运行由专门的视图服务器来完成。 CouchDB 中默认的视图定义语言是 JavaScript 。 CouchDB 中的视图运行使用的是 MapReduce 编程模型。每个视图的定义中至少需要提供 Map 方法,Reduce 方法是可选的。

视图的 MapReduce
Map 方法的参数只有一个,就是当前的文档对象。 Map 方法的实现需要根据文档对象的内容,确定是否要输出结果。如果需要输出的话,可以通过emit来完成。emit方法有两个参数,分别是key和 value,分别表示输出结果的键和值。使用什么样的键和值应该根据视图的实际需要来确定。当希望对文档的某个字段进行排序和过滤操作的时候,应该把该字段作为键(key)或是键的一部分;value的值可以提供给 Reduce 方法使用,也可能会出现在最终的结果中。可以作为键的不仅是简单数据类型,也可以是任意的 JSON 对象。比如emit([doc.title, doc.price], doc)中,使用数组作为键。

通过 Map 方法输出的结果称为中间结果。中间结果可以通过 Reduce 方法来进一步做聚集操作。聚集操作是对结果中键(key)相同的数据集合来进行的。 Reduce 方法的输入不仅是 Map 方法输出的中间结果,也可以是上一次 Reduce 方法的结果,后面这种情况称为 reReduce 。 Reduce 方法的参数有三个:key、values和rereduce,分别表示键、值和是否是 reReduce 。由于 reReduce 情况的存在,Reduce 方法一般需要处理两种情况:

  • * 传入的参数rereduce的值为false:这表明 Reduce 方法的输入是 Map 方法输出的中间结果。参数key的值是一个数组,对应于中间结果中的每条记录。该数组的每个元素都是一个包含两个元素的数组,第一个元素是在 Map 方法中通过emit输出的键(key),第二个元素是记录所在的文档 ID 。参数values的值是一个数组,对应于 Map 方法中通过emit输出的值(value)。
  • * 传入的参数rereduce的值为true:这表明 Reduce 方法的输入是上次 Reduce 方法的输出。参数key的值为null。参数values的值是一个数组,对应于上次 Reduce 方法的输出结果。

下面通过一个实例来说明视图 Map 和 Reduce 的用法。该视图要解决的问题是对图书简介中出现的字符进行计数,这也是一个经典的 MapReduce 编程模型的实例。代码清单 12中给出了该视图的定义。

清单 12. 对图书简介中的字符计数的视图定义

>>> 阅读全文

 

, , , ,

面向文档的数据库 CouchDB (三) 开发Web应用

CouchDB 不仅是一个数据库服务器,同时也是一个应用服务器。在前面对 REST API 的介绍中,说明了如何把 CouchDB 作为一个数据库服务器来使用。下面将介绍如何将 Web 应用运行在 CouchDB 上。

由于 CouchDB 的 REST API 使用 JSON 作为展现形式,因此使用 CouchDB 的 Web 应用只需要编写浏览器端的代码就可以使用 JavaScript 与 CouchDB 进行交互;而 CouchDB 所支持的附件功能,又使得浏览器端的 HTML、JavaScript 和 CSS 代码可以直接存放在 CouchDB 中。这样 CouchDB 中不但保存了 Web 应用的数据,也保存了 Web 应用的逻辑。也就是说,只需要 CouchDB 就可以构建一个完整的 Web 应用运行环境。

在 CouchDB 中,一个 Web 应用对应的是一个设计文档。这个 Web 应用可以操作 CouchDB 中保存的文档型数据。当需要创建新的 Web 应用的时候,只需要创建新的设计文档即可。 CouchDB 使得 Web 应用的部署和管理变得非常简单,只需要通过 REST API 管理设计文档即可。从更大的角度来说,CouchDB 有可能创造一种新的 Web 应用开发模式。在这种模式中,CouchDB 中保存的文档型数据可以为每个应用开发者所使用,开发者在数据之上创建满足各种需求的 Web 应用。

本文中将以一个具体的小型网站作为实例来介绍使用 CouchDB 开发 Web 应用中的细节。该网站是一个类似“豆瓣”的用户点评网站。在该网站中用户可以对图书进行编辑和评价。

使用 CouchApp
CouchApp 是一个开发使用 CouchDB 的 Web 应用的小型框架。它的主要功能是可以把一个文件系统的目录转换成 CouchDB 中的一个设计文档。在开发的时候,可以按照一般 Web 应用的结构来组织文件系统,当需要测试和部署的时候,只需要一条命令就可以把该目录保存到 CouchDB 中。 CouchApp 目前有 Python 和 Ruby 两种语言的版本,本文中使用的是 Python 版本。由于目前 CouchApp 正在开发中,所以最好是从源代码安装。代码清单 7 中给出了 CouchApp 的安装脚本。

>>> 阅读全文

 

, , , ,

面向文档的数据库 CouchDB (二) REST API和建模

CouchDB 提供 REST API 来供客户端程序使用 CouchDB 的功能,并对数据库进行操作。REST API 主要针对 CouchDB 中的三种资源:数据库、文档和视图。下面分别介绍这三种 REST API 的细节。

数据库 REST API

数据库 REST API 用来查询、创建和删除数据库。 CouchDB 中数据库的名称只能是小写字母、数字以及特殊字符_$()+-/。需要注意的是大写字母是不允许的,这是由于某些操作系统的文件系统是大小写不敏感的。 CouchDB 为了避免可能出现的问题,限制了不能使用大写字母。数据库 REST API 的具体用法如下:

  • * 通过 GET 请求访问 URL/_all_dbs可以查询 CouchDB 中所有的数据库名称。该请求返回的是一个 JSON 数组,其中每个元素表示一个数据库名称。
  • * 通过 GET 请求访问 URL/databasename/可以查询名为databasename的数据库的具体信息。该请求返回的是一个 JSON 对象。
  • * 通过 PUT 请求访问 URL/databasename/可以创建名为databasename的数据库。如果数据库创建成功的话,返回 HTTP 状态代码 201 ;如果已有一个同名数据库的话,返回 HTTP 状态代码 412 。
  • * 通过 DELETE 请求访问 URL/databasename/可以删除名为databasename的数据库。如果数据库删除成功的话,返回 HTTP 状态代码 200 ;如果数据库不存在,返回 HTTP 状态代码 404 。

文档 REST API
文档 REST API 用来查询、创建、更新和删除文档。具体的用法如下:

  • * 通过 GET 请求访问 URL/databasename/doc_id可以获取名称为databasename的数据库中 ID 为doc_id文档的内容。文档的内容是一个 JSON 对象,其中以“ _ ”作为前缀的顶层字段是由 CouchDB 保留使用的,如_id和_rev。
  • * 通过 PUT 请求访问 URL/databasename/doc_id可以在名称为databasename的数据库中创建 ID 为doc_id的文档。通过 POST 请求访问 URL/databasename/也可以创建新文档,不过是由 CouchDB 来生成文档的 ID 。
  • * 通过 PUT 请求访问 URL/databasename/doc_id可以更新已有的文档。在 PUT 请求内容的文档中需要包含_rev字段,表示文档的修订版本号。 CouchDB 使用该字段来做更新时的冲突检测。如果该字段的值与 CouchDB 中保存的该文档的修订版本号一致,则表明没有冲突,可以进行更新。当更新完成之后,返回 HTTP 状态代码 201 ;否则返回 HTTP 状态代码 409,表示有版本冲突。
  • * 通过 DELETE 请求访问 URL/databasename/doc_id?rev=rev_id可以删除数据库databasename中 ID 为doc_id,并且修订版本号为rev_id的文档。

视图 REST API

>>> 阅读全文

 

, , , ,

面向文档的数据库 CouchDB (一) 概述与安装

文章评价:
Apache CouchDB 是一个面向文档的数据库管理系统。它提供以 JSON 作为数据格式的 REST 接口来对其进行操作,并可以通过视图来操纵文档的组织和呈现。 CouchDB 是 Apache 基金会的顶级开源项目。本文将介绍 CouchDB 的基本概念,包括文档、视图,REST API,并通过一个实际的图书点评网站来说明如何用 CouchDB 开发 Web 应用。

CouchDB 介绍

CouchDB 是一个文档型数据库服务器。与现在流行的关系数据库服务器不同,CouchDB 是围绕一系列语义上自包含的文档而组织的。 CouchDB 中的文档是没有模式的(schema free),也就是说并不要求文档具有某种特定的结构。 CouchDB 的这种特性使得相对于传统的关系数据库而言,有自己的适用范围。一般来说,围绕文档来构建的应用都比较适合使用 CouchDB 作为其后台存储。 CouchDB 强调其中所存储的文档,在语义上是自包含的。这种面向文档的设计思路,更贴近很多应用的问题域的真实情况。对于这类应用,使用 CouchDB 的文档来进行建模,会更加自然和简单。与此同时,CouchDB 也提供基于 MapReduce 编程模型的视图来对文档进行查询,可以提供类似于关系数据库中 SQL 语句的能力。 CouchDB 对于很多应用来说,提供了关系数据库之外的更好的选择。下面介绍 CouchDB 中的一些重要概念。

基本概念

文档(document): 文档是 CouchDB 中的核心概念。一个 CouchDB 数据库实际上是一系列文档的集合,而这些文档之间并不存在层次结构。每个文档都是自包含的数据单元,是一系列数据项的集合。每个数据项都有一个名称与对应的值,值既可以是简单的数据类型,如字符串、数字和日期等;也可以是复杂的类型,如有序列表和关联对象。每个文档都有一个全局惟一的标识符(ID)以及一个修订版本号(revision number)。 ID 用来惟一标识一个文档,而修订版本号则用来实现多版本并发控制(Multiversion concurrency control,MVVC)。在 CouchDB 中,文档是以 JSON 对象的形式保存的。

>>> 阅读全文

 

, , , , , ,

MongoDB 开发手册 (二) 连接串和mongo操作台概述

数据库连接
MongoDB是数据库服务器,它可以在前台或者后台运行并等待用户连接。因此,当你启动MongoDB的时候,你会看到这样的字句:

~/$ ./mongod
#
# some logging output
#
Tue Mar  9 11:15:43 waiting for connections on port 27017
Tue Mar  9 11:15:43 web admin interface listening on port 28017

这时屏幕会暂停输出,但并未死机,它会在27017端口上侦听用户的连接。一旦用户连接上数据库并开始发送命令,它又会再次记录它所做的一切。任何一款MongoDB驱动或者Mongo操作台都可以用来连接数据库。

不能通过在浏览器输入”http://localhost:27017″来连接MongoDB,数据库不能通过27017端口上的HTTP协议来存取。

标准连接串格式
这儿介绍的URI schema不一定为所有的驱动程序所支持,你可以参考相关的驱动程序文档以获知该驱动支持多少种标准连接URI。所有的驱动都支持某种指定连接格式的替代方式,如果该格式不被支持。

mongodb://[username:password@]host1[:port1][,host2[:port2],…[,hostN[:portN]]][/database]
  • mongodb://是必选的前缀,表明该字串是标准的连接格式
  • username:password@是可选项,如果指定了该项,驱动程序在连接数据库服务器之后,尝试用它连接数据库。
  • host1是URI中唯一的必选项,表明所连接的服务器地址。
  • :portX是可选项,未指定的话默认为27017。
  • /database是要登录的数据库名称,只有指定了username:password@之后,该项才有意义,如果未指定,默认将连接到”admin”数据库。

你可以在URI中指定多个主机连以便连接到同步复制对或同步复制集(replica pairs/sets). 下面是一些例子:

>>> 阅读全文

 

, , , ,

Previous Posts