ฉันจะออกแบบโครงร่างนี้ใน MongoDB ได้อย่างไร ฉันคิดว่าไม่มีคีย์ต่างประเทศ!
ฉันจะออกแบบโครงร่างนี้ใน MongoDB ได้อย่างไร ฉันคิดว่าไม่มีคีย์ต่างประเทศ!
คำตอบ:
คุณอาจสนใจใช้ ORM เช่น Mongoid หรือ MongoMapper
http://mongoid.org/docs/relations/referenced/1-n.html
ในฐานข้อมูล NoSQL เช่น MongoDB ไม่มี 'ตาราง' แต่เป็นคอลเลกชัน เอกสารถูกจัดกลุ่มไว้ในคอลเล็กชัน คุณสามารถมีเอกสารประเภทใดก็ได้พร้อมข้อมูลประเภทใดก็ได้ในคอลเลกชันเดียว โดยพื้นฐานแล้วในฐานข้อมูล 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
ของหลักสูตร เป็นเรื่องง่ายที่จะกำหนดความสัมพันธ์แบบหนึ่งต่อกลุ่ม แต่ถ้าเราต้องการที่จะเรียกชื่อหลักสูตรของนักเรียน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
ตัวอย่างด้านบน
เหมาะสำหรับหนึ่งต่อ squillions เช่นข้อความบันทึก
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 จะช่วยประหยัดพื้นที่ได้มากเนื่องจากข้อความบันทึกเป็น squillions
อ้างอิง:
อีกทางเลือกหนึ่งในการใช้การรวมคือการทำให้ข้อมูลของคุณเป็นปกติ ในอดีตการทำให้เป็นปกติถูกสงวนไว้สำหรับโค้ดที่ไวต่อประสิทธิภาพหรือเมื่อข้อมูลควรถูกสแน็ปช็อต (เช่นในบันทึกการตรวจสอบ) อย่างไรก็ตามด้วยความนิยมที่เพิ่มขึ้นเรื่อย ๆ ของ NoSQL ซึ่งส่วนใหญ่ไม่มีการเชื่อมต่อการทำให้เป็นมาตรฐานเป็นส่วนหนึ่งของการสร้างแบบจำลองปกติกลายเป็นเรื่องปกติมากขึ้นเรื่อย ๆ นี่ไม่ได้หมายความว่าคุณควรทำซ้ำข้อมูลทุกชิ้นในทุกเอกสาร อย่างไรก็ตามแทนที่จะปล่อยให้ความกลัวว่าข้อมูลซ้ำจะขับเคลื่อนการตัดสินใจในการออกแบบของคุณให้พิจารณาสร้างแบบจำลองข้อมูลของคุณโดยพิจารณาจากข้อมูลที่เป็นของเอกสาร
ดังนั้น,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{
name: 'Biology 101',
mark: 85,
id:bio101
},
]
}
หากเป็นข้อมูล RESTful API ให้แทนที่รหัสหลักสูตรด้วยลิงก์ GET ไปยังทรัพยากรของหลักสูตร
วัตถุประสงค์ของ ForeignKey คือเพื่อป้องกันการสร้างข้อมูลหากค่าฟิลด์ไม่ตรงกับ ForeignKey ในการทำสิ่งนี้ให้สำเร็จใน MongoDB เราใช้โปรแกรมมิดเดิลแวร์ของ Schema เพื่อให้แน่ใจว่าข้อมูลมีความสอดคล้อง
โปรดดูเอกสารประกอบ https://mongoosejs.com/docs/middleware.html#pre