Hướng dẫn mongodb foreign key relationships - mối quan hệ khóa ngoại mongodb

Hướng dẫn mongodb foreign key relationships - mối quan hệ khóa ngoại mongodb

Làm thế nào để tôi thiết kế một sơ đồ như vậy trong MongoDB? Tôi nghĩ rằng không có chìa khóa nước ngoài!

Đã hỏi ngày 13 tháng 6 năm 2011 lúc 17:40Jun 13, 2011 at 17:40

Mark Pegasovmark PegasovMark Pegasov

4.9599 Huy hiệu vàng25 Huy hiệu bạc 30 Huy hiệu Đồng9 gold badges25 silver badges30 bronze badges

4

Làm thế nào để thiết kế bàn như thế này trong MongoDB?

Đầu tiên, để làm rõ một số quy ước đặt tên. MongoDB sử dụng collections thay vì tables.

Tôi nghĩ rằng không có chìa khóa nước ngoài!

Lấy mô hình sau:

student
{ 
  _id: ObjectId(...),
  name: 'Jane',
  courses: [
    { course: 'bio101', mark: 85 },
    { course: 'chem101', mark: 89 }
  ]
}

course
{
  _id: 'bio101',
  name: 'Biology 101',
  description: 'Introduction to biology'
}

Rõ ràng danh sách khóa học của Jane chỉ ra một số khóa học cụ thể. Cơ sở dữ liệu không áp dụng bất kỳ ràng buộc nào cho hệ thống (tức là: các ràng buộc khóa nước ngoài), do đó, không có "Cascading xóa" hoặc "Cập nhật xếp tầng". Tuy nhiên, cơ sở dữ liệu có chứa thông tin chính xác.

Ngoài ra, MongoDB có tiêu chuẩn DBREF giúp tiêu chuẩn hóa việc tạo các tài liệu tham khảo này. Trong thực tế, nếu bạn xem xét liên kết đó, nó có một ví dụ tương tự.

Làm thế nào tôi có thể giải quyết nhiệm vụ này?

Để rõ ràng, MongoDB không quan hệ. Không có "dạng bình thường" tiêu chuẩn. Bạn nên mô hình hóa cơ sở dữ liệu của bạn phù hợp với dữ liệu bạn lưu trữ và các truy vấn bạn định chạy.

Frank Schmitt

29.3k11 Huy hiệu vàng69 Huy hiệu bạc105 Huy hiệu Đồng11 gold badges69 silver badges105 bronze badges

Đã trả lời ngày 13 tháng 6 năm 2011 lúc 18:03Jun 13, 2011 at 18:03

3

Bạn có thể quan tâm đến việc sử dụng một ORM như Mongoid hoặc Mongomapper.

http://mongoid.org/docs/relations/referenced/1-n.html

Trong cơ sở dữ liệu NoQuery như MongoDB không có 'bảng' mà là các bộ sưu tập. Tài liệu được nhóm lại bên trong các bộ sưu tập. Bạn có thể có bất kỳ loại tài liệu nào - với bất kỳ loại dữ liệu nào - trong một bộ sưu tập duy nhất. Về cơ bản, trong cơ sở dữ liệu NoQuery, tùy thuộc vào bạn để quyết định cách tổ chức dữ liệu và các mối quan hệ của nó, nếu có.

Những gì Mongoid và Mongomapper làm là cung cấp cho bạn các phương pháp thuận tiện để thiết lập quan hệ khá dễ dàng. Kiểm tra liên kết tôi đã cung cấp cho bạn và hỏi bất cứ điều gì.

Edit:

Trong Mongoid, bạn sẽ viết sơ đồ của mình như thế này:

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

Edit:

> 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" }

Bạn có thể sử dụng ObjectID đó để thực hiện quan hệ giữa các tài liệu.

Renno

2.5491 Huy hiệu vàng23 Huy hiệu bạc51 Huy hiệu đồng1 gold badge23 silver badges51 bronze badges

Đã trả lời ngày 13 tháng 6 năm 2011 lúc 17:46Jun 13, 2011 at 17:46

NeriannerianNerian

15.6K12 Huy hiệu vàng65 Huy hiệu bạc94 Huy hiệu đồng12 gold badges65 silver badges94 bronze badges

7

Chúng ta có thể xác định cái gọi là foreign key trong MongoDB. Tuy nhiên, chúng ta cần duy trì tính toàn vẹn dữ liệu của chính mình. Ví dụ,BY OURSELVES. For example,

