zoukankan      html  css  js  c++  java
  • mongodb指南(翻译)(十四) developer zone 数据类型和约定(三)之数据库引用

    由于mongodb是非关系型的(没有连接(join)),文档间的引用(“外键”)通常是在客户端通过向服务器进行额外查询来解决的(linking)。

    这些连接总是在客户端解决的。直接/手动做这些是非常容易并且也是推荐这样做的。

    这里还有一个很多驱动都支持的DBRef机制,它在一定程度上抽象了linking的概念。推荐的方法是使用直接/手动link

    内嵌对象是对linking的一种备选方案并且很多时候它非常合适和表现优秀。

    简单的直接/手动linking

    通常,手动编写link解决方案就可以很好工作并且也很简单。我们存储_id中的值到数据库的其他文档,稍后对它进行查询。例如:

    > // grab a random blog post:
    > p = db.postings.findOne();
    {
    "_id" : ObjectId("4b866f08234ae01d21d89604"),
    "author" : "jim",
    "title" : "Brewing Methods"
    }
    > // get more info on author of post p. this is the "linking" step.
    > a = db.users.findOne( { _id : p.author } )
    { "_id" : "jim", "email" : "jim@gmail.com" }
    > // inverse: given an author, find all blog posts for the author
    > db.postings.find( {author : a._id } )

    DBRef

    DBRef是一种创建文档间引用的更加正式的规范。DBRefs(通常)除了对象id外还包含一个集合名称。大多数开发者只在文档中的集合可以改变为其他的时候才使用DBRef。如果你引用的集合总是相同的,那么上面描述的手动引用会更加高效。

    DBRef是在同一个数据库中一个文档对另一个文档的引用。一个数据库引用是标准的内嵌(JSON/BSON)对象:我们定义的一种约定,不是一个特殊类型。通过使用标准方法来表现,驱动和数据框架可以添加助手方法按照标准方法来操作引用。

    在某些驱动中DBRef有一个优点,允许可选的原子性的客户端解引用。在很多场景中,你可以只是把_id存储为引用,然后按照前面“简单手动引用”章节所说进行解引用。

    DBRef引用值的语法是:

    { $ref : <collname>, $id : <idvalue>[, $db : <dbname>] }

    <collname>是被引用的集合名(没有数据库名),<idvalue>是引用对象的字段_id的值。$db是可选的(目前大部分驱动还不支持)并且允许引用的文档是其他数据库的(由<dbname>指定)。

    不同语言/驱动中的DBRef

    C#

    使用DBRef类。构造函数的参数是集合名和_id。然后你可以使用Database类中的FollowReference方法来获取引用文档。

    C++

    c++驱动尚没有提供方法来自动遍历DBRefs。当然你还是可以手动来完成的。

    Java

    java使用DBRef类支持DB引用。

    Javascript(mongo shell)

    例子:

    > x = { name : 'Biology' }
    { "name" : "Biology" }
    > db.courses.save(x)
    > x
    { "name" : "Biology", "_id" : ObjectId("4b0552b0f0da7d1eb6f126a1") }
    > stu = { name : 'Joe', classes : [ new DBRef('courses', x._id) ] }
    // or we could write:
    // stu = { name : 'Joe', classes : [ {$ref:'courses',$id:x._id} ] }
    > db.students.save(stu)
    > stu
    {
    "name" : "Joe",
    "classes" : [
    {
    "$ref" : "courses",
    "$id" : ObjectId("4b0552b0f0da7d1eb6f126a1")
    }
    ],
    "_id" : ObjectId("4b0552e4f0da7d1eb6f126a2")
    }
    > stu.classes[0]
    { "$ref" : "courses", "$id" : ObjectId("4b0552b0f0da7d1eb6f126a1") }
    > stu.classes[0].fetch()
    { "_id" : ObjectId("4b0552b0f0da7d1eb6f126a1"), "name" : "Biology" }
    >

    Perl

    perl驱动没有提供方法自动遍历DBRefs,但是有一个CPAN包:MongoDBx::AutoDeref.当然你还可以手动遍历他们。

    PHP

    除了在数据库层面(MongoDB::createDBRef和MongoDB::getDBRef)和集合层面(MongoCollection::createDBRef和MongoCollection::getDBRef)的创建和解引用方法外,PHP还提供了MongoDBRef类来支持DB引用。

    Python

    在python中使用bson.dbref.DBRef类来创建一个DB引用。你还可以使用Database实例中的dereference方法让解引用变得更加容易。

    Ruby

    Ruby也使用DBRef类和DB实例中的dereference方法来支持DB引用。例如:

    @db = Connection.new.db("blog")
    @user = @db["users"].save({:name => "Smith"})
    @post = @db["posts"].save({:title => "Hello World", :user_id => @user.id})
    @ref = DBRef.new("users", @post.user_id)
    assert_equal @user, @db.dereference(@ref)
  • 相关阅读:
    关于binary log一点总结[转]
    使用mysql索引技巧及注意事项
    优化php性能的一点总结
    html静态页面实现微信分享思路
    MySql字符串函数使用技巧
    Oracle计算时间差函数
    oracle10g获取Date类型字段无时分秒解决办法!
    Oracle常用函数
    COALESCE操作符
    关于null的操作
  • 原文地址:https://www.cnblogs.com/xinghebuluo/p/2289110.html
Copyright © 2011-2022 走看看