程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java 順序員容易犯的10個SQL錯誤

Java 順序員容易犯的10個SQL錯誤

編輯:關於JAVA

Java 順序員容易犯的10個SQL錯誤。本站提示廣大學習愛好者:(Java 順序員容易犯的10個SQL錯誤)文章只能為提供參考,不一定能成為您想要的結果。以下是Java 順序員容易犯的10個SQL錯誤正文


Java順序員編程時需求混合面向對象思想和普通命令式編程的辦法,能否完滿的將兩者結合起來完全得依托編程人員的水准:

  • 技藝(任何人都能容易學會命令式編程)
  • 形式(有些人用“形式-形式”,舉個例子,形式可以使用就任何中央,而且都可以歸為某一類形式)
  • 心境(首先,要寫個好的面向對象順序是比命令式順序難的多,你得破費一些功夫)

但當Java順序員寫SQL語句時,一切都不一樣了。SQL是闡明性言語而非面向對象或是命令式編程言語。在SQL中要寫個查詢語句是很復雜的。但在Java裡相似的語句卻不容易,由於順序員不只要重復思索編程范式,而且也要思索算法的問題。

上面是Java順序員在寫SQL時常犯的錯誤(沒有特定的順序):

 

1.忘掉NULL

Java順序員寫SQL時對NULL的曲解能夠是最大的錯誤。也許是由於(並非獨一理由)NULL也稱作UNKNOWN。假如被稱作UNKNOWN,這還好了解些。另一個緣由是,當你從數據庫拿東西或是綁定變量時,JDBC將SQL NULL 和Java中的null對應了起來。這樣招致了NULL = NULL(SQL)和null=null(Java)的曲解。

關於NULL最大的曲解是當NULL被用作行值表達式完好性約束條件時。

另一個曲解呈現在關於NULL 在 NOT IN anti-joins的使用中。

處理辦法:

好好的訓練你自己。當你寫SQL時要不停得想到NULL的用法:

  • 這個NULL完好性約束條件是正確的?
  • NULL能否影響到後果?
  2.在Java內存中處置數據

很少有Java開發者能將SQL了解的很好.偶然運用的JOIN,還有乖僻的UNION,好吧.但是關於窗口函數呢?還有對集合停止分組呢?許多的Java開發者將SQL數據加載到內存中,將這些數據轉換成某些相近的集合類型,然後再那些集合下面運用邊界循環控制構造(至多在Java8的集合晉級以前)執行令人生厭的數學運算.

但是一些SQL數據庫支持先進的(而且是SQL規范支持的!)OLAP特性,這一特性表現更好而且寫起來也愈加方便.一個(並不怎樣規范的)例子就是Oracle超棒的MODEL分句.只讓數據庫來做處置然後只把後果帶到Java內存中吧.由於畢竟一切十分聰明的家伙曾經對這些昂貴的產品停止了優化.因而實踐上,經過將OLAP移到數據庫,你將取得一下兩項益處:

  • 便當性.這比在Java中編寫正確的SQL能夠愈加的容易.
  • 功能表現.數據庫應該比你的算法處置起來愈加快.而且愈加重要的是,你不用再去傳遞數百萬條記載了.

完善的辦法:

每次你運用Java完成一個以數據為中心的算法時,問問自己:有沒有一種辦法可以讓數據庫替代為我做這種費事事.

 

3. 運用UNION替代UNION ALL

太可恥了,和UNION相比UNION ALL還需求額定的關鍵字。假如SQL規范曾經規則了支持,那麼能夠會更好點。

  • UNION(允許反復)
  • UNION DISTINCT (去除了反復)

移除反復行不只很少需求(有時甚至是錯的),而且關於帶很多行的大數據集合會相當慢,由於兩個子select需求排序,而且每個元組也需求和它的子序列元組比擬。

留意即便SQL規范規則了INTERSECT ALL和EXCEPT ALL,很多數據庫會完成這些沒用的集合操作符。

處置辦法:
每次你寫UNION語句時,思索實踐上能否需求UNION ALL語句。

 

4.經過JDBC分頁技術給少量的後果停止分頁操作

大局部的數據庫都會支持一些分頁命令完成分頁效果,譬如LIMIT..OFFSET,TOP..START AT,OFFSET..FETCH語句等。即便沒有支持這些語句的數據庫,仍有能夠對ROWNUM(甲骨文)或許是ROW NUMBER() OVER()過濾(DB2,SQL Server2008等),這些比在內存中完成分頁更疾速。在處置少量數據中,效果尤其分明。

糾正:

 

僅僅運用這些語句,那麼一個工具(例如JOOQ)就可以模仿這些語句的操作。

 

