4

PHPとMongoDBを使用して、同じDB内にusersというコレクションとformsという別のコレクションがあります。

フォームコレクション内のドキュメントのユーザー識別子としてMongodbObjectIDを使用しており、各フォームドキュメントでユーザーObjectIdをuidとして保存しています。

フォームコレクションにuidフィールドのインデックスを作成しますが、私の質問は、ユーザーのObjectidをどのように保存する必要があるかということです。

今のところ私はそれを(簡略化された)のような通常の文字列として保存しています

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

これは論理的に見えますか、それともこの場合、次のようなuidのMongodbObjectIDを作成するためのベストプラクティスですか?

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

2 に答える 2

6

手動参照の使用は完全に問題ありません-でもお勧めします。DbRefsは、自動参照解除を許可するなど、特定の利点がある場合にのみ使用してください(mongoスクリプトまたはphpコードは、fooがコレクションxを指し、id y [データベースz]を使用していることを自動的に認識できます)。

異なるタイプは悪いデザインです

ただし、型ジャグリングは避けてください。

1つのコレクションに事実上外部キーであるものがあり、それが指しているコレクションのタイプとは異なるタイプであるということは、悪い設計です。型ジャグリングは、一般的に開発から排除するものであり、導入するものではありません。

データベースについて考える

dbで実行されたこのようなコードは機能するはずです:

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

また、userscollection_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に変換する必要がありますが、これでは変換しないでください」と考える必要があります

これは回避できたはずの問題ですが、代わりに導入されました。

于 2012-10-25T13:47:47.563 に答える
4

今、私は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/でも推奨されています。

于 2012-10-25T12:39:17.527 に答える