zoukankan      html  css  js  c++  java
  • 数据库的设计问题-分表的好处

    问题:

      注意:这里说的不是【分库分表】里的分表,而是将一个大表的某些字段拆分到别的表里

      一个论坛系统,有两个页面,一个是帖子基本信息列表页面,一个是展示某个帖子的详细内容页面。现在可以在一张表A中,同时存储帖子的基本信息和详细内容。

      1、后来发现,帖子的数量多了,帖子列表页面的加载速度明显慢了很多。这是为什么?
      2、是不是说将表A拆分成两张一对一关联的表,一张表只放基本信息,用来加载帖子列表页面;另一张表只放详细内容,在查询的时候也只是查单张表,不会影响效率?

    解决过程:

      想了想,搜了搜,才发现自己真的是二了。

      1、我只是用到了某些基本信息字段(比如标题等),但是查询的时候却查了所有的字段,其中单content列的数据就十分庞大,速度自然就慢了。所以查询的字段越多,查询的速度越慢
      下图,可以看到两条sql语句的查询时间:

      

      2、可以将表拆成一对一关联的表,但这是表设计方面的问题了,现在数据已经很多了,调整数据结构太复杂了。

        那么根据“hibernate查询部分字段值,比查询所有字段值效率高”的原理,如上图那样,查询的时候,只查部分数据,是不是也可以呢?
        兴致勃勃得尝试了以后,才发现自己太天真了
        以下是我更改后的查询方法:

    //String hql="from Topic where top=1";
    String hql="select id,modifyTime,publishTime,title,good,top,replySum,remark,firstimg,section,user from Topic where top=1");
    Query query = em.createQuery(hql);
    List<Topic> result = query.getResultList();

      结果报错:java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to forum.po.Topic
      类型转换出错。调试发现,只有部分字段数据根本不能转换成真正的对象,最后页面调用的时候,自然会出错。

      后来研究“hibernate是如何把查询结果转换为对象的”,感觉只取查询结果中的一部分值到对象里并不容易。

      

      最后还是更改了数据库和实体类:
        将帖子的基本信息,和帖子的详细内容分成两张表A、B存储。
        刚开始使用@OneToOne关联映射,懒加载。仍然报错,懒加载没有加载到。
        后来,我就决定不使用OneToOne了,而是手动定义详细内容表B中的一列为基本信息表A中的主键。只是增加、删除的时候需要多考虑一张表。


      结果:页面加载速度也快了,问题解决。

      分析:使用@OneToOne关联,就必须定义外键了,在查询的时候懒加载,可能加载不到外键的数据,所以页面中也获取不到

        后来分成的A、B两张表,并没有定义外键关联,只是有B表的一列表示A表的主键。这样的话,两张表之间是完全没有关联的,可以单独查询。麻烦的是在增删的时候,要在代码中控制一起创建(A先B后),或者一起删除(先后无所谓)。

      原创文章,欢迎转载,转载请注明出处!

  • 相关阅读:
    angularjs $index用来取顺序
    angularjs &登录跳转
    if(!confirm("您确定删除吗?")){return;}
    登录跳转
    undefined null测试
    git生成密钥
    遍历map
    网络相关名词解释
    redis的Pub/Sub
    SQLAlchemy的使用
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/databaseSplitTable.html
Copyright © 2011-2022 走看看