给MongoDB开发者的50条建议 #Tip 3

#第三条 尝试在单条查询中去获取数据(Try to fetch data in a single query)

在这条里面首先需要明白一个概念,叫做“应用单元(application unit)”。如果你开发的是一个Web应用或是移动应用,你可以将之理解为向后端发起的一次请求。另外一些例子,比如:

  • 在桌面应用程序中,应用单元可能就是一次用户交互。
  • 在分析系统中,应用单元也许就是一次图表的加载。

应用单元基本上就是指你应用程序中会进行数据库访问的离散单元。

MongoDB数据模型应该针对每个应用单元去做查询。

Example: a blog
假设我们正在设计一个博客程序,一次请求博客文章的过程应该是一个应用单元。当我们去显示一篇博文,需要的数据有博文内容、标签、作者的信息、以及博文的评论。因此,我们会将这些所有的信息都嵌入到博文文档(post document)中去,然后我们通过一次查询去获取所需的所有数据。
记住我们的目标是做一次查询,而不是在一个文档中查。有时候我们一次查询会返回多个文档或者文档的一部分(not evry field)。例如:主页可能需要从博文(post)文档集合中取最新的10篇博文,但只需要标题、作者、和摘要:

 > db.posts.find({},{"title":1,"author":1,"slug":1,"_id":0}).sort({"date":-1}).limit(10)

会有一个用来显示给定标签下面最新的20篇博文的页面:

 > db.posts.find({"tag":someTag},{"title":1,"author":1,"slug":1,"_id":0}).sort.limit(20)

还有有一个包含所有作者完整资料的作者集合(authors collection),作者页面很简单,仅仅是作者集合(authors collection)中的一个作者文档(author document):

 > db.authors.findOne({"name":authorName})

博文集合(posts collection)中的的文档(document)也许会包含作者文档(author document)中的一些信息:作者名称和缩略图。

需要注意的是:尽管先前的例子中单次查询都是只与一个文档交互,这并不是说应用单元就应该只查询单个文档。事实上有许多情况应用单元需要通过单次查询来查询多个文档中的数据。

Example: an image board
假设我们有一个贴图板,用户可以在新的或是已经存在的线程中发布图片和文字。这个程序中有一个应用单元是在同一个线程中查看20条贴图信息,所以我们会将每个人的贴子(post)分别存储为帖子集合(posts collection)的文档。当我们需要显示的时候,会做如下查询:

 > db.posts.find({"threadId":id}).sort({"date":1}).limit(20)

当我们需要查看下一页的时候,我们做下面的查询:

 > db.posts.find({"threadId":id,"date":{"$gt":latestDateSeen}}).sort({"date":1}).limit(20)

然后我们会在{threadId:1,date:1}上面加索引,来提高查询效率。

当你的应用程序变得很复杂并且用户和经理又需要添加很多新特性的时候,请不要因为需要在一个应用单元中做多于一次的查询而感到沮丧.”one-query-per-unit”的目标是一个良好的起点和衡量初始设计是否合理的一个度量标准,现实的情况是很复杂的。在十分复杂的应用程序中,你可能会为其功能特性使用多于一条的查询。

如何成为一名黑客(转)

本文转自 http://www.aka.org.cn/Docs/hacker-howto_2001.html
这篇文档中所阐述的黑客价值观,深深地影响了我,我也希望它能影响到更多的人。

全文如下:

为什么会有这份文档?

作为 Jargon File 的编辑和 一些其他有名的类似性质文章的作者,我经常收到充满热情的网络新手的email提问(确实如此) “我如何才能成为一名出色的黑客?”非常奇怪的是似乎没有任何的FAQ或者Web形式的文档来说明这个 十分重要的问题,因此我写了一份。

如果你现在读的是这份文档的离线拷贝,那么请注意当前最新版本(英文版)在 http://www.tuxedo.org/~esr/faqs/hacker-howto.html可以得到。

注意:在这份文档最后有 FAQ(常问问题解答)。 请在向我提出任何关于这份文档的疑问之前读两遍。

目前这份文档有很多翻译版本: 保加利亚语, 简体中文, 繁体中文, 丹麦语, 荷兰语, 法语, 德语, 匈牙利语, 印尼语, 日语, 朝鲜语, 葡萄牙语, 俄语及 瑞典语。 注意由于这份文档时有修正,所以以上翻译版本可能有不同程度的过时。

什么是黑客?

Jargon File 包含了一大堆关于“hacker”这个词的定义,大部分与技术高超和热衷解决问题 及超越极限有关。但如果你只想知道如何 成为 一名黑客, 那么只有两件事情确实相关。

这可以追溯到几十年前第一台分时小型电脑诞生, ARPAnet 实验也刚展开的 年代,那时有一个由程序设计专家和网络名人所组成的, 具有分享特点的文化社群。 这种文化的成员创造了 “hacker” 这个名词。黑客们建立了 Internet。 黑客们发明出了现在使用的 UNIX 操作系统。黑客们使 Usenet 运作起来, 黑客们让 WWW 运转起来。如果你是这个文化的一部分,如果你对这种文化有所贡献,而且 这个社群的其它成员也认识你并称你为 hacker, 那么你就是一位黑客。

黑客精神并不仅仅局限在软件的黑客文化中。 有人用黑客态度对待其它事情,如电子学和音乐—— 事实上,你可以在任何最高级别的科学和艺术活动中发现它。 精于软件的黑客赞赏这些在其他领域的同类并把他们也称作黑客—— 有人宣称黑客天性是绝对独立于他们工作的特定领域的。 但在这份文档中, 我们将注意力集中在软件黑客的技术和态度, 以及发明了“黑客”一词的以共享为特征的文化传统之上。

