數據庫的設計問題-分表的好處


問題:

  注意:這里說的不是【分庫分表】里的分表,而是將一個大表的某些字段拆分到別的表里

  一個論壇系統,有兩個頁面,一個是帖子基本信息列表頁面,一個是展示某個帖子的詳細內容頁面。現在可以在一張表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后),或者一起刪除(先后無所謂)。

 

  原創文章,歡迎轉載,轉載請注明出處!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM