您的位置:知识库 » 数据库

IBM,DW,NoSQL,数据建模

来源: PHPChina.com  发布时间: 2010-08-04 11:09  阅读: 1651 次  推荐: 0   原文链接   [收藏]  
[1] IBM,DW,NoSQL,数据建模
[2] IBM,DW,NoSQL,数据建模

 

  清单7.查找程序的实际运行

def nrace = Race.findByName("Charlottesville Marathon")
assertnrace.distance ==26.2
def races = Race.findAllByName("Charlottesville Marathon")
assertraces.class== ArrayList.class

  清单 7中的查找程序按照既定的方式运行:findByName返回一个实例,而 findAllByName返回一个 Collection(假定有多个“Charlottesville Marathon”)。

现在我已能够创建并找到 Race的实例,现在可以创建一个快速的 Runner对象了。这个过程与创建初始的 Race实例一样简单,只需如清单 8 所示扩展 Model:

  清单 8.创建一个参赛者很简单

package com.b50.nosql class Runner extends Model
{ public Runner(params){ super(params)}}

  看看清单 8,我感觉自己几乎完成工作了。但是,我还需创建参赛者和比赛之间的链接。当然,我将把它建模为一个“多对多”关系,因为我希望我的参赛者可以参加多项比赛。

  没有架构的域建模

  Google App Engine 在 Bigtable 上面的抽象不是一个面向对象的抽象;即,我不能原样存储关系,但可以共享键。因此,为建模多个 Race和多个 Runner之间的关系,我将在每个 Race实例中存储一列 Runner键,并在每个 Runner实例中存储一列 Race键。

  我必须对我的键共享机制添加一点逻辑,但是,因为我希望生成的 API 比较自然—我不想询问一个 Race以获取一列 Runner键,因此我想要一列 Runner。幸运的是,这并不难实现。

  在清单 9 中,我已经添加了两个方法到 Race实例。但一个 Runner实例被传递到 addRunner方法时,它的对应 id被添加到底层 entity的 runners属性中驻留的 id的 Collection。如果有一个现成的 runners的 collection,则新的 Runner实例键将添加到它;否则,将创建一个新的 Collection,且这个 Runner的键(实体上的 id属性)将添加到它。

  清单9.添加并检索参赛者

def addRunner(runner)
{ if (this.@entity.runners)
{ this.@entity.runners << runner.id }
else{ this.@entity.runners = [runner.id] }}
def getRunners()
{ return this.@entity.runners.collect
 { new Runner( this.getEntity(Runner.class.simpleName, it))
}}

  当清单 9 中的 getRunners方法调用时,一个 Runner实例集合将从底层的 id集合创建。这样,一个新方法(getEntity)将在 Model类中创建,如清单 10 所示:

  清单10.从一个id 创建一个实体

def getEntity(entityType, id)
{ 
def key = KeyFactory.createKey(entityType, id) 
return this.@datastore.get(key)
}

  getEntity方法使用 Google 的 KeyFactory类来创建底层键,它可以用于查找数据存储中的一个单独实体。

  最后,定义一个新的构造函数来接受一个实体类型,如清单 11 所示:

  清单11.一个新添加的构造函数

public Model(Entity entity){ this.@entity = entity}

  如清单 9、10和 11、以及图 1的对象模型所示,我可以将一个 Runner添加到任一 Race,也可以从任一Race获取一列 Runner实例。在清单 12 中,我在这个等式的 Runner方上创建了一个类似的联系。清单 12 展示了 Runner类的新方法。

  清单12.参赛者及其比赛

def addRace(race)
{ if (this.@entity.races) 
{ this.@entity.races << race.id }
  else
{ this.@entity.races = [race.id] }} 
def getRaces()
{ return this.@entity.races.collect 
{ new Race( this.getEntity(Race.class.simpleName, it))
}}

  这样,我就使用一个无模式数据存储创建了两个域对象。

  通过一些参赛者完成这个比赛

  此前我所做的是创建一个 Runner实例并将其添加到一个 Race。如果我希望这个关系是双向的,如图1中我的对象模型所示,那么我也可以添加一些 Race实例到一些Runner,如清单 13 所示:

  清单 13.参加多个比赛的多个参赛者

