[英]Managing relationships with MongoDb in a Microservices architecture
我使用微服務已經有一段時間了,總是使用關系數據庫。 我正在查看 MongoDb,但我不確定如何處理涉及不同微服務的實體關系。 這是一個例子:
public class Employee implements Serializable {
private String id;
...
}
public class Department implements Serializable {
private String id;
private String desc;
private List<Employee> employees = new ArrayList<>();
...
}
這兩個實體由兩個不同的微服務管理,具有由Department
實體管理的一對多關系。 到目前為止,一切都很好。
使用關系數據庫(作為一個可選關系,並且一名員工可能屬於多個部門),我會在Departments
微服務中使用 map ,其中一個表包含兩個字段: employee_id
和department_id
。 當客戶端調用getDepartmentWithEmployees(depId)
時,此微服務將讀取表並從Employees
微服務中獲取適當的員工。
但是,據我所知,在 MongoDb 數據庫中,當我存儲Department
object 時,它存儲所有關聯的Employee
。 這不是重復信息嗎? 有沒有辦法,也許,MongoDb 不存儲有關員工的所有信息,而只存儲他們的 ID? 還是有別的答案?
我很確定這是一個非常基本的問題,但我對所有這些東西都很陌生。
提前致謝。
但是,據我所知,在 MongoDB 數據庫中,當我存儲部門 object 時,它會存儲所有相關的員工。 這不是重復信息嗎?
首先,上面的說法是不正確的。 從 MongoDB 的角度來看,作為 BSON 提供的任何內容都按原樣存儲。 如果您為員工提供部門,那么是的,它應該。 您可以在創建部門后應用部分更新...(例如使用$set
運算符)。 但是,我認為您的問題的 scope 比這更廣泛。
恕我直言,為數據庫中的每個文檔/表創建納米服務不是一個好方法。 特別是當服務只負責基本的 CRUD 操作時。 您應該首先定義您的有界上下文、聚合根等... 簡而言之,在將業務需求映射到域對象之前不要嘗試設計表。 我想說的是使用 DDD 原則:)
這些是我目前發現的策略。 在設計微服務時,您還應該考慮每種策略的優缺點。 (參見底部的參考資料。)
可以通過兩種方式映射 1:1 關系;
表:
// Employee document
{
"id": 123,
"Name":"John Doe"
}
// Address document
{
"City":"Ankara",
"Street":"Genclik Street",
"Nr":10
}
{
"id": 123,
"Name":"John Doe",
"Address": {
"City":"Ankara",
"Street":"Genclik Street",
"Nr":10
}
}
{
"id": 763541685, // link this
"Name":"John Doe"
}
帶文件密鑰的地址;
{
"employee_id": 763541685,
"City":"Ankara",
"Street":"Genclik street",
"Nr":10
}
最初的:
// Department collection
{
"id": 1,
"deparment_name": "Software",
"department_location": "Amsterdam"
}
/// Employee collection
[
{
"employee_id": 46515,
"employee_name": "John Doe"
},
{
"employee_id": 81584,
"employee_name": "John Wick"
}
]
警告:
{
"id": 1,
"deparment_name": "Software",
"department_location": "Amsterdam",
"employess": [
{
"employee_id": 46515,
"employee_name": "John Doe"
},
{
"employee_id": 81584,
"employee_name": "John Wick"
}
]
}
我們可以從員工文檔中鏈接 department_id。
Retrieve all employees that are belong to department X.
這個查詢需要大量的讀取操作![
{
"employee_id": 46515,
"employee_name": "John Doe",
"department_id": 1
},
{
"employee_id": 81584,
"employee_name": "John Wick",
"department_id": 1
}
]
我們將員工分成多個桶,每個桶中最多有 100 名員工。
{
"id":1,
"Page":1,
"Count":100,
"Employees":[
{
"employee_id": 46515,
"employee_name": "John Doe"
},
{
"employee_id": 81584,
"employee_name": "John Wick"
}
]
}
要選擇Two Way Embedding或One Way Embedding ,用戶必須確定 N 的最大尺寸和 M 的尺寸。
例如; 如果 N 是一本書最多 3 個類別,M 是一個類別中最多 5,000,000 本書,則您應該選擇 One Way Embedding。
如果 N 最大為 3,M 最大為 5,則雙向嵌入可能會很好地工作。 架構基礎
在雙向嵌入中,我們將在作者文檔的 book 字段下包含 Book 外鍵。
作者合集
[
{
"id":1,
"Name":"John Doe",
"Books":[ 1, 2 ]
},{
"id":2,
"Name": "John Wick",
"Books": [ 2 ]
}
]
藏書:
[
{
"id": 1,
"title": "Brave New World",
"authors": [ 1 ]
},{
"id":2,
"title": "Dune",
"authors": [ 1, 2 ]
}
]
示例書籍和類別:案例是幾本書屬於幾個類別,但幾個類別可以有很多書。
類別
[
{
"id": 1,
"category_name": "Brave New World"
},
{
"id": 2,
"category_name": "Dune"
}
]
具有Categories
外鍵的Book
文檔示例
[
{
"id": 1,
"title": "Brave New World",
"categories": [ 1, 2 ],
"authors": [ 1 ]
},
{
"id": 2,
"title": "Dune",
"categories": [ 1],
"authors": [ 1, 2 ]
}
]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.