背景
最近在实际开发过程中,时常看到历史遗留的跨对象条件搜索(对象1与对象2通过某个字段关联,筛选出满足条件的对象2所关联的所有对象1)的需求。
本身这样的需求源自产品方便客户快速检索数据无可厚非,然而由于跨对象搜索条件是一个时常变化的属性的时候且对象关联是一对多且无上限的时候如何处理就是决定系统是否稳定、可靠的要素。
场景
例如,CRM系统中有两种常见的对象:线索与客户。
如下图所示:
1.线索通过customer_id关联一个客户。
2.一个客户可以被多个线索关联。
classDiagram
class 线索 {
+id:线索id
+name:线索名称
+customer_id: 客户id
}
class 客户 {
+id: 客户id
+name: 客户名称
+status: 状态
}
客户 "1" <-- "n" 线索
案例
搜索客户名称为“XXX”的所有线索
那我们通常实现方式无非两种:
1.关联查询
select * from 线索,客户 where 线索.customer_id=客户.id and 客户.name = 'XXX';
2.多次查询
List<Integer> customerIds = "select * from 客户 where 客户.name='XXX'";
List<线索> 线索列表 = "select * from 线索 where 线索.customer_id in (customerIds);"
实现需求了,上线。
结果,没多久,客户反馈,这个查询太慢了~~
为什么呢?
1.Mysql 对于IN条件个数如果查过一定数量,索引会失效; 2.如果满足客户过多,customerId列表将会无限长,这样导致的只会是搜索范围过广; 3.Mysql对于sql语句长度也有限制,默认是1M(当然一般不会到这个时候才发现这个设计的问题); 4.Java字符串最大长度也有限制(默认Integer.MAX_VALUE); ...
这些原因都极有可能影响系统的稳定运行,数据量越大,越容易出现问题。
怎么解决?
- 冗余字段: 将关联对象的搜索字段冗余到当前对象中,这样就能解决
1.冗余字段需要满足不可变的前提
- 关联设置上限
1.对象与对象关联设计上限,最多允许关联(10 或者 100)个(mysql 5.6 in 查询个数超过10个会失效,5.7 in 条件数超过200 会失效)
-
交互重新设计