架构小白到砖家-09-数据库的价值-多表查询和特殊操作处理

通过前面对jpa提供的JpaRepository和JpaSpecificationExecutor两种面向对象数据库操作研究,已经解决了绝大多数开发工作中单表对象化操作。这两种解决方案确实都非常优雅,省去了写SQL的烦恼,甚至连接口的实现类都不需要我们去写了。但是我们心中更加好奇,jpa难得真的就能将数据库概念给抹杀掉了吗?让我们带着疑问,再继续整理一下,还有什么数据库使用场景咱们没有讨论到。
在这里插入图片描述
前面已经提到过,咱们一直讨论的单表操作,那么数据库的多表查询呢?我们先来看看jpa怎么处理多表之间的关联关系。数据库理论中有范式概念,一共定义了六种范式,有兴趣的同学可以自己去补充下这个知识,这里就不展开讨论了。我们可以简单把范式理解为将一个复杂数据模型从一张单表,拆解成多张子表的规范。这里为了讨论方便,我们还是举一个多表模型案例,就用户权限模型吧。

用户权限我们就简化成用户和角色两个模型,用户和角色是多对多的双向关系,这种关系在数据库范式中,我们需要建立除了用户表和角色表之外,还要建立一张用户角色关系表。那么在ORM框架方案中,定义了数据库表关系注解,@OneToOne,@OneToMany,@ManyToMany。由于这个方案的内容非常多,咱们就不展开讨论这些注解的使用方法。咱们主要是为了说明解数据库多表之间关系,通过数据库范式的要求,有主外键和关系表的概念,并且ORM框架提供了映射关系的方案。
在这里插入图片描述

我们已经定义好了用户表、角色表、用户角色关系表,不管是自己创建数据库表,还是ORM框架自动生成,数据库的理论都是不会改变的,都会生成这样三张表。那么我们在实际的开发过程中,使用的是对象,所以我们还是需要把JAVA的对象模型创建出来,为了简化讨论范围,我们只研究用户对角色的一对多单向关系。
在这里插入图片描述

咱们的数据库多表模型案例就准备就绪了,可以进行讨论了。User和Role的单表映射,咱们都已经会了,只需要在User中添加一个@OneToMany关系。正常SQL操作来说,查询用户信息,先获取User信息,然后在获取用户对应的角色信息放入User对象中roles。就需要发送两条SQL,查询用户信息,查询角色信息。存储一个用户时,也需要两条SQL,存储用户信息,存储用户角色关系信息。

下面再来给几个具体案例场景,看看SQL操作和ORM操作都怎么处理。
第一修改用户密码,只需要用户信息;
第二获取菜单信息,需要用户和角色信息;
第三删除用户信息。

使用SQL
第一个场景,只查询用户一条SQL,
第二个场景,发送两条SQL。或者不在乎数据库性能,第一和第二场景都发送两条SQL。
第三个场景,先删除user表信息,在删除关系表信息。或者只删除用户表,关系表不删除。当然这种操作需要降低数据库范式要求,关系表不使用强制外键,就只是普通字段。这种操作虽然不合理,会造成关系表中有脏数据,但是可以快速满足业务需求,实际场景中经常遇到很多非合理业务要求。

使用ORM框架
第一个场景,可以设置懒加载,进行延迟抓取,发一条SQL;
第二个场景,需要设置立即加载,发送两条SQL。如果也是懒加载,就会在使用角色信息的时候,再发SQL获取,会引发两个问题,一个问题是使用角色信息的时候,超出了事务范围,无法获取数据了;另一个问题是造成N+1问题,每一个角色都会发送一条SQL。
第三个场景,只删除user对象就可以了,会自动删除关系表信息。表关系必须是强制外键,这种情况如果是一对一双向关系,那就麻烦了,删除一端,必须删除另外一端,否则无法删除。非常不灵活,特别是业务模型很复杂,关联关系很多的情况。
在这里插入图片描述
简单的从上面的对比中可以看出来,使用SQL会更加灵活,限制条件不多,可以降低数据库范式等级来满足复杂多变的业务场景需求;但是ORM方式就必须严格遵守数据库强制外键的范式等级,理论上范式等级越高数据库使用越合理,实际情况并不是这样,范式的使用是需要特定业务场景的限制。另外还有数据加载时机问题,懒加载和立即加载只能二选一,引入更多的使用条件限制和N+1的难题。以前有过项目尝试ORM强制外键关系,最后都是惨痛教训收场。当然ORM这种方案还是有一定优点,对象化操作多表数据,自动联动表关系处理,但是也带来了更多坏处,属于得不偿失的情况。
在这里插入图片描述

结论,建议放弃ORM的多表方案,降低数据库范式等级,不要使用强制外键,自己手动维护数据库表关系。但是必须在有清晰的数据库模型管理制度前提上。

回顾总结,数据存储方案中,JPA没法完全消除数据库概念,需要原生SQL来解决多表查询和特殊操作处理,比如报表查询就是一个典型案例,报表涉及到大量的数据库函数、多表连接、子视图查询等复杂SQL;还有一些特殊场景需要使用到数据库存储过程,来高效处理批量数据问题。

猜你喜欢

转载自blog.csdn.net/jea_dong/article/details/86215769