【问题标题】:MongoDB, Using Mongodb ObjectID between collectionsMongoDB,在集合之间使用 Mongodb ObjectID
【发布时间】:2012-10-15 15:12:06
【问题描述】:

使用 PHP 和 MongoDB,我在同一个数据库中有一个称为 users 的集合和另一个称为 forms 的集合。

我使用 Mongodb ObjectID 作为表单集合中文档的用户标识符,将用户 ObjectId 保存为每个表单文档上的 uid。

我要在表单集合中创建 uid 字段的索引,但我的问题是我应该如何保存用户 Objectid?

到目前为止,我将其保存为普通字符串,例如(简化)

$collection->insert( array('formName'=>'The name','uid'=>'CURRENT_USERS_ObjectId_AS_string') );

在这种情况下,为类似 uid 创建 Mongodb ObjectID 是否符合逻辑或最佳实践

$collection->insert( array('formName'=>'The name','uid'=> new MongoId('CURRENT_USERS_ObjectId_AS_string')) );

【问题讨论】:

    标签: php mongodb


    【解决方案1】:

    manual references 的使用非常好 - 甚至推荐。仅在 DbRefs 提供特定好处时才使用它们 - 例如允许自动取消引用(mongo 脚本或 php 代码可以自动知道 foo 指向集合 x,id y [in database z])。

    不同的类型是糟糕的设计

    但要避免类型杂耍。

    在一个集合中拥有一个有效的外键,并且它与它所指向的集合的类型不同,这是一个糟糕的设计。一般来说,类型杂耍是从开发中消除的东西,而不是引入。

    想想数据库

    这样在数据库上运行的代码应该可以工作:

    form = db.forms.findOne();
    user = db.users.findOne({_id: form.user_id});
    

    用户集合 _id 字段的类型无关紧要。使用问题中的架构,此代码变为:

    form = db.forms.findOne();
    user = db.users.findOne({_id: new MongoId(form.user_id)});
    

    就其本身而言,这并不是一个巨大的差异,但这意味着您必须考虑/记住转换这些引用,如果/当创建使用不同类型的集合时,就会出现问题 - 它会引入不一致。

    考虑以下几点:

    > school = db.schools.insert({_id: 123, name: "my school"});
    > userId = new ObjectId();
    > db.users.insert({_id: userId, name: "Me"});
    > db.forms.insert({user_id: userId, school_id: 123});
    

    假设学校 ID 是唯一的代码。如果它不可能改变 - 用作 _id 字段是合适的,也是一个好主意。现在,学校 id 和用户 id 是不同的类型:

    > db.forms.findOne();
    {
    "_id" : ObjectId("508940370392baf87e68e31d"),
    "user_id" : ObjectId("5089401c0392baf87e68e31b"),
    "school_id" : 123
    }
    

    如果它们按原样存储,仍然可能完全不了解查询中的这些不同类型:

    form = db.forms.findOne();
    school = db.schools.findOne({_id: form.school_id});
    user = db.users.findOne({_id: form.user_id});
    

    如果使用了不同的类型,这意味着有必要考虑“使用这个集合我需要将字符串转换为一个ObjectId,但是对于这个我必须不是”。

    这是一个本可以避免的问题,但它被引入了。

    【讨论】:

    • 一个很好的观点,一个很好的答案!在这种情况下,我将坚持将键存储为字符串而不是 en ObjectId,因为我不确定如果字段是 ObjectId 类型,则在表单集合中索引 uid 字段是否会一样好。对此有什么想法吗?我的意思是索引的后果。
    • 有一个 existing question 涵盖了这一点。对象 ID 更小,因此比较起来更快
    • 是的关于类型杂耍的好点。让我看看我是否可以清理我的架构设计。谢谢:)
    • @AD7six 很抱歉跟进。只想确认一下。根据我的问题中的示例,您会选择替代方案 2,在存储 uid 时使用 new Mongoid() 而不是字符串?谢谢。
    • 是的,存储forms.uidusers._id完全相同
    【解决方案2】:

    现在我对 PHP 不熟悉,但您建议的架构设计很好。我在我的 c# 实现中使用了类似的结构。这里要清楚的是我的架构设计示例

    Account Class
    
    public  ObjectId Id{get;set;}
    public   string  Email {get;set}
    public   string  Password{get;set;}
    
    User Class
    
     public ObjectId Id{get;set;} 
     public string  AccountId {get;set}//refers to the ID in the account.
    

    现在,如果我想查询任何用户的帐户,我可以简单地使用用户类中的 accountId 进行查询。

    MongoDb 将这种引用技术称为手动引用,这也是它在这里推荐的一种方法是链接http://docs.mongodb.org/manual/applications/database-references/

    【讨论】:

    • 感谢您的好回答。我正在寻找来自 MongoDB 的信息,如上面发布的答案中的信息,但没有找到。我将选择具有正常索引的替代方案,因为这是您和供应商在文章中所建议的。
    猜你喜欢
    • 2020-05-10
    • 2014-05-12
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多