第一週的文章主要介紹了 MongoDB 的 CRUD 操作及資料型態,今天則要開始介紹 MongoDB 中資料之間的 關係。
對於有學習過 SQL 的朋友應該很熟悉資料庫裡的各種關係(一對一、一對多、多對多),而雖然 MongoDB 是 NoSQL 資料庫,但一樣可以使用關係。
我們之前範例使用的資料都是在單一個 collection 裡存放所有的資料,如下:
{
"_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
}
]
}
上圖中每一個 document 裡儲存了每一個顧客的所有資料,包括的基本個資(姓名、email、電話)以及所有的訂單資訊(日期、產品、花費),其中訂單資訊是以嵌入式文件儲存成有層次的(layered) document 格式。
但這樣的儲存方式對於需要查詢訂單資訊會非常不方便,尤其當顧客的訂單資訊數量龐大時。因此,我們也可以改用兩個 collections 來儲存顧客資訊:
# customers
{
"_id": 1,
"name": "John Cart",
"email": "jc@jc.com",
"phone": 12345,
"orders": [1, 2, 3]
}
# orders
[
{
"_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
}
]
而這種儲存資料的方式我們可以說 「customers 和 orders 這兩個 collections 之間存在關係」。
以上分別用單個 collection 及兩個 collections 來儲存顧客的個資及訂單資訊,兩種方法都可以實作,但我們要如何選擇該使用哪種方法呢?主要有以下兩種考量:
一對一關係指的是兩個 collections 的其中一個 collection 中的 document 只會對應到另一個 collection 中的一個 document。例如在以下範例中,我們使用兩個 collections 來儲存每個人的個資及地址資訊,每個人只會對應到一個地址,所以這兩個 collections 之間是 一對一關係。
# people
{
"_id": 1,
"name": "John Cart",
"email": "jc@jc.com",
"phone": 12345,
"address": 1
}
# address
{
"_id": 1,
"city": "Shanghai",
"street": "aaaaa",
"building": 1,
"unit": 2,
"room": 1021
}
使用 findOne()
來分別查看這兩個 collections 的資訊
如果我們想要取得某人的地址,必須先在 people collection 查詢這個人的地址 id,再依這個地址 id 去 address collection 查詢地址:
而我們也可以把地址資訊直接存到 people 這個 collection 中
透過這樣的儲存方式,我們不需要使用兩個步驟才能查詢某人的地址資訊,可以直接在 people collection 中查詢到地址資訊:
如果我們只想查詢地址以外的其他個資,則可以透過 {address: 0}
的設定來查詢:
今天介紹了 MongoDB 中的其中一種關係:一對一關係,接下來兩篇會繼續分別介紹 一對多關係 及 多對多關係。