def runner = new Runner([fname:"Chris", lname:"Smith", date:34])
runner.save() 
race.addRunner(runner)
race.save() 
runner.addRace(race)
runner.save()

  将一个新的 Runner添加到 race并添加对Race的save的调用后,这个数据存储已使用一列ID 更新,如图 3 中的屏幕快照所示:

  图3.查看一项比赛中的多个参赛者的新属性

 IBM dW NoSQL数据建模

  通过仔细检查Google App Engine 中的数据,可以看到,一个Race实体现在拥有了一个Runners 的list,如图 4 所示。

  图4.查看新的参赛者列表

IBM dW NoSQL数据建模 

  同样,在将一个 Race添加到一个新创建的 Runner实例之前,这个属性并不存在,如图 5 所示。

  图5.一个没有比赛的参赛者

 IBM dW NoSQL数据建模

  但是,将一个 Race关联到一个 Runner后,数据存储将添加新的 races ids 的 list。

  图6.一个参加比赛的参赛者

IBM dW NoSQL数据建模  

  无模式数据存储的灵活性正在刷新—属性按照需要自动添加到底层存储。作为开发人员,我无须更新或更改架构,更谈不上部署架构了!

  NoSQL 的利弊

  当然,无模式数据建模也有利有弊。回顾上面的比赛应用程序,它的一个优势是非常灵活。如果我决定将一个新属性(比如 SSN)添加到一个 Runner,我不必进行大幅更改—事实上,如果我将该属性包含在构造函数的参数中,那么它就会自动添加。对那些没有使用一个 SSN 创建的旧实例而言,发生了什么事情?什么也没发生!它们拥有一个值为 null的字段。

  另一方面,我已经明确表明要牺牲一致性和完整性来换取效率。这个应用程序的当前数据架构没有向我施加任何限制—理论上我可以为同一个对象创建无限个实例。在 Google App Engine 引擎的键处理机制下,它们都有惟一的键,但其他属性都是一致的。更糟糕的是,级联删除不存在,因此如果我使用相同的技术来建模一个“一对多”关系并删除父节点,那么我得到一些无效的子节点。当然,我可以实现自己的完整性检查—但关键是,我必须亲自动手(就像完成其他任务一样)。

  使用无模式数据存储需要严明的纪律。如果我创建各种类型的 Races —有些有名称,有些没有,有些有 date属性,而另一些有 race_date属性—那么我只是在搬起石头砸自己(或使用我的代码的人)的脚。

  当然,也有可能联合使用 JDO、JPA 和 Google App Engine。在多个项目上使用过关系模型和无模式模型后,我可以说 Gaelyk 的低级 API 最灵活,使用最方便。使用 Gaelyk 的另一个好处是能够深入了解 Bigtable 和一般的无模式数据存储。

  结束语

  流行时尚来了又去,有时无需理会它们(明智的建议来自一个衣橱里满是休闲服的家伙)。但 NoSQL 看起来不太像一种时尚,更像是高度可伸缩的 Web 应用程序开发的一个新兴基础。NoSQL 数据库不会替代 RDBMS,但是,它们将补充它。无数成功的工具和框架基于关系数据库,RDBMSs 本身似乎没有面临过时的危险。

  总之,NoSQL 数据库的作用是向对象——关系数据模型提供一个及时的替代方案。它们向我们展示,有些事情是可行的,并且对于一些特定的、高度强制的用例甚至更好。无模式数据库最适用于需要高速数据检索和可伸缩性的多节点 Web 应用程序。它们还有一个极好的副作用,即允许开发人员从一个面向域的视角、而不是关系视角进行数据建模。

[第1页][第2页]
0
0
 

数据库热门文章

    数据库最新文章

      最新新闻

        热门新闻