手動参照の使用は完全に問題ありません-でもお勧めします。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に変換する必要がありますが、これでは変換しないでください」と考える必要があります。
これは回避できたはずの問題ですが、代わりに導入されました。