5.在java內存中參加數據

從SQL的初期開端,當在SQL中運用JOIN語句時,一些開發者依舊有不安的覺得。這是源自對參加JOIN後會變慢的固有恐懼。假設基於本錢的優化選擇去完成嵌套循環,在創立一張銜接表源前,能夠加載一切的表在數據庫內存中,這能夠是真的。但是這事發作的概率太低了。經過適宜的預測,約束和索引,兼並銜接和哈希銜接的操作都是相當的快。這完全是是關於正確元數據(在這裡我不可以援用Tom Kyte的太多)。而且,能夠依然有不少的Java開發人員加載兩張表經過分開查詢到一個映射中,並且在某種水平上把他們加到了內存當中。

糾正:

假設你在各個步驟中有從各種表的查詢操作,好好想想能否可以表達你的查詢操作在單條語句中。

 

6.在一個暫時的笛卡爾積集合中運用 DISTINCT 或 UNION 消弭反復項

經過復雜的銜接,人們能夠會對SQL語句中扮演關鍵角色的一切關系得到概念。特別的,假如這觸及到多列外鍵關系的話,很有能夠會遺忘在JOIN .. ON子句中添加相關的判別。這會招致反復的記載,但或許只是在特殊的狀況下。有些開發者因而能夠選擇DISTINCT來消弭這些反復記載。從三個方面來說這是錯誤的:

  • 它(也許)處理了外表症狀但並沒有處理問題。它也有能夠無法處理極端狀況下的症狀。
  • 對具有很多列的龐大的後果集合來說它很慢。DISTINCT要執行ORDER BY操作來消弭反復。
  • 對龐大的笛卡爾積集合來說它很慢,還是需求加載很多的數據到內存中。

處理辦法:

依據經歷,假如你取得了不需求的反復記載,還是反省你的JOIN判別吧。能夠在某個中央有一個很難察覺的笛卡爾積集合。

 

7. 不運用MERGE語句

這並不是一個過失,但是能夠是短少知識或許關於強悍的MERGE語句決心缺乏。一些數據庫了解其它方式的更新拔出(UPSERT)語句, 如 MYSQL的反復主鍵更新語句,但是MERGE在數據庫中確是很弱小,很重要,以致於大肆擴展SQL規范,例如SQL SERVER。

處理之道:

假如你運用像結合INSERT和UPDATE或許結合SELECT .. FOR UPDATE然後在INSERT或UPDATE等更新拔出時,請三思。你完全可以運用一個更復雜的MERGE語句來遠離冒險競爭條件。

 

8. 運用聚合函數替代窗口函數(window functions)

在引見窗口函數之前,在SQL中聚合數據意味著運用GROUP BY語句與聚合函數相映射。在很多情形下都任務得很好,如聚合數據需求稀釋慣例數據,那麼就在join子查詢中運用group查詢。

但是在SQL:2003中定義了窗口函數,這個在很多主流數據庫都完成了它。窗口函數可以在後果集上聚合數據,但是卻沒有分組。現實上,每個窗口函數都有自己的、獨立的PARTITION BY語句,這個工具關於顯示報告太TM好了。

運用窗口函數:

  • 使SQL更易讀(但在子查詢中沒有GROUP BY語句專業)
  • 提升功能,像關系數據庫管理零碎可以更容易優化窗口函數

處理辦法:

 

當你在子查詢中運用GROUP BY語句時,請再三思索能否可以運用窗口函數完成。

 

9. 運用內存直接排序

SQL的ORDER BY語句支持很多類型的表達式,包括CASE語句,關於直接排序非常有用。你能夠重來不會在Java內存中排序數據,由於你會想:

  • SQL排序很慢
  • SQL排序辦不到

處置辦法:

 

假如你在內存中排序任何SQL數據,請再三思索,能否不能在數據庫中排序。這關於數據庫分頁數據非常有用。

 

10. 一條一條的拔出少量紀錄

JDBC ”懂“批處置(batch),你應該不會忘了它。不要運用INSERT語句來一條一條的出入不計其數的記載,(由於)每次都會創立一個新的PreparedStatement對象。假如你的一切記載都拔出到同一個表時,那麼就創立一個帶有一條SQL語句以及附帶很多值集合的拔出批處置語句。你能夠需求在到達一定量的拔出記載後才提交來保證UNDO日志肥大,這依賴於你的數據庫和數據庫設置。

關注盛行國外網站

facebook:http://www.fb-on.com

facebook官網:http://www.facebookzh.com

facebook:http://www.cn-face-book.com

youtube:http://www.youtubezh.com

twitter:http://www.twitterzh.com

 

處置辦法:
總是運用批處置拔出少量數據。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved