Elasticsearch高手进阶篇(59)
数据建模实战_关系型与document类型数据模型对比
关系型数据库的数据模型
- department的结构
public class Department {
private Integer deptId;
private String name;
private String desc;
private List<Employee> employees;
}
- employee的结构
public class Employee {
private Integer empId;
private String name;
private Integer age;
private String gender;
private Department dept;
}
关系型数据库中
-
department表
- dept_id
- name
- desc
-
employee表
- emp_id
- name
- age
- gender
- dept_id
三范式
- 将每个数据实体拆分为一个独立的数据表,同时使用主外键关联关系将多个数据表关联起来 --> 确保没有任何冗余的数据
- 一份数据,只会放在一个数据表中 --> dept name,部门名称,就只会放在department表中,不会在employee表中也放一个dept name,如果说你要查看某个员工的部门名称,那么必须通过员工表中的外键,dept_id,找到在部门表中对应的记录,然后找到部门名称
es文档数据模型
{
"deptId": "1",
"name": "研发部门",
"desc": "负责公司的所有研发项目",
"employees": [
{
"empId": "1",
"name": "waws1",
"age": 18,
"gender": "男"
},
{
"empId": "2",
"name": "waws2",
"age": 26,
"gender": "女"
},
{
"empId": "3",
"name": "waws3",
"age": 36,
"gender": "男"
}
]
}
- es,更加类似于面向对象的数据模型,将所有由关联关系的数据,放在一个doc json类型数据中,整个数据的关系,还有完整的数据,都放在了一起
Elasticsearch高手进阶篇(60)
数据建模实战_通过应用层join实现用户与博客的关联
构造用户与博客数据
在构造数据模型的时候,还是将有关联关系的数据,然后分割为不同的实体,类似于关系型数据库中的模型
案例背景:博客网站, 我们会模拟各种用户发表各种博客,然后针对用户和博客之间的关系进行数据建模,同时针对建模好的数据执行各种搜索/聚合的操作
PUT /waws_webblog/users/1
{
"name":"waws",
"email":"waws@sina.com",
"birthday":"1980-01-01"
}
PUT /waws_webblog/blogs/1
{
"title":"waws第一篇博客",
"content":"waws第一篇博客,开通啦!",
"userId":1
}
一个用户对应多个博客,一对多的关系,做了建模
建模方式,分割实体,类似三范式的方式,用主外键关联关系,将多个实体关联起来
搜索waws发表的所有博客
- 比如这里搜索的是,1万个用户的博客,可能第一次搜索,会得到1万个userId
GET /waws_webblog/users/_search
{
"query": {
"term": {
"name.keyword": {
"value": "waws"
}
}
}
}
{
"took": 27,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "waws_webblog",
"_type": "users",
"_id": "1",
"_score": 0.2876821,
"_source": {
"name": "waws",
"email": "waws@sina.com",
"birthday": "1980-01-01"
}
}
]
}
}
- 第二次搜索的时候,要放入terms中1万个userId,才能进行搜索,这个时候性能比较差了
GET /waws_webblog/blogs/_search
{
"query": {
"constant_score": {
"filter": {
"terms": {
"userId": [
1
]
}
}
}
}
}
{
"took": 22,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "waws_webblog",
"_type": "blogs",
"_id": "1",
"_score": 1,
"_source": {
"title": "waws第一篇博客",
"content": "waws第一篇博客,开通啦!",
"userId": 1
}
}
]
}
}
上面的操作,就属于应用层的join,在应用层先查出一份数据,然后再查出一份数据,进行关联
优点和缺点
- 优点:数据不冗余,维护方便
- 缺点:应用层join,如果关联数据过多,导致查询过大,性能很差
Elasticsearch高手进阶篇(61)
数据建模实战_通过数据冗余实现用户与博客的关联
构造冗余的用户和博客数据
第二种建模方式:用冗余数据,采用文档数据模型,进行数据建模,实现用户和博客的关联
PUT /waws_webblog/users/1
{
"name":"waws",
"email":"waws@sina.com",
"birthday":"1980-01-01"
}
PUT /waws_webblog/blogs/1
{
"title": "waws的第一篇博客",
"content": "大家好,我是waws",
"userInfo": {
"userId": 1,
"username": "waws"
}
}
- 冗余数据,就是说,将可能会进行搜索的条件和要搜索的数据,放在一个doc中
基于冗余用户数据搜索博客
GET /waws_webblog/blogs/_search
{
"query": {
"term": {
"userInfo.username.keyword": {
"value": "waws"
}
}
}
}
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "waws_webblog",
"_type": "blogs",
"_id": "1",
"_score": 0.2876821,
"_source": {
"title": "waws的第一篇博客",
"content": "大家好,我是waws",
"userInfo": {
"userId": 1,
"username": "waws"
}
}
}
]
}
}
就不需要走应用层的join,先搜一个数据,找到id,再去搜另一份数据
直接走一个有冗余数据的type即可,指定要的搜索条件,即可搜索出自己想要的数据来
优点和缺点
优点:性能高,不需要执行两次搜索 缺点:数据冗余,维护成本高 --> 每次如果你的username变化了,同时要更新user type和blog type
一般来说,对于es这种NoSQL类型的数据存储来讲,都是冗余模式....
当然,你要去维护数据的关联关系,也是很有必要的,所以一旦出现冗余数据的修改,必须记得将所有关联的数据全部更新