MongoDBでこのようなスキームを設計するにはどうすればよいですか?外部キーはないと思います!
MongoidやMongoMapperなどのORMの使用に興味があるかもしれません。
http://mongoid.org/docs/relations/referenced/1-n.html
MongoDBのようなNoSQLデータベースには、「テーブル」ではなくドキュメントがあります。ドキュメントはコレクション内にグループ化されます。単一のコレクションに、あらゆる種類のドキュメント、あらゆる種類のデータを含めることができます。基本的に、NoSQLデータベースでは、データとその関係があれば、それを整理する方法を決定するのはユーザー次第です。
MongoidとMongoMapperが行うことは、リレーションを非常に簡単に設定するための便利な方法を提供することです。私があなたに与えたリンクをチェックして、何かを尋ねてください。
編集:
Mongoidでは、次のようにスキームを記述します。
class Student
include Mongoid::Document
field :name
embeds_many :addresses
embeds_many :scores
end
class Address
include Mongoid::Document
field :address
field :city
field :state
field :postalCode
embedded_in :student
end
class Score
include Mongoid::Document
belongs_to :course
field :grade, type: Float
embedded_in :student
end
class Course
include Mongoid::Document
field :name
has_many :scores
end
編集:
> db.foo.insert({group:"phones"})
> db.foo.find()
{ "_id" : ObjectId("4df6539ae90592692ccc9940"), "group" : "phones" }
{ "_id" : ObjectId("4df6540fe90592692ccc9941"), "group" : "phones" }
>db.foo.find({'_id':ObjectId("4df6539ae90592692ccc9940")})
{ "_id" : ObjectId("4df6539ae90592692ccc9940"), "group" : "phones" }
そのObjectIdを使用して、ドキュメント間の関係を作成できます。
Mongodbでこのようにテーブルを設計する方法は?
まず、いくつかの命名規則を明確にします。 MongoDBは、collections
の代わりにtables
を使用します。
外部キーはないと思います!
次のモデルを使用します。
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{ course: 'bio101', mark: 85 },
{ course: 'chem101', mark: 89 }
]
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
明らかに、ジェーンのコースリストはいくつかの特定のコースを指しています。データベースはシステムに制約を適用しません()。つまり、外部キー制約)。したがって、「カスケード削除」または「カスケード更新」はありません。ただし、データベースには正しい情報が含まれています。
さらに、MongoDBには DBRef標準 があり、これらの参照の作成を標準化するのに役立ちます。実際、そのリンクを見ると、同様の例があります。
このタスクを解決するにはどうすればよいですか?
明確にするために、MongoDBはリレーショナルではありません。標準の「標準形式」はありません。保存するデータと実行するクエリに適したデータベースをモデル化する必要があります。
結合を使用するもう1つの方法は、データの非正規化です。歴史的に、非正規化は、パフォーマンスに敏感なコード、またはデータをスナップショットする必要がある場合(監査ログなど)に予約されていました。ただし、NoSQLの人気が高まり、その多くに結合が含まれていないため、通常のモデリングの一部としての非正規化がますます一般的になっています。これは、すべてのドキュメントのすべての情報を複製する必要があるという意味ではありません。ただし、データの重複を恐れて設計上の決定を下すのではなく、どの情報がどのドキュメントに属するかに基づいてデータをモデリングすることを検討してください。
そう、
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{
name: 'Biology 101',
mark: 85,
id:bio101
},
]
}
RESTful APIデータの場合、コースIDをコースリソースへのGETリンクに置き換えます
MongoDBでforeign key
と呼ばれるものを定義できます。ただし、データの整合性を維持する必要がありますBY OURSELVES。例えば、
student
{
_id: ObjectId(...),
name: 'Jane',
courses: ['bio101', 'bio102'] // <= ids of the courses
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
courses
フィールドには、_id
sのコースが含まれます。 1対多の関係を定義するのは簡単です。ただし、学生Jane
のコース名を取得する場合は、_id
を介してcourse
ドキュメントを取得する別の操作を実行する必要があります。
コースbio101
が削除された場合、courses
ドキュメントのstudent
フィールドを更新する別の操作を実行する必要があります。
MongoDBのドキュメントタイプの性質は、関係を定義する柔軟な方法をサポートします。 1対多の関係を定義するには:
例:
student
{
name: 'Kate Monster',
addresses : [
{ street: '123 Sesame St', city: 'Anytown', cc: 'USA' },
{ street: '123 Avenue Q', city: 'New York', cc: 'USA' }
]
}
上記のstudent
/course
の例のように。
ログメッセージなど、1対10に適しています。
Host
{
_id : ObjectID('AAAB'),
name : 'goofy.example.com',
ipaddr : '127.66.66.66'
}
logmsg
{
time : ISODate("2014-03-28T09:42:41.382Z"),
message : 'cpu is on fire!',
Host: ObjectID('AAAB') // Reference to the Host document
}
実質的に、Host
はlogmsg
の親です。 Host
idを参照すると、ログメッセージが大量にあるため、スペースを大幅に節約できます。
参照: