[英]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.