student
{ 
  _id: ObjectId(...),
  name: 'Jane',
  courses: ['bio101', 'bio102']   // <= ids of the courses
}

course
{
  _id: 'bio101',
  name: 'Biology 101',
  description: 'Introduction to biology'
}

Trường

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
0 chứa
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
1 của các khóa học. Thật dễ dàng để xác định một mối quan hệ một-nhiều. Tuy nhiên, nếu chúng tôi muốn truy xuất tên khóa học của sinh viên
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
2, chúng tôi cần thực hiện một thao tác khác để truy xuất tài liệu
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
3 qua
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
1.It is easy to define a one-to-many relationship. However, if we want to retrieve the course names of student
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
2, we need to perform another operation to retrieve the
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
3 document via
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
1.

Nếu khóa học

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
5 bị xóa, chúng ta cần thực hiện một thao tác khác để cập nhật trường
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
0 trong tài liệu
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
7.

XEM THÊM: Thiết kế lược đồ MongoDB

Bản chất gõ tài liệu của MongoDB hỗ trợ các cách linh hoạt để xác định các mối quan hệ. Để xác định mối quan hệ một-nhiều:

Tài liệu nhúng

  1. Thích hợp cho một-few.
  2. Ưu điểm: Không cần thực hiện các truy vấn bổ sung cho một tài liệu khác.
  3. Nhược điểm: Không thể quản lý thực thể của các tài liệu nhúng riêng lẻ.

Example:

student
{
  name: 'Kate Monster',
  addresses : [
     { street: '123 Sesame St', city: 'Anytown', cc: 'USA' },
     { street: '123 Avenue Q', city: 'New York', cc: 'USA' }
  ]
}

Trẻ giới thiệu

Giống như ví dụ ________ 17/________ 13 ở trên.

Phụ huynh tham khảo

Thích hợp cho một đến một lần, chẳng hạn như tin nhắn nhật ký.

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
}

Hầu như,

> 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" }
0 là cha mẹ của
> 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" }
1. Tham khảo ID
> 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" }
0 tiết kiệm nhiều không gian cho rằng các thông báo nhật ký là squilions.

References:

  1. 6 Quy tắc ngón tay cái cho Thiết kế lược đồ MongoDB: Phần 1
  2. 6 Quy tắc ngón tay cái cho Thiết kế lược đồ MongoDB: Phần 2
  3. 6 Quy tắc ngón tay cái cho Thiết kế lược đồ MongoDB: Phần 3
  4. Mô hình mối quan hệ một-nhiều nhiều với tài liệu tham khảo tài liệu

Đã trả lời ngày 8 tháng 5 năm 2017 lúc 11:05May 8, 2017 at 11:05

JoyjoyJoy

9.24811 Huy hiệu vàng41 Huy hiệu bạc93 Huy hiệu Đồng11 gold badges41 silver badges93 bronze badges

1

Từ cuốn sách nhỏ MongoDB

Tuy nhiên, một lựa chọn khác để sử dụng các tham gia là từ chối dữ liệu của bạn. Trong lịch sử, việc denqualization được dành riêng cho mã nhạy cảm với hiệu suất hoặc khi dữ liệu phải được nhanh chóng (như trong nhật ký kiểm toán). Tuy nhiên, với sự phổ biến ngày càng tăng của NoQuery, nhiều người trong số đó không có sự tham gia, việc phi chính thức hóa như một phần của mô hình bình thường đang ngày càng trở nên phổ biến. Điều này không có nghĩa là bạn nên sao chép mọi thông tin trong mỗi tài liệu. Tuy nhiên, thay vì để sợ dữ liệu trùng lặp thúc đẩy các quyết định thiết kế của bạn, hãy xem xét mô hình hóa dữ liệu của bạn dựa trên thông tin thuộc về tài liệu nào.

So,

student
{ 
    _id: ObjectId(...),
    name: 'Jane',
    courses: [
    { 
        name: 'Biology 101', 
        mark: 85, 
        id:bio101 
    },
  ]
}

Nếu dữ liệu API RESTful, hãy thay thế ID khóa học bằng liên kết GET đến tài nguyên khóa học

Ben

52.3K48 Huy hiệu vàng171 Huy hiệu bạc217 Huy hiệu đồng48 gold badges171 silver badges217 bronze badges

Đã trả lời ngày 5 tháng 9 năm 2013 lúc 13:23Sep 5, 2013 at 13:23

ZakyzakyZAky

1.0847 Huy hiệu bạc21 Huy hiệu đồng7 silver badges21 bronze badges

2

