MongoDB에서 이와 같은 체계를 어떻게 설계합니까? 외래 키가 없다고 생각합니다!
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'
}
분명히 Jane의 코스 목록은 특정 코스를 가리 킵니다. 데이터베이스는 시스템에 어떠한 제약도 적용하지 않으므로 ( 예 : 외래 키 제약 ) "계단식 삭제"또는 "계단식 업데이트"가 없습니다. 그러나 데이터베이스에는 올바른 정보가 포함되어 있습니다.
또한 MongoDB에는 이러한 참조 생성을 표준화 하는 데 도움 이되는 DBRef 표준 이 있습니다. 실제로 해당 링크를 살펴보면 유사한 예가 있습니다.
이 작업을 어떻게 해결할 수 있습니까?
명확하게 말하면 MongoDB는 관계형이 아닙니다. 표준 "정규형"은 없습니다. 저장하는 데이터와 실행할 쿼리에 적합한 데이터베이스를 모델링해야합니다.
소위 foreign key
MongoDB에서 정의 할 수 있습니다 . 그러나 우리는 스스로 데이터 무결성을 유지해야합니다 . 예를 들면
student
{
_id: ObjectId(...),
name: 'Jane',
courses: ['bio101', 'bio102'] // <= ids of the courses
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
이 courses
필드에는 _id
코스 가 포함되어 있습니다. 일대 다 관계를 정의하는 것은 쉽습니다. 그러나 student의 코스 이름 Jane
을 검색하려면을 course
통해 문서를 검색하는 다른 작업을 수행해야합니다 _id
.
과정 bio101
이 제거되면 문서 의 courses
필드 를 업데이트하기 위해 다른 작업을 수행해야합니다 student
.
MongoDB의 문서 유형 특성은 관계를 정의하는 유연한 방법을 지원합니다. 일대 다 관계를 정의하려면
예:
student
{
name: 'Kate Monster',
addresses : [
{ street: '123 Sesame St', city: 'Anytown', cc: 'USA' },
{ street: '123 Avenue Q', city: 'New York', cc: 'USA' }
]
}
student
/ 처럼course
위 예 .
로그 메시지와 같은 일대 기법에 적합합니다.
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
}
사실상 a host
는 logmsg
. 참조host
ID를 하면 로그 메시지가 엉망인 경우 많은 공간이 절약됩니다.
참조 :
조인을 사용하는 또 다른 대안은 데이터를 비정규 화하는 것입니다. 역사적으로 비정규 화는 성능에 민감한 코드 또는 데이터를 스냅 샷해야하는 경우 (예 : 감사 로그)를 위해 예약되었습니다. 그러나 대부분이 조인이없는 NoSQL의 인기가 계속 높아지면서 일반 모델링의 일부인 비정규 화가 점점 보편화되고 있습니다. 그렇다고 모든 문서의 모든 정보를 복제해야하는 것은 아닙니다. 그러나 중복 데이터에 대한 두려움 때문에 설계 결정을 내리는 대신 어떤 정보가 어떤 문서에 속하는 지에 따라 데이터를 모델링하는 것이 좋습니다.
그래서,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{
name: 'Biology 101',
mark: 85,
id:bio101
},
]
}
RESTful API 데이터 인 경우 코스 ID를 코스 리소스에 대한 GET 링크로 바꿉니다.
ForeignKey의 목적은 필드 값이 해당 ForeignKey와 일치하지 않는 경우 데이터 생성을 방지하는 것입니다. MongoDB에서이를 수행하기 위해 데이터 일관성을 보장하는 스키마 미들웨어를 사용합니다.
설명서를 참조하십시오. https://mongoosejs.com/docs/middleware.html#pre