hbase和couchdb
Apache CouchDB是NoSQL运动中的一种新型数据库管理系统(DBMS)。 主要信息存储为JavaScript Object Notation(JSON)文档。 CouchDB还支持更通用的文档格式作为托管附件。 它不支持的是经典的表格数据,这些数据是SQL查询的,数十年来一直统治着DBMS。 CouchDB的另一个关键特性是,其所有操作都可以通过简单的HTTP调用来使用,尤其是在REST (表示状态传输)形式下。 不管您的主机平台或工具包如何,此体系结构均可轻松使用CouchDB。 它还使CouchDB成为为网站和应用程序提供持久后端的有用工具。
你可以找到几个教程,让你开始使用CouchDB的应用开发使用其内置JavaScript库和相关的工具,比如CouchApp(参见相关主题 )。 在本文中,我采用了不同的方法,表明可以通过将CouchDB与简单的静态服务网站支架相结合来快速建立网站原型。
Bootstrap是一种快速建立网站前端的流行新方法。 Bootstrap系统是由Twitter工程师开发的,旨在帮助驯服他们用于网站开发的平台和工具包的动物园。 Bootstrap为Web应用程序UI提供了一个一致的框架。 它可以轻松地使用级联样式表(CSS)元素来设计漂亮的网站,这些元素用于版式,表单,按钮,表格,网格,导航,警报等。 在本文中,学习使用Bootstrap作为前端,CouchDB作为后端来启动开发过程,即使对于复杂的Web应用程序也是如此。
为什么不完全在CouchDB堆栈上原型?
尽管许多教程都显示了完全在CouchDB上开发完整的生产网站非常容易,但不建议这样做。 以这种方式入门会极大地诱惑人们偷工减料,并在网站公开时使用相同的方法。 从安全和维护的角度来看,最好将数据库后端与演示前端分开。 本文为您提供了多种选择,用于在CouchDB实例上线时对其进行锁定,以保护所有敏感数据。 安全始终需要警惕和专业知识。 由于基于静态文件的网站使用时间最长,因此最好理解它们,其管理工具也最成熟。
将CouchDB与网站前端分开可以为您带来另一个优势,因为在Web开发过程中通常会使用多个框架:
- 用于处理数据的DBMS
- Web服务器或内容管理系统
- 网页设计框架
在本文中,我使用CouchDB,Apache HTTP Server和Bootstrap。
这些层的人员,技能和选择技术的标准通常会有所不同。 您希望将一个决策与另一个决策放在一起。 除了它们之外,您还可以移动一些部分,例如内容交付网络,测试框架,支持安全性的中间件等等。 您可以在混合和匹配这些组件时获得更大的灵活性,从中长期来看,系统越容易维护和改进。
我为本文选择的技术反映了我的数据库管理专业知识。 Apache和Bootstrap只是帮助我快速启动该应用程序的工具。 我希望在基础知识到位后与其他专家合作。 中间件开发人员可能更喜欢继续使用诸如Django或Ruby on Rails之类的Web服务器框架,甚至是诸如WordPress之类的内容管理系统,因此我以可以在不严重影响其他层的情况下进行替换的方式使用Apache。 。 Web设计师很可能会喜欢手工设计而不是Bootstrap,因此我以易于替换的方式使用Bootstrap。 由于有了现代的工具和框架,以这种方式对Web应用程序进行原型开发并不需要依赖单个整体堆栈,因此,这并没有什么复杂的事情。
入门
我将展示一个简单的Web应用程序演示:一个诗歌报价网站。 有关安装CouchDB的帮助,请参阅参考资料 。 一旦在服务器上运行了CouchDB,就可以下载普通的Twitter Bootstrap(仅是CSS和JavaScript的捆绑包)或完整的项目捆绑包。 我正在使用本文中的完整捆绑包。
我从Twitter Bootstrap捆绑包中的fluid.html示例开始。 我修剪了文件,修复了CSS和JavaScript脚本,以删除../assets/
,并更新了示例站点的一些静态内容。 我保存为index.html的结果在本文的代码包中(请参阅下载 )。 清单1中是HTML页面标题的重要部分:
清单1. index.html页面标题的一部分
<!-- Styles -->
<link href="css/bootstrap.css" rel="stylesheet">
<style type="text/css">
body {
padding-top: 60px;
padding-bottom: 40px;
}
.sidebar-nav {
padding: 9px 0;
}
</style>
<link href="css/bootstrap-responsive.css" rel="stylesheet">
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
清单2是index.html表的一部分,从CouchDB加载了特色报价:
清单2. index.html表的一部分,其中装入了引号
<div class="row-fluid">
<div class="span4 featured-quote">
<h2>Poet's name</h2>
<p>Body of quote here.</p>
<p><a class="btn" href="#">View details »</a></p>
</div><!--/span-->
<div class="span4 featured-quote">
<h2>Poet's name</h2>
<p>Body of quote here.</p>
<p><a class="btn" href="#">View details »</a></p>
</div><!--/span-->
<div class="span4 featured-quote">
<h2>Poet's name</h2>
<p>Body of quote here.</p>
<p><a class="btn" href="#">View details »</a></p>
</div><!--/span-->
</div><!--/row-->
该页面还包括与数据库进行交互的机制。 特别是,侧边栏包含用户可以用来创建新报价记录的表单。 用户通过单击链接来访问表单,这将触发jQuery使表单出现。 清单3显示了表单标记。 (前两行<input>
行被拆分以适合本文的页面宽度限制。)
清单3.用于创建新报价记录的index.html表单
<a href="#popup" id="popup">Click to create a new quote</a>
<div>
<form id="newquote" action="index.html">
<fieldset>
<legend>The quote</legend>
<label for="author">Author's Name</label>
<input id="author" name="author" type="text" placeholder="First and last name"
required="required" autofocus="autofocus">
<label for="text">Text of the quotation</label>
<input id="text" name="text" type="textarea" placeholder="Text of the quote here"
required="required">
</fieldset>
<fieldset>
<legend>The work</legend>
<label for="title">Title of the work</label>
<input id="title" name="title" type="text" required="required">
<label for="link">Link to the work</label>
<input id="link" name="link" type="text" required="required">
<label for="year">Year of the work</label>
<input id="year" name="year" type="text" required="required">
</fieldset>
<input id="donewquote" type="submit" value="Add quote" />
</form>
</div>
清单4是index.html页面主体末尾附近的部分,用于加载必要JavaScript。 最后一个script
行包含用于在CouchDB中使用poquotes
数据库的特定代码。
清单4.在index.html页面主体的末尾附近加载JavaScript
<!-- Placed at the end of the document so the pages load faster -->
<script src="js/jquery-1.7.1.js"></script>
<script src="js/bootstrap.js"></script>
<script src="js/poquotes.js"></script>
</body>
在不到5分钟的时间内,Bootstrap使我能够享受一个网站的基本设置,该网站提供了最现代的功能,包括在旧版浏览器和移动设备上的优雅支持。 对于您自己的网站,更新颜色,字体,图像和其他详细信息以适合您的设计。 您可以访问Bootstrap画廊以获取很多启发(请参阅参考资料 )。
准备数据
在清单2中 ,请注意div
featured-quote
类的div
元素。 我将从CouchDB加载数据到那些元素中。 主页上有六个引号,这些引号由页面脚本动态加载并替换当前样板。
转至基于CouchDB浏览器的控制台Futon(例如,位于http:// localhost:5984 / _utils /),并创建一个名为poquotes,
的数据库,如图1所示:
图1.从CouchDB Futon页面设置poquotes
数据库
清单5是一个示例文档,其中包含报价信息。 (第四行分为两部分以适合本文的页面宽度。)
清单5.引号的示例JSON文档
{
"type": "quote",
"author": "Thomas Hardy",
"text": "And as the smart ship grew<br>In stature, grace, and hue<br>
In shadowy silent distance grew the Iceberg too.",
"work": {
"title": "The Convergence Of The Twain",
"link": "http://www.poetryfoundation.org/poem/176678",
"year": 1915
}
}
我使用cURL将文件q1.json加载到新数据库中:
curl -u user:passwd -X POST http://localhost:5984/poquotes \
-H 'Content-Type: application/json' -d @q1.json
{"ok":true,"id":"ca42f5a16ca1905978afdeda68c116c2",
"rev":"1-7fe040eb6d322a35a86d2f871b100ff0"}
CouchDB的响应(以{"ok"
开头)表明该文档已添加,并给出了生成的ID和新文档的修订版。 CouchDB的RESTful特性使该站点的数据集原型制作几乎与操纵文件系统一样容易。 如果愿意,还可以使用Futon添加文档。 本文的可下载示例代码包括六个这样的报价文档-足以填充目标页面的网格。
准备主要查询
我使用Futon设计了一个视图,以加载网页所需的文档。 在Futon中,您可以设计临时视图,对其进行测试,然后将其保存以供实际使用。 如果可能,请在开发周期的早期设计视图,而数据库中只有几个文档,因为临时视图会很快变慢。 清单6是视图JavaScript:
清单6.用于获取所有报价文档的CouchDB视图,按源工作年份进行索引
function(doc) {
if (doc.type == "quote") {
emit(doc.work.year, doc);
}
}
该视图很简单,但是可以解决问题,可以按工作年份索引结果,因为这就是我想要将记录排序到页面中的方式。 要将此视图添加到数据库中,请单击“ 视图”选择器,然后切换到“ 临时视图” 。 然后,您可以将清单6粘贴到Map Function框中。 单击运行以查看包含六个文档的表列表。 如果可行,请使用设计文档名称by_year保存该视图。 它不再是临时视图。 然后,您可以返回到可信任的cURL来执行视图:
curl "http://localhost:5984/poquotes/_design/poquotes/_view/\
by_year?&descending=true&limit=6"
GET
参数( &descending=true&limit=6
)调整数据库如何传递查询结果。 在这种情况下,仅以降序返回六个最新文档,以确保具有最新年份字段的文档排在第一位。
跨域限制
使多层Web应用程序的松散耦合,快速原型制作变得棘手的一件事是浏览器中的一组跨域请求限制。 出于安全原因,除了与源页面位于同一主机上的同一端口外,浏览器脚本受到严格限制,无法发出HTTP请求。 有几种解决此问题的方法。 其中之一是使用JSONP(带填充的JSON;请参阅参考资料 )。 清单7是poquotes.js的摘录-该部分将记录加载到目标div
:
清单7.用引号加载目标页面JavaScript和jQuery代码
...
root: "http://localhost:5984/",
...
max_quotes: 6,
//Invoked when the HTML page is first loaded
loadPage: function()
{
var six_latest = poq.root + "poquotes/_design/poquotes/_view/by_year?&limit="
+ poq.max_quotes + "&descending=true&callback=?";
$.getJSON(six_latest, poq.handleMainQuotes);
...
},
//Invoked with the result of the Ajax call to load quote documents
handleMainQuotes: function(json)
{
//Load up to six records, as available
quote_count = Math.min(poq.max_quotes, json["total_rows"])
for (var i=0; i<quote_count; i++) {
var doc = json["rows"][i]["value"]
var year = doc["work"]["year"].toString()
var title = doc["work"]["title"].toString()
var link = doc["work"]["link"].toString()
//Create an HTML snippet from the fields of each quote document
qblock = $("<div class='span4 featured-quote'></div>")
.append("<h2>" + doc["author"] + "</h2>")
.append("<p style='font-size: 80%; height: 8em;'>" + doc["text"] + "</p>")
.append("<p>" + year + "</p>")
.append("<p><a href='" + link + "'>" + title + "</a></p>")
.append("<p><a class='btn' href='#'>View details »</a></p>")
//jQuery's eq selector to find the target div corresponding to the loop index
$('div.featured-quote:eq(' + i.toString() + ')').replaceWith(qblock);
}
},
在清单7中 , callback=?
在URL的末尾添加了用于加载文档的文件。 这告诉jQuery将JSONP用于Ajax GET
查询以从CouchDB中提取文档,这是必需的,因为该数据库在与Web前端不同的端口上运行。 如果查询其他主机上的数据库,则也需要此解决方法。
使用GET
以外的方法发出Ajax请求比较麻烦。 清单8是poquotes.js的摘录,poquotes.js是创建新表单并将其发送到数据库的部分:
清单8. JavaScript和jQuery代码到转场从形式到记录和POST
它的CouchDB
...
dbroot: "db/",
...
//Invoked when the HTML page is first loaded
loadPage: function()
{
...
$('#donewquote').click(function() {
var db_link = poq.dbroot + "poquotes";
var record = {
"type": "quote",
"author": $("#author").val(),
"text": $("#text").val(),
"work": {
"title": $("#title").val(),
"link": $("#link").val(),
"year": parseInt($("#year").val())
}
};
$.ajax({
url : db_link,
data : JSON.stringify(record),
contentType : "application/json",
type : 'POST',
processData : false,
dataType : "json",
success : function(resp) {
alert("New document created: " + JSON.stringify(resp));
}
});
return false;
});
//Set up the collapsible form for adding new quotes
$('#popup').click(function(){
$("#newquote").slideToggle();
});
//Start out with the create quote form collapsed
$("#newquote").slideToggle();
},
在清单8中 , POST
是在相同的主机和端口上进行的,但在/ db / URL上进行。 我使用标准技巧来设置从该URL到CouchDB主机和端口的反向代理。 更具体地说,我使用Apache HTTP Server ProxyPass
指令。 此技术的详细信息取决于您的设置,但在设置Web原型时很有用,该原型在浏览器和服务器层之间有很强的分隔。
外观
图2显示了在目标div
中填充了数据库中的记录之后,首次加载时的工作示例页面:
图2.从Apache Web服务器加载index.html之后的浏览器屏幕
用户可以选择Click来创建新报价,以显示用于添加新报价的表单,如图3所示:
图3. index.html的浏览器屏幕,显示表单
结语
在整篇文章中,我已经解释了为什么我偏爱某些用于对Web应用程序进行原型制作的技术。 它们使Web设计和中间件更容易在独立的并行轨道上进行,这感觉像是自然而然的关注点分离。 我宁愿有一个专用的Web服务器来托管该站点,甚至是在开发中,而不是DBMS。
在本文中,我介绍了CouchDB上用户身份验证和授权的详细信息。 在原型制作阶段之后,我将更新中间件以处理用户管理,会话等。 我可以将这些问题转发给CouchDB的机构,也可以根据项目使用单独的框架。 这是我获得的关键灵活性。 Web应用程序获得了有关登录和会话管理的一些详细信息,但是通常它是一个独立的层。
我在本文中的意图不是要贬低在NoSQL平台上进行原型制作的其他方法。 我提供它作为值得考虑的替代方法。 结合最有趣的开源项目,将每个项目都集中在其核心优势上,既有趣又富有成效。 在此过程中,您还将学到许多重要的细节,而这些细节常常被太紧密地耦合在一起的工具所掩盖。
翻译自: https://www.ibm.com/developerworks/opensource/library/wa-couchdb-bootstrap/index.html
hbase和couchdb