[英]Managing relationships with MongoDb in a Microservices architecture
I've been working with microservices for some time now, always with relational databases.我使用微服务已经有一段时间了,总是使用关系数据库。 I am looking at MongoDb and I am not sure how to handle entity relationships involving different microservices.
我正在查看 MongoDb,但我不确定如何处理涉及不同微服务的实体关系。 Here goes an example:
这是一个例子:
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<>();
...
}
These two entities are managed by two different microservices, with a one-to-many relationship managed by the Department
entity.这两个实体由两个不同的微服务管理,具有由
Department
实体管理的一对多关系。 So far, so good.到目前为止,一切都很好。
With a relational database (being an optional relationship and with the possibility of one employee belonging to several departments) I'd map this in the Departments
microservice with one table containing two fields: employee_id
and department_id
.使用关系数据库(作为一个可选关系,并且一名员工可能属于多个部门),我会在
Departments
微服务中使用 map ,其中一个表包含两个字段: employee_id
和department_id
。 When the client calls getDepartmentWithEmployees(depId)
this microservice will read the table and obtain the proper employees from the Employees
microservice.当客户端调用
getDepartmentWithEmployees(depId)
时,此微服务将读取表并从Employees
微服务中获取适当的员工。
But, in a MongoDb database, as far as I know, when I store a Department
object it stores all associated Employee
s.但是,据我所知,在 MongoDb 数据库中,当我存储
Department
object 时,它存储所有关联的Employee
。 Is not that duplicating the information?这不是重复信息吗? Is there a way, maybe, where MongoDb don't store all info about the employees but just their id?
有没有办法,也许,MongoDb 不存储有关员工的所有信息,而只存储他们的 ID? Or there is another answer?
还是有别的答案?
I am pretty sure this is a very basic question, but I am new to all this stuff.我很确定这是一个非常基本的问题,但我对所有这些东西都很陌生。
Thanks in advance.提前致谢。
But, in a MongoDB database, as far as I know, when I store a Department object it stores all associated Employees.
但是,据我所知,在 MongoDB 数据库中,当我存储部门 object 时,它会存储所有相关的员工。 Is not that duplicating the information?
这不是重复信息吗?
First of all, the statement above is not correct.首先,上面的说法是不正确的。 From the MongoDB's perspective, whatever is provided as BSON is stored as it is.
从 MongoDB 的角度来看,作为 BSON 提供的任何内容都按原样存储。 If you provide employees with the department then yes, it should.
如果您为员工提供部门,那么是的,它应该。 You can apply partial updates after creating the department... (eg using
$set
operator).您可以在创建部门后应用部分更新...(例如使用
$set
运算符)。 But, I think the scope of your question is broader than this.但是,我认为您的问题的 scope 比这更广泛。
IMHO, creating nano-services for each document/table in the database is not a good approach.恕我直言,为数据库中的每个文档/表创建纳米服务不是一个好方法。 Especially, when the services only responsible for basic CRUD operation.
特别是当服务只负责基本的 CRUD 操作时。 You should first define your bounded contexts, aggragate roots and etc... In short, do not try to design tables before mapping business requirements to domain objects.
您应该首先定义您的有界上下文、聚合根等... 简而言之,在将业务需求映射到域对象之前不要尝试设计表。 What I'm trying to say is use DDD principles:)
我想说的是使用 DDD 原则:)
These are the strategies that I found so far.这些是我目前发现的策略。 When designing microservices you should also consider pros and cons of each strategy.
在设计微服务时,您还应该考虑每种策略的优缺点。 (See bottom for references.)
(参见底部的参考资料。)
The 1:1 relation can be mapped in two ways;可以通过两种方式映射 1:1 关系;
Tables:表:
// 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"
}
Address with document key;带文件密钥的地址;
{
"employee_id": 763541685,
"City":"Ankara",
"Street":"Genclik street",
"Nr":10
}
Initial:最初的:
// 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"
}
]
Warning:警告:
{
"id": 1,
"deparment_name": "Software",
"department_location": "Amsterdam",
"employess": [
{
"employee_id": 46515,
"employee_name": "John Doe"
},
{
"employee_id": 81584,
"employee_name": "John Wick"
}
]
}
We can link department_id from employee document.我们可以从员工文档中链接 department_id。
Retrieve all employees that are belong to department X.
This query will need a lot of read operations!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
}
]
We'll split the employees into buckets with maximum of 100 employees in each bucket.我们将员工分成多个桶,每个桶中最多有 100 名员工。
{
"id":1,
"Page":1,
"Count":100,
"Employees":[
{
"employee_id": 46515,
"employee_name": "John Doe"
},
{
"employee_id": 81584,
"employee_name": "John Wick"
}
]
}
To choose Two Way Embedding or One Way Embedding , the user must establish the maximum size of N and the size of M.
要选择Two Way Embedding或One Way Embedding ,用户必须确定 N 的最大尺寸和 M 的尺寸。
For example;例如; if N is a maximum 3 categories for a book and M is a maximum of 5,000,000 books in a category you should pick One Way Embedding.
如果 N 是一本书最多 3 个类别,M 是一个类别中最多 5,000,000 本书,则您应该选择 One Way Embedding。
If N is a maximum 3 and M is a maximum of 5 then Two Way Embedding might work well.如果 N 最大为 3,M 最大为 5,则双向嵌入可能会很好地工作。 schema basics
架构基础
In Two Way Embedding we will include the Book foreign keys under the book field in the author document.在双向嵌入中,我们将在作者文档的 book 字段下包含 Book 外键。
Author collection作者合集
[
{
"id":1,
"Name":"John Doe",
"Books":[ 1, 2 ]
},{
"id":2,
"Name": "John Wick",
"Books": [ 2 ]
}
]
Book collection:藏书:
[
{
"id": 1,
"title": "Brave New World",
"authors": [ 1 ]
},{
"id":2,
"title": "Dune",
"authors": [ 1, 2 ]
}
]
Example Books and Categories: The case is that several books belong to a few categories but a couple categories can have many books.示例书籍和类别:案例是几本书属于几个类别,但几个类别可以有很多书。
Catergory类别
[
{
"id": 1,
"category_name": "Brave New World"
},
{
"id": 2,
"category_name": "Dune"
}
]
An example of a Book
document with foreign keys for Categories
具有
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.