sql - mongodb linking




在mongo的外鍵? (3)

如何在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不是關係型的。 沒有標準的“正常形式”。 您應該根據您存儲的數據和要運行的查詢對數據庫進行建模。

如何在MongoDB中設計這樣的方案? 我覺得沒有外鍵!


來自The Little MongoDB Book

使用連接的另一種替代方法是對數據進行非規範化。 從歷史上看,非規範化是為性能敏感的代碼保留的,或者是應該對數據進行快照(如在審計日誌中)。 然而,隨著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的課程。 定義一對多關係很容易。 但是,如果我們想要檢索學生Jane的課程名稱,我們需要執行另一個操作來通過_id檢索course文檔。

如果刪除了課程bio101 ,我們需要執行另一項操作來更新student文檔中的courses字段。

更多:MongoDB架構設計

MongoDB的文檔類型特性支持靈活的方式來定義關係。 要定義一對多關係:

嵌入式文件

  1. 適合一對一。
  2. 優點:無需對其他文檔執行其他查詢。
  3. 缺點:無法單獨管理嵌入文檔的實體。

例:

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
}

實際上, hostlogmsg的父logmsg 。 引用host ID可以節省大量空間,因為日誌消息是萬億分之一。

參考文獻:

  1. 3 MongoDB架構設計的經驗法則:第1部分
  2. 3 MongoDB架構設計的經驗法則:第2部分
  3. 3 MongoDB架構設計的經驗法則:第3部分
  4. 與文檔參考的模型一對多關係




nosql