MongoDB 關係實現

小強Zzz 發表於 2022-06-27
MongoDB

前言

MongoDB不同於我們常用的mysql,作為一款非關係型資料庫,資料儲存已類似於json格式儲存在文件裡,不存在外建,無法實現mysql的表格之間關聯。那麼,對於一對一,一對多,多對一,多對多關係如何實現呢?

一對多

對於一條班級資料

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "name": "軟體181班",
   "number": "36"
}

與多條學生資料

{
   "_id":ObjectId("52ffc33cd85242f436000002"),
   "name": "張三",
   "num": "185762",
   "address": "河北省XX市"
}
{
   "_id":ObjectId("52ffc33cd85242f436000003"),
   "name": "李四",
   "num": "185763",
   "address": "河北省XX市"
}

有嵌入和引用兩種方法

嵌入

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "name": "軟體181班",
   "number": "36",
   "student": [
      {
        "name": "張三",
        "num": "185762",
        "address": "河北省XX市"
      },
      {
        "name": "李四",
        "num": "185763",
        "address": "河北省XX市"
      }]
}

優點是一次查詢便可找到關聯資料。
缺點是隨著關聯資料量的增加,會增加讀寫時間。

引用

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "name": "軟體181班",
   "number": "36",
   "student_ids": [
      ObjectId("52ffc4a5d85242602e000001"),
      ObjectId("52ffc4a5d85242602e000002")
    ]
}

引用方式,對於學生基礎資料儲存在學生表,一條班級資料只儲存所有相關學生id。
關聯查詢時,需要兩次查詢,第一次查詢班級資訊,第二次使用班級關聯學生id查詢學生資訊。
優點是當大量關聯資料時減少一次讀寫時間。
缺點是造成多次查詢,增加查詢時間。

多對多

對於多對多關係我們需要具體問題具體分析。
比如圖書和標籤多對多。只需要查詢圖書對應標籤,而沒有通過標籤查詢圖書功能(假如沒有)。那麼只需要在一張表去記錄圖書和標籤資料即可。

{
   "_id":ObjectId("00000111111"),
   "name": "計算機組成原理",
   "tag": [
      {
        "name": "計算機",
      },
      {
        "name": "考研",
      }]
}
{
   "_id":ObjectId("00000111111"),
   "name": "湯家鳳高等數學18講",
   "tag": [
      {
        "name": "數學",
      },
      {
        "name": "考研",
      }]
}

但是對於課程和班級多對多來講,我們有時需要查詢班級上哪幾門課程,有時需要查詢這門課程都哪幾個班級上,但是大多情況下都是查詢班級上哪幾門課程。我們就可以設定一個班級表,一個課程表,在班級表下關聯相關課程。
班級表

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "name": "軟體181班",
   "number": "36",
   "klass_ids": [
      ObjectId("52ffc4a0001"),
      ObjectId("52ffc4a0002")
    ]
}
{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "name": "軟體182班",
   "number": "35",
   "klass_ids": [
      ObjectId("52ffc4a0001"),
      ObjectId("52ffc4a0003")
    ]
}

課程表

{
   "_id":ObjectId("52ffc4a0001"),
   "name": "資料結構",
}
{
   "_id":ObjectId("52ffc4a0002"),
   "name": "計算機網路",
}
{
   "_id":ObjectId("52ffc4a0003"),
   "name": "軟體工程",
}

對於大多數情景,我們可以通過班級查詢有哪些課程。對於課程查詢有哪些班級,我們也可以通過語句反查。

總結

對比Mysql來說,NoSql相對於更加靈活,我們應拋棄mysql的思想,服務於我們的場景去設計資料庫。