iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
0
AI & Data

從入門到精通 MongoDB系列 第 9

Day09: NoSQL 中的關係(2) - 一對多關係

上一篇介紹了 MongoDB 中資料的關係,也介紹了 一對一關係,今天要來跟大家介紹第2種關係:一對多關係


一對多關係 One-to-Many Relationship

在上一篇「Day08: NoSQL 中的關係(1) - 一對一關係」文章中介紹一對一關係的範例裡,我們使用兩個 collections:people 及 address,來儲存每個人的個資及對應的地址,而一個人只會有一個地址,因此是一對一的關係。但現實生活中有許多對應關係是一對多的關係,例如每位顧客對應的訂單資訊,一個顧客很可能會有超過一筆的訂單資訊,因此,如果我們使用兩個 collections 來分別儲存顧客個資及訂單資訊,那這樣的關係就是 一對多關係

使用單一 collection

# customer
{
    "_id": 1,
    "name": "John Cart",
    "email": "jc@jc.com",
    "phone": 12345,
    "orders": [
        {
            "date": "2018-12-10",
            "product": "book",
            "cost": 19.99
        },
        {
            "date": "2018-12-13",
            "product": "book",
            "cost": 39.99
        },
        {
            "date": "2018-12-22",
            "product": "computer",
            "cost": 2899
        }
    ]
},
{
    "_id": 2,
    "name": "Arber Su",
    "email": "as@as.com",
    "phone": 56789,
    "orders": [
        {
            "date": "2018-12-01",
            "product": "book",
            "cost": 19.99
        },
        {
            "date": "2018-12-29",
            "product": "computer",
            "cost": 2899
        }
    ]
}

從上方的 BSON 可以看出來每個 document 都儲存了每位顧客的所有資訊,包含姓名、email、電話及所有訂單資訊,而訂單資訊是以嵌入式文件的方法來儲存每筆訂單的時間、產品、花費等資訊。

這種儲存方式會讓資料結構變得較為複雜,那什麼情況下適合使用這樣的方式呢?如果訂單的數量不多,那我們可以選擇把所有訂單資訊都存在一個 customer collection 中。這樣的儲存方式有以下的優缺點:

優點

  • 可以一次取得顧客的所有資訊

缺點

  • 不適合對所有訂單進行分析:假設我們想要查詢訂單的產品是書本的資料,則必須要遍歷所有 documents 的 orders 資料,再求總數量。

使用兩個 collections

# customer
{
    "_id": 1,
    "name": "John Cart",
    "email": "jc@jc,com",
    "phone": 12345,
    "orders": [1, 2, 3]
},
{
    "_id": 2,
    "name": "Arber Su",
    "email": "as@as.com",
    "phone": 56789,
    "orders": [4, 5]
}


# order
{
    "_id": 1,
    "date": "2018-12-10",
    "product": "book",
    "cost": 19.99
},
{
    "_id": 2,
    "date": "2018-12-13",
    "product": "book",
    "cost": 39.99
},
{
    "_id": 3,
    "date": "2018-12-22",
    "product": "computer",
    "cost": 2899
},
{
    "_id": 4,
    "date": "2018-12-01",
    "product": "book",
    "cost": 19.99
},
{
    "_id": 5,
    "date": "2018-12-29",
    "product": "computer",
    "cost": 2899
}

我們也可以使用兩個 collections:customer 及 order 來分別儲存顧客個資及訂單資訊。在上方的範例 BSON 裡可以看到,customer 這個 collection 儲存了兩位顧客的資訊,其中 order 這個 field 的 value 是該顧客對應的訂單在 order collection 中的 "_id" 所組成的 array。而在 order 這個 collection 中則儲存了 5 筆訂單資訊。

使用兩個 collections 的方法有以下的優缺點:

優點

  • 容易取得訂單資訊
  • 便於對訂單資訊進行分析:過濾、統計、計算

缺點

  • 要取得顧客的所有資訊不方便

範例1

例如我們想要查詢 "id": 1 的顧客資訊跟訂單資訊,則需先在 customers 取得顧客資訊,再依照 order id 在 orders 中取得訂單資訊

  1. db.customer.findOne({_id:1})

  2. db.customer.findOne({_id:1}).orders

  3. var a = db.customer.findOne({_id:1}).orders

  4. db.order.find({_id: {$in: a}})

範例2

如果我們一樣想要查詢書本的訂單有多少?則可以直接對 order collection 進行操作

  • db.order.find({product: "book"})

  • db.order.find({product: "book"}).count()

  • db.order.count({product: "book"})

該選擇哪種方法儲存資料?

依需求而定

  • 若需針對訂單做統計分析 → 分兩個 collections 儲存
  • 若沒有以上需求 → 將所有資料存在一個 collection 裡
  • order 數量很多 → 分兩個 collections 儲存資料

今天介紹了 MongoDB 中第2種關係:一對多關係,下一篇將會繼續介紹最後一種關係:多對多關係。


上一篇
Day08: NoSQL 中的關係(1) - 一對一關係
下一篇
Day10: NoSQL 中的關係(3) - 多對多關係
系列文
從入門到精通 MongoDB26
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言