有一群人大声嚷嚷着自己是黑客,但他们不是。 他们(主要是正值青春的少年)是一些蓄意破坏计算机和电话系统的人。 真正的黑客把这些人叫做“骇客”(cracker),并不屑与之为伍。 多数真正的黑客认为骇客们又懒又不负责任,还没什么大本事。 专门以破坏别人安全为目的的行为并不能使你成为一名黑客, 正如 用铁丝偷开走汽车并不能使你成为一个汽车工程师。 不幸的是,很多记者和作家往往错把“骇客”当成黑客; 这种做法一直使真正的黑客感到恼火。

根本的区别是:黑客搞建设,骇客搞破坏。

如果你想成为一名黑客,请接着读下去。如果你想做一个骇客,去读 alt.2600 新闻组,并在意识到你并不像自己想象的那么聪明后去坐五到十次监狱。 关于骇客,我只想说这么多。

继续阅读

给MongoDB开发者的50条建议 #Tip 2

#第二条 要使你的数据面向未来,那么就对数据进行规范化(Normalize if you need to future-proof data)

“面向未来的规范的数据”就是指在未来,不同的应用程序能够以各种不同的方式对规范化过的数据进行查询。
这就假定了你有一些数据集合是要被许多应用程序年复一年的使用,有些数据集合是像这样的,但大多数人的数据是不断发展变化的,一些旧的数据会被更新或是丢弃。大多数的人都希望自己现在的查询能够尽可能的快速高效,但是如果他们在将来改变这些查询,他们将要为新的查询去优化数据库。

另外,如果一个应用很成功,其数据集往往变得非常特定于应用程序。这并不是说该数据集不能被应用于多个应用程序,通常你会考虑在其上做“荟萃分析”(meta-analysis)。但是这很难等同于“面向未来”所追求的“在10年内人们可以做任何他们想要的查询”。

#我的评注:

其实这里的“规范化(Normalization)”并不是指关系型数据库中的”规范化”。这里的规范化其实指的是“reference objects in a different collection”。就是使用我们“#第一条“中的引用。

读完这条我有些云里雾里,所以查阅了一些资料,StackOverflow上有一则关于MongoDB Normalization的问答让我高清了一些问题:
http://stackoverflow.com/questions/5841681/mongodb-normalization-foreign-key-and-joining-question

一见倾心的coffeescript(一)简介及安装

CoffeeScript是什么?简单的说就是javascript的一件漂亮外衣。正式的说就是“CoffeeScript is a little language that compiles into JavaScript.”。CoffeeScript的设计灵感源于ruby和python,拥有优雅的语法构成,最终会被编译成Javascript。

那么使用CoffeeScript比起原生的Javascript又有什么优势呢?

首先,降低了代码量。CoffeScript非常简洁,它有一些很简洁的特性,比如array comprehensions, prototype aliases, classes等等,使用这些特性能大大降低代码量。
其次,更具有亲和力。Javascript有很多迷惑新手的地方,而CoffeeScript则巧妙的避开了这些。

体验CoffeeScirpt最简单的方式就是在浏览器中直接使用。进入http://coffeescript.org,点击导航栏上的“TRY COFFEESCRIPT”,左边输入CoffeeScript,右边就会被转换为Javascript。

其实,还可以通过基于浏览器编译的方式来使用CoffeeScirpt,在你的页面文件中引入如下脚本:

<script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js"
type="text/javascript" charset="utf-8"></script>
<script type="text/coffeescript">
# 在这里写入CoffeeScript
</script>

不过这种方式是在运行时解释执行,效率比较低,实际项目中不会选择使用这种方式。

继续阅读

给MongoDB开发者的50条建议 #Tip 1

对于MongoDB,面临的最大问题就是如何为应用程序设计出良好的数据模型,大家都是摸着石头过河,意见很难达成一致。最近读了O‘REILLY的一本小册子《50 Tips & Tricks for MongoDB Developers》受益匪浅,所以决定将其中的内容翻译出来。并结合自己实际感受给予评注。

#第一条 为了速度去重复数据,为了完整性去引用数据(Duplicate data for speed,reference data for integrity

多个文档中的数据能够被“嵌入”(embed)或是“引用”(reference)。很难说“嵌入”的方式就一定比“引用”好,反之亦然。每种方式都有自己用处,而你应该为你的应用程序去选择合适的方式。
“嵌入”会引起数据的“不一致”:假设你想把(图1.1)中的苹果变成梨,如果你更改了其中一个文档中的值,但恰巧在就要更改第二个文档的值之前系统崩溃了,那么你的数据库中对于fruit会出现两个不同的值。

继续阅读

Ubuntu下设置环境变量

在Ubuntu中有如下几个文件可以设置环境变量:

1. /etc/profile:在登录时,操作系统定制用户环境时使用的第一个文件,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行.

2. /etc/environment:在登录时操作系统使用的第二个文件,系统在读取你自己的profile前,设置环境文件的环境变量.

3. ~/.bash_profile:在登录时用到的第三个文件是.profile文件,每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件.

4. /etc/bash.bashrc:为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取.

5. ~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取.

继续阅读

2012年第一天 洛克的BLOG开张啦!

以前也写博客,东写写,西写写,没有固定的地方,写的东西也不成系统,最重要的是没有毅力坚持下来。

2012年打算好好的把自己的博客写起来,一方面是总结和梳理一下知识系统,另一方面可以督促一下自己,一定要坚持补充新知识啊!

留下此文给自己的博客奠基!