Câu trả lời ngắn gọn: Bạn nên sử dụng "Tài liệu tham khảo yếu" giữa các bộ sưu tập, sử dụng các thuộc tính ObjectID:

Tài liệu tham khảo lưu trữ mối quan hệ giữa dữ liệu bằng cách bao gồm các liên kết hoặc tài liệu tham khảo từ tài liệu này sang tài liệu khác. Các ứng dụng có thể giải quyết các tham chiếu này để truy cập dữ liệu liên quan. Nhìn chung, đây là các mô hình dữ liệu được chuẩn hóa.

https://docs.mongodb.com/manual/core/data-modeling-introduction/#references

Điều này tất nhiên sẽ không kiểm tra bất kỳ tính toàn vẹn tham chiếu. Bạn cần xử lý "liên kết chết" ở phía bạn (mức ứng dụng).

Đã trả lời ngày 26 tháng 1 năm 2021 lúc 15:44Jan 26, 2021 at 15:44

EfrainefrainEfrain

3.0982 Huy hiệu vàng32 Huy hiệu bạc58 Huy hiệu đồng2 gold badges32 silver badges58 bronze badges

Mục đích của nước ngoài là để ngăn chặn việc tạo dữ liệu nếu giá trị trường không khớp với nước ngoài của nó. Để thực hiện điều này trong MongoDB, chúng tôi sử dụng Lược đồ giữa để đảm bảo tính nhất quán của dữ liệu.

Xin hãy xem tài liệu. https://mongoosejs.com/docs/middleware.html#pre

Đã trả lời ngày 1 tháng 7 năm 2020 lúc 18:35Jul 1, 2020 at 18:35

Tôi thấy không có lý do tại sao bạn không thể sử dụng NoQuery DB như một DB quan hệ vì bạn có các đường ống tổng hợp mà bạn có thể sử dụng để tạo các chế độ xem như các kết nối bên trong SQL.

Mỗi bộ sưu tập phải chứa một loại, ví dụ: Thứ tự và chi tiết đơn đặt hàng là mối quan hệ 1: m.

ID bộ sưu tập đơn hàng (PK) Loại: Guid OrderNo (ứng cử viên hoặc PK thay thế) orderdate customerId (fk) ... nhiều trường đặt hàng hơn
id (PK) Type: GUID
OrderNo (candidate or alternate PK)
OrderDate
Customerid (FK)
...more order fields

ID bộ sưu tập chi tiết đơn đặt hàng (PK) OrderID (FK) ProductID (fk) Qty ...
id (PK)
Orderid (FK)
Productid (FK)
Qty
...more fields

ID sản phẩm (PK) Nhà cung cấp (FK) Chi phí
id (PK)
Supplierid (FK)
Name
Cost

Và như thế.

Lý do tại sao bạn không chỉ đơn giản sử dụng cơ sở dữ liệu quan hệ là vì cơ sở dữ liệu NoQuery có các tính năng khác mà bạn có thể sử dụng song song với các bộ sưu tập dữ liệu được thiết kế theo quan hệ.

Cách bạn thực hiện các mối quan hệ giống như trong cơ sở dữ liệu quan hệ. Bạn phải tự thêm các khóa nước ngoài (các khóa chính được thêm tự động cho mỗi đối tượng tài liệu) và tạo các bộ sưu tập tham gia được chuẩn hóa. Một cơ sở dữ liệu sẽ không bình thường hóa thường.

Cấp độ duy nhất là bạn phải mã hóa tính toàn vẹn tham chiếu là NoQuery không làm điều đó (chưa). Vì vậy, trong UI quản trị viên của bạn nếu người dùng cố gắng xóa cha mẹ có con bạn ném lỗi thân thiện nói rằng họ phải xóa trẻ trước. Không khó nhưng bạn vẫn cần phải cẩn thận khi sử dụng các tiện ích DB không xóa cha mẹ có con vì DB sẽ cho phép bạn.

Luôn luôn sử dụng các quy ước đặt tên cho ID khóa ngoại. Ví dụ:

ID bộ sưu tập chi tiết đơn đặt hàng (PK) OrderID (FK) .... bạn dễ dàng suy luận rằng khóa ngoại là khóa chính trong bộ sưu tập thứ tự bằng cách gắn bó với quy ước đặt tên này.
id (PK)
Orderid (FK) .... you an easily deduce that this foreign key is the primary key in the Order collection by sticking to this naming convention.

Đã trả lời ngày 29 tháng 8 năm 2021 lúc 8:26Aug 29, 2021 at 8:26

2