如果需要跨库join,该如何实现?
典型回答 所谓跨库join,指的就是数据分散在不同的数据库中,但是又需要做关联查询,这时候就需要解决跨库join的问题。 举个例子,比如我们有两个数据库一个交易trade库,一个用户customer库,这时候,如果我们想join查询位于trade库的orders表和位于customer库的users表,因为他们是不同的数据库,是没办法直接用以下SQL进行join的: 1 2 3 4 select orders.order_id,users.user_name from orders join users on orders.user_id = users.id 那么,如果要解决这个问题,可以有以下几个方案。 指定库名join 虽然交易trade库和用户customer库是不同的数据库,但是如果他们位于同一个数据库实例中,也是可以进行跨库join的,只需要在JOIN语句中通过指定数据库名来引用它们。例如,在MySQL中: 1 2 3 4 select orders.order_id,users.user_name from trade.orders join customer.users on trade.orders.user_id = customer.users.id 但是这个要求就是他们必须属于同一个数据库实例。 但是,需要注意的是,跨库JOIN操作可能会影响查询性能,尤其是在处理大量数据时。优化查询和考虑索引的使用可以帮助改善性能。 数据冗余 ✅为什么大厂不建议使用多表join? 在上面这篇文章中,我们提及过,有的时候,我们为了避免join,会在数据库表设计的时候,考虑反范式,即做一些字段的冗余。 比如上面的那个例子,我们可以在orders表中把user_name字段冗余下来,这样在一些需要在展示订单的时候展示用户名称的时候就可以不用join了。 但是,这么做也会带来一定的数据一致性的问题,那就是当users表中的用户改了名字,就会导致orders表中的用户名不一致,这时候就需要考虑同时修改,但是如果订单量很大,改起来是成本很高的。 所以,一般来说历史的数据就不改了,这种场景来说,如果用户看自己之前的订单,发现是自己之前的昵称,也是可以接受的。 但是不管怎么说,这个方案毕竟有限制,会带来数据不一致的问题。如果要考虑一致性,就会带来级联修改的问题。 但是,这个方案确实是公司里面用的比较多的。很多时候对于一些不常修改的字段,做一些数据冗余是非常方便的,比如用户的真实姓名。 内存中做join 所谓在内存中做join,其实就是在应用程序中,通过写代码做join。比如: 1 2 3 4 5 6 7 8 9 //先从数据库中查询出要查询的订单列表 List<OrderDO> orders = getOrders(); for(OrderDO orderDO : orders){ OrderDTO orderDTO= new OrderDTO(orderDO); //根据用户ID去users表查询用户名 String userName = getUserNameByUserId(orderDO.getuserId); orderDTO.setUserName(userName); } 这种做法非常多,虽然这么做,代码会比较复杂,然后需要多次查询,但是对于那些没有数据冗余,又没有很复杂的join的场景,还是非常常用的。 ...