你的報表工具會做數(shù)據(jù)準備嗎 ——報表開發(fā)中的深層次問題

前言

現(xiàn)在企業(yè)的報表開發(fā)大部分都使用報表工具完成诚亚,成熟的報表工具提供了豐富的顯示設置增蹭、圖表類型滴某、導出打印等功能可以簡化報表開發(fā),非常方便滋迈。但在實際報表開發(fā)中還是經(jīng)常碰到一些非常棘手的深層次問題霎奢,即使是已經(jīng)熟練使用報表工具的開發(fā)老手也會很撓頭。

為什么有了報表工具還會出現(xiàn)這些問題呢饼灿?

報表開發(fā)幕侠,看起來就是將數(shù)據(jù)按照指定格式的表格或圖形呈現(xiàn)出來,這也是報表工具一直以來很擅長的環(huán)節(jié)碍彭。但是晤硕,原始數(shù)據(jù)經(jīng)常并不適合直接呈現(xiàn)悼潭,需要先做一些復雜的處理,這就是數(shù)據(jù)準備環(huán)節(jié)舞箍。

從報表工具的眼光上看舰褪,數(shù)據(jù)準備屬于報表之外的事情,可以堂而皇之地拒絕處理疏橄。但是占拍,拒絕不等于不存在,這個工作總還要做软族。沒有好的工具刷喜,目前報表的數(shù)據(jù)準備還處于比較原始的硬編碼階段,上千行的 SQL立砸、幾百 K 的存儲過程和大量的 JAVA 代碼充斥在報表之后掖疮。

落后的工具必然導致低下的生產(chǎn)效率,會嚴重拖累整個報表開發(fā)的進程颗祝,也就出現(xiàn)了前述的“撓頭”現(xiàn)象浊闪。再由于大多數(shù)報表工具的不重視,這個問題遲遲還沒有被解決的跡象螺戳。

報表數(shù)據(jù)準備之于報表有如樹根之于大樹搁宾,如果根本得不到解決,在枝葉上花多少精力都是白費倔幼。

這種深層次問題在報表開發(fā)初期一般很少碰到盖腿,但隨著報表開發(fā)的深入這些問題會接連不斷地出現(xiàn)了。

我們在這里收集整理了一批此類問題损同,以供報表開發(fā)者參考翩腐。內(nèi)容比較多,建議先收藏再慢慢看膏燃。

目錄

1. 零編碼制作報表可能嗎茂卦?

2. 為什么說當前報表開發(fā)的工作量主要在數(shù)據(jù)源環(huán)節(jié)?

3. 用存儲過程和 JAVA 寫報表數(shù)據(jù)源有什么弊端组哩?

4. 什么是報表的多樣性數(shù)據(jù)源問題等龙?

5. 報表的性能問題是怎樣產(chǎn)生的?

6. 什么是大報表伶贰?

7. 中間表是什么蛛砰?和報表有什么關系?會帶來怎樣的問題幕袱?

8. 報表熱切換是什么意思暴备?

9. 報表沒完沒了是個什么狀況?

1. 零編碼制作報表可能嗎们豌?

要回答這個問題涯捻,首先要明確啥程度算“零編碼”?

以 Excel 為例望迎,如果把寫 Excel 公式(包括復雜一些的)看做零編碼障癌;而把寫 Excel VBA 看做編碼的話,

報表開發(fā)是可以零編碼的辩尊!

但是涛浙,這有個前提:在數(shù)據(jù)(集)準備好的情況下才可以零編碼!

為什么這么說摄欲?

我們知道報表開發(fā)主要分兩個階段:

第一階段是為報表準備數(shù)據(jù)轿亮,也就是把原始數(shù)據(jù)通過 SQL/ 存儲過程加工成數(shù)據(jù)集;

第二階段是使用已準備的數(shù)據(jù)編寫表達式做報表呈現(xiàn)胸墙。在報表工具提供的 IDE 里可視化地畫出報表樣式我注,然后再填入一些把數(shù)據(jù)和單元格綁定的表達式就可以完成報表呈現(xiàn)了,雖然表達式可能比較復雜迟隅,但相對硬編碼要簡單得多(Excel 公式和 VBA 的關系)但骨。所以說這個階段是能做到“零編碼”的。

那報表數(shù)據(jù)準備怎么辦智袭?

很遺憾奔缠,這個階段沒法零編碼,一直以來只能硬編碼吼野,想想我們報表里寫的嵌套 SQL校哎、存儲過程、JAVA 程序就知道了瞳步。為什么報表工具發(fā)展這么多年報表呈現(xiàn)已經(jīng)完全工具化而報表數(shù)據(jù)準備的手段還這樣原始呢闷哆?因為這個階段太復雜了,不僅涉及計算邏輯的算法實現(xiàn)谚攒,還涉及報表性能(要知道大部分報表性能問題都是數(shù)據(jù)準備階段引起的)阳准。

那報表數(shù)據(jù)準備是不是沒辦法了呢?

雖然不能做到零編碼馏臭,但可以朝著簡單化的方向努力野蝇,將數(shù)據(jù)準備階段也工具化,這樣可以使用工具提供的便利來簡化報表數(shù)據(jù)準備階段的工作括儒,從而進一步簡化報表的開發(fā)绕沈。

那怎么實現(xiàn)報表數(shù)據(jù)準備工具化?

要實現(xiàn)這個目標并不容易帮寻,像上面提到要考慮的內(nèi)容有點多乍狐,大體來說數(shù)據(jù)準備工具至少要滿足這幾方面:

1. 具備完備的計算能力

說的有點拗口,掰開了其實在說既然在工具里做數(shù)據(jù)計算固逗,那得讓我什么都能算吧浅蚪,不能原來 SQL/JAVA 寫的放到這里就不行了藕帜,該有的計算方法和類庫都應該有,最好用起來還比較簡單(比原來硬編碼難就沒意義了)惜傲,專業(yè)的說法叫:計算體系是完備的洽故;

2. 支持熱切換

這點是相對 JAVA 來說的,通過數(shù)據(jù)準備工具生成的算法應該是解釋執(zhí)行的盗誊,不能每次改完報表還要重啟應用时甚,即時修改即時生效;

3.具備多源混算能力

通過數(shù)據(jù)準備工具可以同時連接多種數(shù)據(jù)源(RDBMS哈踱、NoSQL荒适、TXT、Excel开镣、Hadoop刀诬、HTTP、ES哑子、Kafka 等等)進行計算舅列,混合計算,這個數(shù)據(jù)源讀個表卧蜓、那個數(shù)據(jù)源加載個文件帐要,兩部分數(shù)據(jù)可以 join 到一起混算。現(xiàn)在我們的數(shù)據(jù)源太多了弥奸,報表常常會跨數(shù)據(jù)源取數(shù)榨惠,支持了異構源混算以后,原來還要考慮諸如數(shù)據(jù)是不是先入到一個庫里的事情就不用管了盛霎,那叫一個清爽赠橙;

4.高性能

直接簡化數(shù)據(jù)準備的工作還不夠,實現(xiàn)再簡單跑不快也不行愤炸。所以羞迷,還要高性能扫俺,至少不能比原來跑的慢吧剧罩,大家都是講道理的人枚冗;

以上是我們認為數(shù)據(jù)準備工具應該具備的能力,其他還有一些能力不是特別重要诞仓,但如果有最好了缤苫。包括:

* 有沒有易用的編輯調(diào)試環(huán)境,可以很方便地調(diào)試算法墅拭;

* 為了更快能不能并行計算

* 有沒有標準接口可以讓其他程序或工具調(diào)用

等等活玲,實際要用的時候照著這些特點去找就行了,有益無害。

說了這么多舒憾,總結來說镀钓,“零編碼制作報表”的確更像一句口號,沒法真正做到珍剑,但可以不斷努力接近這個目標掸宛,求其上得其中嘛死陆。

擴展閱讀:

【數(shù)據(jù)蔣堂】第 43 期:報表開發(fā)的現(xiàn)狀

報表提效資料匯總(體系結構和性能優(yōu)化)

2. 為什么說當前報表開發(fā)的工作量主要在數(shù)據(jù)源環(huán)節(jié)招拙?

我們知道,報表開發(fā)主要有兩個階段措译。

第一階段:數(shù)據(jù)準備别凤。將原始數(shù)據(jù)加工成報表需要的結果集(數(shù)據(jù)源);

第二階段:數(shù)據(jù)呈現(xiàn)领虹。根據(jù)已準備的結果集(數(shù)據(jù)源)編寫表達式將數(shù)據(jù)以表格或圖形方式呈現(xiàn)规哪。

這兩個階段雖然處于同一報表開發(fā)過程,但實現(xiàn)方式卻大不相同塌衰。

通常原始數(shù)據(jù)距離報表“能用”還相去甚遠诉稍,通過 SQL/JAVA/ 存儲過程等編碼方式準備報表可用的數(shù)據(jù)源是第一階段的目標,過程中可能涉及復雜的數(shù)據(jù)處理過程最疆,因而這個階段會牽扯較多的精力杯巨,占用的工作量也多努酸。

數(shù)據(jù)源準備好后服爷,通過報表工具來解決數(shù)據(jù)以何種方式(圖表)、何種樣式(外觀)呈現(xiàn)的問題获诈,通過點選設置仍源、編寫少量表達式就可以快速完成,實現(xiàn)簡單舔涎,占用的工作量也少笼踩。

可以說,報表開發(fā)的工作量主要在數(shù)據(jù)處理(計算)亡嫌,數(shù)據(jù)處理后如何呈現(xiàn)嚎于,通過工具可以快速完成。

那是不是報表呈現(xiàn)階段就不涉及數(shù)據(jù)處理了呢昼伴?

并不完全是這樣匾旭。

早期報表開發(fā)

大概 2015 年以前,報表呈現(xiàn)方式主要以表格(或圖表混合)為主圃郊,這時通過報表工具實現(xiàn)時就會涉及一定的數(shù)據(jù)計算价涝,如分組匯總、多源分片持舆、格間計算(同比環(huán)比)等色瘩。如下圖所示:

計算分布在數(shù)據(jù)準備和數(shù)據(jù)呈現(xiàn)兩個階段伪窖,兩個階段的工作量相當(各占 50%)。這個時期居兆,數(shù)據(jù)準備階段可以把數(shù)據(jù)準備得“粗糙”一些覆山,然后利用報表工具的計算能力在呈現(xiàn)階段將數(shù)據(jù)進一步加工成目標結果進行呈現(xiàn)。比如泥栖,我們在數(shù)據(jù)準備階段完成關聯(lián)過濾簇宽,再在報表呈現(xiàn)模板中按多個維度分組匯總;或者在呈現(xiàn)模板中計算同比環(huán)比吧享。

當前報表開發(fā)

隨著報表工具的逐漸成熟魏割,報表工具提供了更豐富的圖形(類型和效果),報表選擇圖形呈現(xiàn)幾乎與表格占比相當了(占比仍在增長)

使用圖形呈現(xiàn)钢颂,由于沒有“格子”钞它,就無法利用報表工具的計算能力在呈現(xiàn)模板中完成數(shù)據(jù)處理,而圖形本身并不具備計算能力(不包括硬編碼)殊鞭,這時自然而然就要在數(shù)據(jù)準備階段將前端需要的數(shù)據(jù)完全準備好遭垛,前端工具接收數(shù)據(jù)直接圖形呈現(xiàn)。

圖形設置基本沒什么工作量操灿,而后端數(shù)據(jù)源的準備工作就占了大頭锯仪,數(shù)據(jù)呈現(xiàn)和數(shù)據(jù)準備所占的工作量占比約為 20%:80%。

當前報表開發(fā)的工作量主要在數(shù)據(jù)源端(數(shù)據(jù)準備階段)牲尺,要提升報表開發(fā)效率卵酪,勢必要解決報表數(shù)據(jù)源準備效率問題。這也是為什么很多時候用上了一流的報表工具谤碳,但報表開發(fā)的工作量仍然很大的原因溃卡。

如何提升報表數(shù)據(jù)源端的開發(fā)效率,從而整體降低報表開發(fā)工作量蜒简?

借鑒報表開發(fā)的發(fā)展歷史瘸羡,或許可以獲得一些思路。

早期搓茬,報表開發(fā)靠完全硬編碼犹赖,無論數(shù)據(jù)準備還是報表呈現(xiàn),后來報表工具出現(xiàn)替代了硬編碼方式卷仑,將報表呈現(xiàn)階段的開發(fā)工具化峻村,解放了報表呈現(xiàn)階段的人力(你可以感受一下寫代碼畫報表比用工具做麻煩多少)。

按照這個思路锡凝,用工具替代硬編碼就可以提高生產(chǎn)效率粘昨,將數(shù)據(jù)準備階段工具化就可以解決報表數(shù)據(jù)源的開發(fā)效率,從而進一步提升報表整體開發(fā)效率。

數(shù)據(jù)準備工具可以是獨立的张肾,也可以包含在報表工具內(nèi)部芭析,后者要求報表工具的能力能夠延伸到數(shù)據(jù)源層面。

擴展閱讀:

【數(shù)據(jù)蔣堂】第 10 期:報表的數(shù)據(jù)計算層

如何應對報表開發(fā)中的復雜邏輯

3. 用存儲過程和 JAVA 寫報表數(shù)據(jù)源有什么弊端吞瞪?

我們在報表開發(fā)中經(jīng)常會使用存儲過程準備數(shù)據(jù)馁启,存儲過程支持分步計算,可以實現(xiàn)非常復雜的計算邏輯芍秆,為報表開發(fā)帶來便利惯疙。所以,報表開發(fā)中這樣的存儲過程并不少見:

3008 行浪听,141KB 的存儲過程螟碎,會給報表開發(fā)帶來什么不好的影響?

1.編輯調(diào)試性

存儲過程難以編輯調(diào)試迹栓,這樣幾千行存儲過程的開發(fā)周期往往要以周或月計,這樣會嚴重影響報表的開發(fā)效率俭缓,而業(yè)務提的報表需求似乎都“很急”克伊。

2.維護性

相對開發(fā)的一次性,維護的工作可能要經(jīng)常做华坦。實際業(yè)務中報表經(jīng)常會修改愿吹,這種現(xiàn)象叫做報表業(yè)務的穩(wěn)定性差。報表的數(shù)據(jù)準備邏輯變化惜姐,修改上千行的存儲過程對絕大多數(shù)報表開發(fā)人員來說都是噩夢犁跪。

有時這樣的報表會分兩撥人來做,DBA 或?qū)I(yè)程序員負責編寫存儲過程給前端報表開發(fā)人員做報表歹袁,這樣就避免了報表開發(fā)人員寫存儲過程坷衍。但這樣報表修改的流程會變長,修改一張報表涉及多個人員之間溝通(還包括業(yè)務人員)条舔,如果負責報表前后端的兩撥人隸屬不同的團隊就更麻煩了枫耳。

3.知識傳承

從維護性可以直接引出另一個“知識傳承”的問題。還是拿上面的報表為例孟抗,如果一個新人要改上面的報表迁杨,你覺得他要多久能看懂存儲過程,改完報表凄硼?

當然铅协,這個問題還涉及很多管理方面的手段,單純從技術本身來看摊沉,這樣的報表想要很好地傳承知識是很難的狐史。

4.安全性

對存儲過程的修改需要較高的數(shù)據(jù)庫權限,而報表經(jīng)常要改就要經(jīng)常操作數(shù)據(jù)庫,這對數(shù)據(jù)庫安全也是一個隱患预皇,同樣需要強管理機制才能保障一二侈玄。

5.移植性

現(xiàn)在絕大多數(shù)規(guī)定禁止使用存儲過程的原因,首當其沖的就是存儲過程沒有移植性吟温。如果未來數(shù)據(jù)庫發(fā)生變化需要遷移序仙,不管將來是更換數(shù)據(jù)庫類型,還是系統(tǒng)擴展(分表分庫)鲁豪,大量無法移植的存儲過程絕對是最頭疼的問題潘悼。

當然,“換庫”這件事情即使在今天仍然不會頻繁發(fā)生爬橡,但是只要發(fā)生一次就夠受了(有國產(chǎn)化或系統(tǒng)擴展預期的就要注意了)治唤。

6.耦合性

從維護性、安全性和移植性看來糙申,存儲過程會導致報表應用(前端)和數(shù)據(jù)庫(后端)緊耦合宾添。緊耦合除了會導致前面的三個問題外,還會讓數(shù)據(jù)庫編的臃腫柜裸,影響數(shù)據(jù)庫性能缕陕。

重要的事情說好多遍,報表的業(yè)務不穩(wěn)定疙挺,報表除了經(jīng)常增加和修改扛邑,有時還會刪除(不用了),而為這個報表準備的存儲過程還在數(shù)據(jù)庫里铐然,這時想要刪掉這個存儲過程就比較難了蔬崩。

為什么?

因為你不知道是不是還有其他程序在共用這個存儲過程搀暑,刪除會不會對其他程序產(chǎn)生影響沥阳。結果就是數(shù)據(jù)庫的存儲過程越積越多導致數(shù)據(jù)庫臃腫,而有的存儲過程還會涉及自動運行险掀,雖然存儲過程可能不再使用沪袭,但仍然在消耗數(shù)據(jù)庫資源,長此以往數(shù)據(jù)庫性能下降就成為必然了樟氢。

7.多源支持

存儲過程運行在封閉的數(shù)據(jù)庫內(nèi)冈绊,無法進行跨多數(shù)據(jù)源混合計算。關于多源問題埠啃,幾年前在報表開發(fā)還不顯著死宣,那時大家都用關系庫;但現(xiàn)在不一樣了碴开,同一個報表的數(shù)據(jù)可能來自多個不同類型的數(shù)據(jù)源(RDB/NoSQL/TxT/Excel/Hadoop/ES 等等)毅该,這時存儲過程就無能為力了博秫。

如何搞定這些問題?

有沒有辦法解決存儲過程帶來的這些問題呢眶掌?

當然有挡育!

沒有什么是硬編碼解決不了的!用 JAVA 替代存儲過程朴爬,脫離數(shù)據(jù)庫運行來解決上面的問題(自行搜索 SOA 和微服務理念)即寒。存儲過程一個顯示的好處是可以分步實現(xiàn)報表數(shù)據(jù)準備邏輯,這個優(yōu)點 JAVA 也有召噩,甚至比存儲過程更徹底母赵,說句文縐縐的話:JAVA 的離散性更好。

只是 JAVA 寫起來比較麻煩具滴,對于報表開發(fā)人員來講太難了凹嘲,如果還要加一個修飾詞那就是太 XX 難了。存儲過程使用的 SQL 語言非常適合做集合運算构韵,分組匯總一句 group by 就寫出來了周蹭,反觀 JAVA 就不具備這個優(yōu)點了,分組匯總可能要寫上幾十上百行才行(類庫缺失會讓開發(fā)復雜度急劇上升贞绳,想想你為什么不用匯編寫程序而要用 JAVA谷醉?)。

JAVA 還有一些其他的問題也不容忽視冈闭。

不支持熱切換

JAVA 還有一個非常致命的缺點,就是不支持熱切換抖单。報表經(jīng)常要改(又來一遍)萎攒,修改報表數(shù)據(jù)源以后還要重新編譯、重啟應用才能生效矛绘,對絕大多數(shù)業(yè)務系統(tǒng)都是不能接受的耍休。報表講究的不僅是查詢立等可取,修改也要實時生效才行货矮。

報表與應用緊耦合

與使用存儲過程會導致報表與數(shù)據(jù)庫緊耦合類似羊精,用 JAVA 準備報表數(shù)據(jù)源會導致報表模塊和應用的其他業(yè)務模塊緊耦合不宜維護。

我們知道囚玫,報表大多數(shù)情況都是作為一個模塊集成到應用系統(tǒng)提供報表查詢服務喧锦,集成的方式可以是 API(jar 包)方式緊集成;也可以將報表單獨發(fā)布成服務抓督,通過服務調(diào)用的方式松集成燃少,這樣報表服務器產(chǎn)生的任何壓力或問題都不會影響應用系統(tǒng)(高可用)。*API 緊集成后铃在,由于報表數(shù)據(jù)源是 JAVA 寫的阵具,這樣就要和主應用的代碼一起打包碍遍,無法作為獨立的模塊維護,而未來想要拆分也基本不可能了阳液;* 服務松集成則完全無法實現(xiàn)怕敬。

所以,用 JAVA 寫報表數(shù)據(jù)源雖然可行帘皿,但也不是特別理想东跪。

那有沒有其他辦法呢?

我們比較一下存儲過程和 JAVA 的優(yōu)缺點可以發(fā)現(xiàn)矮烹,解決問題應該是沿著繼承二者優(yōu)點越庇,改進缺點的方向進行。清晰起見奉狈,總結一下需要的點卤唉。

把主要的點列了一下,我們的目標就是找到支持這些點的技術手段(問號所在行)仁期。

易開發(fā)桑驱、易維護

這注定了這些能力應該是報表工具內(nèi)置的,這樣報表開發(fā)人員自己就能使用工具搞定報表開發(fā)跛蛋,而不必依賴其他人或團隊熬的;

熱切換

熱切換要求這個技術應該是解釋執(zhí)行的,這樣才能做到實時修改實時生效赊级;

支持多源

能夠?qū)佣喾N不同類型的數(shù)據(jù)源進行混合計算押框,比如文本和數(shù)據(jù)庫表的 join;

低耦合理逊、可移植

數(shù)據(jù)準備能力和報表呈現(xiàn)能力都報表內(nèi)置了橡伞,自然與應用和數(shù)據(jù)源都解耦了,未來系統(tǒng)擴展自然毫無壓力晋被。

這樣我們可以很容易想到在報表端增加一個計算模塊(或引入其他計算工具)兑徘,來替代存儲過程或 JAVA 為報表準備數(shù)據(jù),這個模塊可以是由嵌入報表工具的腳本來實現(xiàn)羡洛,結構可以是這樣的

腳本要具備完善的計算能力(什么計算都能算)挂脑,支持多源,解釋執(zhí)行允許熱切換這些能力欲侮。

這才是報表工具的未來崭闲!

擴展閱讀:

怎樣減少報表開發(fā)中對存儲過程的依賴

如何應對報表開發(fā)中的復雜邏輯

4. 什么是報表的多樣性數(shù)據(jù)源問題?

在報表開發(fā)早期锈麸,報表連接的數(shù)據(jù)源基本只有關系數(shù)據(jù)庫镀脂,而且經(jīng)常只有一種或者只有一個數(shù)據(jù)庫。

但今天就不一樣了忘伞,數(shù)據(jù)源種類繁多薄翅,除了 RDBMS 還有

1.MongoDB沙兰、Cassandra、HBase翘魄、Redis 這些 NoSQL 數(shù)據(jù)庫鼎天;

2.TXT/CSV、Excel暑竟、JSON/XML 等文件斋射;3.HDFS 等分布式文件系統(tǒng);

4.webService但荤;

5.ES罗岖、Kafka 等其他數(shù)據(jù)源形式

……

當這些都成為報表數(shù)據(jù)源,報表需要從這些數(shù)據(jù)源分別或混合取數(shù)運算進行報表呈現(xiàn)時腹躁,報表就出現(xiàn)了多樣性數(shù)據(jù)源問題桑包。

具體是什么樣的問題呢?

主要是兩個問題纺非,復雜計算和多源關聯(lián)計算哑了。

1.復雜計算

我們知道,報表中的計算主要集中在兩處:

一處是數(shù)據(jù)準備階段烧颖。

通過 SQL/ 存儲過程 /Java 程序為報表準備數(shù)據(jù)弱左,這個階段可能涉及非常復雜的數(shù)據(jù)處理邏輯。這樣, 計算能力尤其是集合計算能力較強的 SQL 就比較擅長了炕淮,通過 SQL拆火、復雜 SQL 可以完成大部分的報表數(shù)據(jù)準備任務,有些涉及較多業(yè)務邏輯的計算還可以使用存儲過程涂圆,萬不得已時用 JAVA 自定義數(shù)據(jù)源完成榜掌。

這是早期基于單一 RDBMS 開發(fā)報表時數(shù)據(jù)準備的常用手段,主要依靠 RDBMS(SQL)的計算能力來實現(xiàn)乘综。

但這種方式在多樣性數(shù)據(jù)源的場景下就行不通了,因為有的數(shù)據(jù)源根本就不支持 SQL套硼,甚至計算能力都比較弱(如 NoSQL)卡辰,或者根本就沒有計算能力(如文本),這樣邪意,數(shù)據(jù)準備計算計算無法在這個階段實現(xiàn)九妈,就要看另外一處是否可以完成了?

二處是報表呈現(xiàn)階段

根據(jù)第一階段已準備的數(shù)據(jù)雾鬼,在報表模板中填入綁定格子的報表表達式或圖形來呈現(xiàn)報表是使用報表工具開發(fā)報表的常用方式萌朱。這說明報表工具具備一定的計算能力,通過表達式可以實現(xiàn)分組匯總策菜、過濾晶疼、排序酒贬,復雜一些的同比環(huán)比等計算。

但是翠霍,報表工具的計算能力是有限的锭吨。不考慮性能的情況下国章,單純從數(shù)據(jù)源中讀取數(shù)據(jù)到報表呈現(xiàn)階段完成數(shù)據(jù)組織和報表呈現(xiàn)很多時候是做不到的朋贬,這也是為什么我們會在數(shù)據(jù)準備階段進行復雜數(shù)據(jù)處理的原因了辛馆。

2.多源關聯(lián)計算

與基于單一的某個數(shù)據(jù)源進行的復雜計算不同旬盯,有時一個報表會同時連接多個數(shù)據(jù)源欧瘪,多個數(shù)據(jù)源之間要混合計算聪舒,比如 MongoDB 的數(shù)據(jù)和 RDBMS 的數(shù)據(jù)關聯(lián)運算掖肋,文本和 Excel 關聯(lián)運算等吐咳。

這種跨異構數(shù)據(jù)源的關聯(lián)無法直接通過數(shù)據(jù)源自身的能力實現(xiàn)会宪,只能借助其他方法肖卧。

那報表的多樣性數(shù)據(jù)源問題如何解決呢?

方法總比問題多狈谊。目前大家普遍采用兩種方式來解決報表多樣性數(shù)據(jù)源的問題喜命。

借助 RDBMS

曲線救國。將多樣性數(shù)據(jù)源的數(shù)據(jù)通過 ETL 灌到關系庫中河劝,再基于關系庫出報表壁榕,這樣就可以避免多樣性數(shù)據(jù)源的問題,轉(zhuǎn)而使用最熟悉的手段來解決赎瞎。

不過牌里,這種方式的局限性很大。因為之所以出現(xiàn)多樣性數(shù)據(jù)源务甥,是因為各種數(shù)據(jù)源有各自適用的場景牡辽,換句話說很多是關系庫搞不定的,所以才會用這些數(shù)據(jù)源敞临,比如 NoSQL 的 IO 吞吐能力很強态辛,但計算能力較弱;文本 /Excel 文件適合做臨時存儲且不需要持久化到 DB挺尿;Webservice 則非常靈活奏黑,入庫的動作就顯得過于笨重,…

且不說多樣性數(shù)據(jù)源的數(shù)據(jù)是否能轉(zhuǎn)換到關系庫中编矾,由于要經(jīng)過 ETL 的過程熟史,數(shù)據(jù)的實時性如何保證?數(shù)據(jù)量較大時除了 ETL 慢窄俏,RDBMS 的容量是否夠用蹂匹?查詢性能是否滿足報表查詢要求?等等這些問題都是這種方式要面對的凹蜈。

采用這種方式經(jīng)常是“不得已”限寞,因為解決某類問題上了其他數(shù)據(jù)源忍啸,結果因為出報表又要用回關系庫,也不知道隱含了多少辛酸昆烁。

JAVA 硬編碼

通過 RDBMS 來解決報表多樣性數(shù)據(jù)源的問題有這樣那樣的問題吊骤,那直接硬編碼怎么樣?通過 JAVA 硬編碼對接多樣性數(shù)據(jù)源為報表準備數(shù)據(jù)静尼,畢竟硬編碼想干啥就干啥白粉。

這種方式我們之前有分析過,除了編碼難鼠渺、維護難的問題(報表開發(fā)人員基本搞不定)鸭巴,還存在無法熱切換(JAVA 是編譯型語言)和與業(yè)務應用緊耦合(代碼要跟業(yè)務應用主程序一起打包部署)這些問題。這是我們之前聊過的:用存儲過程和 JAVA 寫報表數(shù)據(jù)源有什么弊端拦盹?

硬編碼似乎也不理想鹃祖。

事實上,我們只需要增強報表工具的計算能力就能解決這個問題普舆。

1. 首先恬口,提供多樣性數(shù)據(jù)源的支持,通過報表工具可以連接這些數(shù)據(jù)源沼侣,要實現(xiàn)這一步相對簡單祖能;

2. 其次,提供復雜計算支持蛾洛,讓所有的復雜計算都能在報表中完成养铸。實現(xiàn)手段可以是強化呈現(xiàn)端的計算能力,通過報表格子表達式就能完成這些復雜計算轧膘。不過钞螟,對于綁定格子的計算(狀態(tài)式計算)想要支持復雜計算并不容易,在呈現(xiàn)端要兼顧數(shù)據(jù)處理和數(shù)據(jù)呈現(xiàn)很多計算就做不了了谎碍,而且呈現(xiàn)格會帶有很多呈現(xiàn)屬性(字體鳞滨、顏色、邊框等等)蟆淀,帶著這些屬性計算會占用過多內(nèi)存太援,嚴重影響計算性能。

很難在報表呈現(xiàn)格表達式中完成復雜計算(功能和性能都不滿足)

可以想到的另外一種方式是在報表中增加計算模塊用來專門做多樣性數(shù)據(jù)源混合計算扳碍,其位置與原來為報表準備數(shù)據(jù)的 SQL 和 JAVA 相當,只不過是內(nèi)嵌在報表中仙蛉,屬于報表自身的能力笋敞,結構大概是這樣

在原有的基礎上增加了計算模塊,計算模塊可以通過可編程計算腳本實現(xiàn)荠瘪,但對這個腳本能力有要求:

1. 提供多樣性數(shù)據(jù)源訪問接口

能直接對接多樣性數(shù)據(jù)源是基礎夯巷,種類越豐富對多樣性數(shù)據(jù)源問題解決得越充分赛惩;

2. 支持復雜計算

當數(shù)據(jù)源自身不具備強計算能力時,通過腳本可以完成報表數(shù)據(jù)準備階段的復雜計算邏輯趁餐,腳本提供豐富的計算類庫喷兼,可以很方便地實現(xiàn)這類計算,最好比 SQL 和 JAVA 都簡單后雷;

3. 支持多源關聯(lián)

可以跨異構數(shù)據(jù)源關聯(lián)計算季惯,這是也解決報表多樣性數(shù)據(jù)源問題需要具備的重要能力;

4. 支持熱切換

腳本修改后可以實時生效臀突,而不會像 JAVA 一樣需要重啟應用勉抓。

當我們遇到報表多樣性數(shù)據(jù)源問題需要選擇報表開發(fā)技術時不妨沿著這個方向考量一下。

擴展閱讀:

【數(shù)據(jù)蔣堂】第 10 期:報表的數(shù)據(jù)計算層

在報表中直接使用多樣性數(shù)據(jù)源

5. 報表的性能問題是怎樣產(chǎn)生的候学?

報表性能是總也避不開的話題藕筋,報表作為 OLAP(在線聯(lián)機分析)中的主要應用場景,無論從涉及數(shù)據(jù)的寬度(表數(shù)量)梳码,還是數(shù)據(jù)的廣度(查詢范圍)都可能非常巨大隐圾;而且在報表中還經(jīng)常伴隨非常復雜的數(shù)據(jù)處理邏輯,這些都會影響報表的運行速度掰茶。而服務器環(huán)境暇藏、數(shù)據(jù)庫環(huán)境、JDBC 效率符匾、網(wǎng)絡環(huán)境叨咖、客戶端環(huán)境這些也都都跟報表性能密切相關。

報表性能可能跟很多因素有關啊胶,非常復雜甸各。這里我們試著從報表運行的各個階段來分析報表性能問題產(chǎn)生的主要原因及其應對方法。未盡之處焰坪,歡迎討論趣倾。

我們知道報表運行主要分報表解析、數(shù)據(jù)準備某饰、數(shù)據(jù)傳輸儒恋、報表計算和報表生成 5 個階段。除了報表解析是引擎加載解析模板黔漂,還未開始運算外诫尽,其他 4 個階段(示意圖中黃色的部分)均可能引起性能問題。

我們在分析報表性能問題時一定要先定位是哪個階段引起的炬守,抓主要矛盾牧嫉。定位的方法也很簡單,就是分析報表運行日志,很多報表工具都會輸出各個階段的運算時間酣藻,看看哪個階段耗時最長曹洽,就是問題發(fā)生的主要階段了。

1.數(shù)據(jù)準備

報表數(shù)據(jù)準備是指從數(shù)據(jù)源中讀取數(shù)據(jù)并將數(shù)據(jù)組織成報表可用的結果集的過程辽剧。在報表中往往是以數(shù)據(jù)集的形式存在送淆,可以通過 SQL、存儲過程或 JAVA 實現(xiàn)怕轿。

數(shù)據(jù)準備并不是簡單地將數(shù)據(jù)源的原始數(shù)據(jù)取出就結束了偷崩,而是會伴隨一些計算過程,有些還很復雜撤卢,可以想想一下平時我們開發(fā)報表時編寫的 SQL 絕大多數(shù)情況下都不是簡單的 select * from tbl环凿。如果這個 SQL 比較復雜(由于大多數(shù)情況都是使用 SQL 準備數(shù)據(jù),所以這里我們僅以 SQL 為例放吩,其他數(shù)據(jù)源可以參考 SQL 數(shù)據(jù)集的解決辦法)運行較慢智听,就會導致報表變慢。

這個階段在數(shù)據(jù)庫中運行渡紫,本質(zhì)上跑的快慢都跟報表無關到推,但好的報表工具是可以干預優(yōu)化這個過程的(后面再說)。

數(shù)據(jù)準備階段慢惕澎,可以先試著優(yōu)化 SQL莉测,但 SQL 優(yōu)化往往復雜度較高,所以也經(jīng)常采用預計算的方式進行性能優(yōu)化(這里不討論硬件升級唧喉、數(shù)據(jù)庫擴容等物理優(yōu)化手段)捣卤。

(1)優(yōu)化 SQL

我們知道復雜 SQL(關聯(lián)多、嵌套多)是比較難優(yōu)化的八孝。數(shù)據(jù)庫的透明化機制讓寫 SQL 時不用關心底層的執(zhí)行順序董朝,由數(shù)據(jù)庫優(yōu)化器自動執(zhí)行,這樣可以簡化編寫 SQL 的難度干跛,但過于透明的機制讓我們很難干預 SQL 的執(zhí)行路徑子姜,也就很難優(yōu)化 SQL 了。

(2)預計算

SQL 無法優(yōu)化或優(yōu)化效果不理想時楼入,通過預計算可以提升報表數(shù)據(jù)準備效率哥捕。將報表需要的結果集事先加工出來存儲到中間表中,報表查詢時直接讀取加工好的結果集嘉熊,這樣就可以節(jié)省大量計算時間遥赚,從而提升報表性能。預計算本質(zhì)是用空間換時間的手段阐肤。

不過鸽捻,預計算的缺點也非常明顯,你不妨先思考一下有哪些問題?

主要的問題有兩個:時間問題和空間問題御蒲。

時間問題

預計算需要“事先”加工,其本質(zhì)是一個 ETL 過程诊赊,這樣就會引起兩個時間問題厚满,數(shù)據(jù)的實時性和預計算的時間成本。

報表基于預計算的結果查詢只能查詢預計算時點以前的數(shù)據(jù)碧磅,無法查詢預計算到當前時間的數(shù)據(jù)碘箍,這樣就導致了數(shù)據(jù)時效性差,不適合數(shù)據(jù)實時性要求高的業(yè)務場景(比如交易系統(tǒng))鲸郊。

預計算往往會放到業(yè)務空閑的階段進行丰榴,比如前一天夜里到第二天上班前,通常還要預留一些時間容錯(跑失敗了要重新跑)秆撮,這樣可能留給預計算的時間也就 5四濒、6 個小時,這個時長基本是固定不變的职辨,而數(shù)據(jù)規(guī)模盗蟆、業(yè)務復雜度、報表數(shù)量都會不斷增長舒裤,未來極有可能會引發(fā)預計算跑不完而影響業(yè)務使用的問題喳资。

空間問題

預計算的結果是要落地的,往往會存儲在數(shù)據(jù)庫物理表中腾供,這樣的表多了會占用大量數(shù)據(jù)庫空間仆邓,引起數(shù)據(jù)庫容量問題;另外這樣的表多了還會帶來管理上的問題伴鳖。

預計算的應用范圍很窄节值,而 SQL 又比較難優(yōu)化,還有什么其他優(yōu)化手段嗎黎侈?

(3)借助其他高性能計算引擎

在數(shù)據(jù)庫內(nèi)搞不定報表數(shù)據(jù)準備階段優(yōu)化時可以引入其他高性能計算引擎察署,這在業(yè)內(nèi)并不少見,但幾乎所有技術都是采用獨立存儲 + 分布式架構來輸出高性能的峻汉,這對報表應用架構(主要是數(shù)據(jù)庫)的改變就有些大了贴汪,難度很大。

比較簡單直接的方式是在報表內(nèi)部就能提供改變 SQL 執(zhí)行路徑的手段休吠,并且可以改善那些顯著低效的 SQL 算法(比如 topN)扳埂,這樣就可以在不改變應用架構的情況下實現(xiàn)數(shù)據(jù)準備階段的優(yōu)化。

這就要求報表工具提供數(shù)據(jù)準備階段的計算能力瘤礁,既可以分步執(zhí)行 SQL(指定執(zhí)行順序)阳懂,還可以改善算法效率。其表現(xiàn)形式可以是一種內(nèi)置在報表工具中的計算腳本,腳本具備分步計算和強計算能力岩调。

報表工具計算模塊提供可干預 SQL 執(zhí)行路徑能力和高效的強計算能力

2.數(shù)據(jù)傳輸

報表通過 JDBC 接口訪問數(shù)據(jù)庫讀取所需數(shù)據(jù)時巷燥,如果數(shù)據(jù)量比較大或者數(shù)據(jù)庫 JDBC 性能較差(要知道各種數(shù)據(jù)庫的 JDBC 效率是不同的)會導致數(shù)據(jù)傳輸時間過長,導致報表變慢号枕。

由于我們沒法改變數(shù)據(jù)庫的驅(qū)動缰揪,我們只能在報表層面想辦法。一個可行的辦法是通過并行取數(shù)來提速葱淳。

(1)并行取數(shù)

通過建立多個數(shù)據(jù)庫連接(這時要求數(shù)據(jù)庫相對空閑)钝腺,采用多線程的方式同時讀取報表所需數(shù)據(jù),可能是同一個表赞厕,也可能是多個表關聯(lián)計算后的結果艳狐,這樣數(shù)據(jù)傳輸?shù)臅r間理論上就會縮短到原來的 1/n(n 是線程數(shù)),從而提升報表性能皿桑。

那么這種并行取數(shù)實現(xiàn)起來難度如何呢毫目?

因為目前大部分報表工具不支持并行取數(shù),要想通過并行來加速數(shù)據(jù)傳輸只能自己使用 JAVA 硬編碼來做唁毒。我們曾經(jīng)討論過在報表中使用 JAVA 硬編碼準備數(shù)據(jù)的弊端蒜茴,而編寫并行程序難度又提升了一級,要知道浆西,并行以后還要歸并(merge)各個線程的計算結果粉私,merge 不是簡單地縱向拼接就完了,有時還涉及分組和順序近零。

使用支持并行取數(shù)的報表工具

比較簡單有效的方式是使用支持并行取數(shù)的報表工具诺核,報表開發(fā)人員不需要考慮數(shù)據(jù)資源沖突、結果歸并等復雜問題就可以簡單實現(xiàn)久信。

(2)異步傳輸

當數(shù)據(jù)量較大時窖杀,可以通過異步機制將數(shù)據(jù)分批返回給報表,報表接收部分數(shù)據(jù)后就立刻呈現(xiàn)裙士,后臺同時進行不間斷的數(shù)據(jù)傳輸入客,這樣就可以提升報表的呈現(xiàn)速度。

異步傳輸需要考慮很多方面腿椎,不建議自己硬編碼實現(xiàn)桌硫,最好使用支持異步傳輸功能的報表工具,簡單快捷啃炸。

3.報表計算

數(shù)據(jù)傳輸完成后铆隘,報表引擎會根據(jù)已準備數(shù)據(jù)和報表表達式運算報表,這個階段也是非常容易出現(xiàn)性能問題的南用。

性能問題常見于多數(shù)據(jù)集報表膀钠。

現(xiàn)在很多報表工具都提供了多數(shù)據(jù)集能力掏湾,允許開發(fā)者在一個報表中建立多個數(shù)據(jù)集,這樣可以分別組織數(shù)據(jù)肿嘲,尤其當數(shù)據(jù)來自不同數(shù)據(jù)庫時融击,多數(shù)據(jù)集尤其方便。但這種方式為報表開發(fā)帶來便利的同時卻會帶來很嚴重的性能問題雳窟。

我們知道砚嘴,多數(shù)據(jù)集的關聯(lián)是在報表單元格的表達式中完成的,類似這樣 ds2.select(ID==ds1.ID)涩拙,報表引擎在解析這個表達式時會按照順序遍歷的方式完成關聯(lián),即從 ds2 中拿出一條記錄耸采,到 ds1 中遍歷兴泥,查找 ID 相同的記錄;然后再拿第二條再去遍歷查找虾宇;…

這個運算復雜度是平方級的搓彻,數(shù)據(jù)量小的時候沒什么影響,數(shù)據(jù)量稍大時性能就會急劇下降嘱朽。

另外旭贬,報表單元格還帶有大量呈現(xiàn)屬性(顏色、字體搪泳、邊框等)稀轨,帶著這些屬性運算也會拖慢報表的運行速度。所以岸军,對于數(shù)據(jù)量較大的多個數(shù)據(jù)集奋刽,最好在數(shù)據(jù)準備階段使用更高效的關聯(lián)算法完成關聯(lián)。

在數(shù)據(jù)準備階段完成關聯(lián)

將多數(shù)據(jù)集關聯(lián)轉(zhuǎn)移到數(shù)據(jù)準備階段完成艰赞,通過 SQL 就可以實施更加高效的關聯(lián)佣谐,只是 SQL 只能基于單一數(shù)據(jù)庫操作,如果數(shù)據(jù)來自多個數(shù)據(jù)源時就不靈了方妖。這時狭魂,最好報表工具在數(shù)據(jù)準備階段還提供諸如 HASH JOIN 等高性能關聯(lián)算法,以便滿足異構數(shù)據(jù)來源時的關聯(lián)運算党觅。HASH JOIN 算法可以整體地看待幾個數(shù)據(jù)集雌澄,效率比報表工具采用的過濾式關聯(lián)要高得多,幾千行規(guī)模時幾乎是零等待仔役。

4.報表生成

報表計算完成后會生成引擎會將計算結果以 HTML 的形式輸出掷伙,生成最終要呈現(xiàn)報表。這個階段的性能問題主要有兩方面又兵。

(1)頁面渲染慢

當報表中添加了大量的呈現(xiàn)效果(隔行異色任柜、背景圖卒废、警戒色等)時,頁面渲染的速度就會變慢宙地。減少過多的報表效果使用可以提升渲染速度摔认;如果這些效果是必須的,那就要比拼使用的報表工具的能力了宅粥。

另外参袱,如果報表單頁的內(nèi)容過大也會影響頁面呈現(xiàn)的速度。對于比較高或者比較寬的報表呈現(xiàn)時建議采用分頁方式輸出秽梅,從而提升頁面呈現(xiàn)效率抹蚀。

(2)客戶端環(huán)境差

總體上是跟用戶端環(huán)境有關系,比如網(wǎng)絡問題企垦、設備問題等环壤,遇到時需要具體分析。

通過了解報表運行各階段可能出現(xiàn)的性能問題钞诡,以及對應解決辦法郑现,有些我們可以硬編碼或借助其他技術來解決,有些還需要報表自身來提升荧降。最直接的方式是使用能夠提供這些能力的報表工具接箫,這個工具大概要具備這些特性才能幫助我們有效解決報表性能問題。

1. 支持分步

這樣可以有效優(yōu)化 SQL 執(zhí)行路徑朵诫,提升數(shù)據(jù)準備效率辛友;

2. 內(nèi)置強計算能力和高效算法

能夠改善原有低效的算法,提高數(shù)據(jù)計算效率拗窃;

支持 HASH JOIN 等高性能關聯(lián)算法瞎领,以減少在呈現(xiàn)模板中進行多數(shù)據(jù)集關聯(lián);

3. 支持并行取數(shù)

能夠通過多線程并行方式提升數(shù)據(jù)傳輸速度效率随夸;

4. 支持異步讀取

提供異步取數(shù)異步呈現(xiàn)機制九默,加速大數(shù)據(jù)量報表的呈現(xiàn)效率;

5. 支持多數(shù)據(jù)源

提供多樣性數(shù)據(jù)源接口宾毒,并能夠進行多數(shù)據(jù)源關聯(lián)運算(同 2)驼修。

擴展閱讀:

【數(shù)據(jù)蔣堂】第 3 期:功夫都在報表外 - 漫談報表性能優(yōu)化

性能優(yōu)化是個手藝活

如何分析報表性能問題

6. 什么是大報表?

實際業(yè)務中有些報表比較“大”诈铛,查詢出的報表數(shù)據(jù)行數(shù)可以達到幾千萬甚至上億乙各,這類行數(shù)很多的報表通常被成為“大報表”。大報表大部分情況下是清單明細報表幢竹,少量是分組報表耳峦。

大報表查詢通常不會采用一次性取出所有記錄再交給前端呈現(xiàn)的方式,因為這樣要等很久焕毫,用戶體驗極差蹲坷;而且報表服務器內(nèi)存也吃不消驶乾。

常見的方式是通過分頁來呈現(xiàn)大報表,一次只取一小部分數(shù)據(jù)循签,取數(shù)結束后立刻交給前端呈現(xiàn)级乐,當頁碼變化時再取出相應頁數(shù)的數(shù)據(jù),這樣可以加快報表呈現(xiàn)速度县匠,用戶幾乎沒有等待感智玻。

具體如何實現(xiàn)呢芒划?有幾種方式汹来。

1.數(shù)據(jù)庫分頁

業(yè)界最常用的做法是使用數(shù)據(jù)庫分頁來實現(xiàn)哼御,具體來講,就是利用數(shù)據(jù)庫提供的返回指定行號范圍內(nèi)記錄的語法兰粉。界面端根據(jù)當前頁號計算出行號范圍(每頁顯示固定行數(shù))作為參數(shù)拼入 SQL 中扮惦,數(shù)據(jù)庫就會只返回當前頁的記錄,從而實現(xiàn)分頁呈現(xiàn)的效果亲桦。

主要借助關系數(shù)據(jù)庫自身的能力,每種數(shù)據(jù)庫實現(xiàn)上會有所差異浊仆,Oracle 可以使用 rownum客峭,mysql 則可以 limit,具體實現(xiàn)網(wǎng)上有很多資料這里不再贅述抡柿。

數(shù)據(jù)庫分頁有沒有什么不足舔琅?任何技術都有其應用范圍,數(shù)據(jù)分頁的問題主要集中在以下 4 點洲劣。

(1)翻頁時效率較差

用這種辦法呈現(xiàn)第一頁一般都會比較快备蚓,但向后翻頁時,所使用的取數(shù) SQL 會被再次執(zhí)行囱稽,并且將前面頁涉及的記錄跳過郊尝。對于有些沒有 OFFSET 關鍵字的數(shù)據(jù)庫,就只能由界面端自行跳過這些數(shù)據(jù)(取出后丟棄)战惊,而像 ORACLE 還需要用子查詢產(chǎn)生一個序號才能再用序號做過濾流昏。這些動作都會降低效率,浪費時間吞获,前幾頁還感覺不明顯况凉,但如果頁號比較大時,翻頁就會有等待感了各拷。

(2)可能出現(xiàn)數(shù)據(jù)不一致

用這種辦法翻頁刁绒,每次按頁取數(shù)時都需要獨立地發(fā)出 SQL。這樣烤黍,如果在兩頁取數(shù)之間又有了插入知市、刪除動作傻盟,那么取的數(shù)反映的是最新的數(shù)據(jù)情況,很可能和原來的頁號匹配不上初狰。例如莫杈,每頁 20 行,在第 1 頁取出后奢入,用戶還沒有翻第 2 頁前筝闹,第 1 頁包含的 20 行記錄中被刪除了 1 行,那么用戶翻頁時取出的第 2 頁的第 1 行實際上是刪除操作前的第 22 行記錄腥光,而原來的第 21 行實際上落到第 1 頁去了关顷,如果要看,還要翻回第 1 頁才能看到武福。如果還要基于取出的數(shù)據(jù)做匯總統(tǒng)計议双,那就會出現(xiàn)錯誤、不一致的結果捉片。

為了克服這兩個問題平痰,有時候我們還會用另一種方法,用 SQL 游標從數(shù)據(jù)庫中取數(shù)伍纫,在取出一頁呈現(xiàn)后宗雇,但并不終止這個游標,在翻下一頁的時候再繼續(xù)取數(shù)莹规。這種方法能有效地克服上述兩個問題赔蒲,翻頁效率較高,而且不會發(fā)生不一致的情況良漱。不過舞虱,絕大多數(shù)的數(shù)據(jù)庫游標只能單向從前往后取數(shù),表現(xiàn)在界面上就只能向后翻頁了母市,這一點很難向業(yè)務用戶交代矾兜,所以很少用這種辦法。

當然患久,我們也可以結合這兩種辦法焕刮,向后翻頁時用游標,一旦需要向前翻頁墙杯,就重新執(zhí)行取數(shù) SQL配并。這樣會比每次分頁都重新取數(shù)的體驗好一些,但并沒有在根本上解決問題高镐。

(3)無法實現(xiàn)分組報表

除了清單報表溉旋,有時我們還要呈現(xiàn)大數(shù)據(jù)量的分組報表,報表包含分組嫉髓、分組匯總及分組明細數(shù)據(jù)观腊。我們知道邑闲,按頁取數(shù)按照翻頁每次讀取固定條數(shù)(一頁或幾頁)記錄,這樣根本無法保證一次性讀取一個完整分組梧油,而分組呈現(xiàn)苫耸、分組匯總都要求基于整組數(shù)據(jù)來操作,否則就會出錯儡陨。

(4)無法使用其他數(shù)據(jù)源

數(shù)據(jù)庫分頁是借助關系數(shù)據(jù)庫自身的能力褪子,而對于非關系數(shù)據(jù)庫就不靈了。試想一下骗村,NoSQL 怎么用 SQL 分頁嫌褪,文本怎么做分頁?

報表的多樣性數(shù)據(jù)源話題我們曾經(jīng)討論過胚股,在數(shù)據(jù)規(guī)模迅速膨脹的今天笼痛,基于非關系數(shù)據(jù)庫出報表已經(jīng)非常普遍。

除了數(shù)據(jù)庫分頁琅拌,還有其他更好的方式嗎缨伊?

2.硬編碼實現(xiàn)

我們發(fā)現(xiàn)基于數(shù)據(jù)庫的分頁方式強依賴數(shù)據(jù)源,無法滿足其他數(shù)據(jù)源類型的需要进宝,也就是與數(shù)據(jù)庫緊耦合的倘核。我們需要一個低耦合數(shù)據(jù)源的實現(xiàn)方式以應對多樣性數(shù)據(jù)源場景,還能同時解決效率即彪、準確性和分組呈現(xiàn)問題。

按照主流的解題思路活尊,可以通過編碼方式實現(xiàn)這個目標隶校,實現(xiàn)思路大概是這樣:

基于數(shù)據(jù)庫時,

把取數(shù)和呈現(xiàn)做現(xiàn)兩個異步線程蛹锰,取數(shù)線程發(fā)出 SQL 后就不斷取出數(shù)據(jù)后緩存到本地存儲中深胳,呈現(xiàn)線程根據(jù)頁數(shù)計算出行數(shù)到本地緩存中去獲取數(shù)據(jù)顯示。這樣铜犬,只要已經(jīng)取過的數(shù)據(jù)就能快速呈現(xiàn)舞终,不會有等待感,還沒取到的數(shù)據(jù)需要等待一下也是正逞⒒可理解的敛劝;而取數(shù)線程只涉及一句 SQL,在數(shù)據(jù)庫中是同一個事務纷宇,也不會有不一致的問題夸盟。這樣,兩個問題都能得到解決像捶。不過這需要設計一種可以按行號隨機訪問記錄的存儲格式上陕,不然要靠遍歷把記錄數(shù)出來桩砰,那反應仍然會很遲鈍。

基于非數(shù)據(jù)庫時释簿,

同樣設置取數(shù)和呈現(xiàn)兩個異步線程亚隅,取數(shù)時通過文件游標(或其他數(shù)據(jù)源提供的分批取數(shù)接口)分批讀取數(shù)據(jù)并緩存到本地,呈現(xiàn)階段則與上述方式完全一致庶溶。

然后再利用報表工具開放的接口和前端報表進行交互煮纵,完成報表的分頁呈現(xiàn)。

做分組報表時渐尿,

就需要一次性取出完整分組醉途,在代碼里進行分組匯總,并將匯總結果插入結果集一并返回給前端報表進行呈現(xiàn)砖茸,同時還要設置分組記錄標志位隘擎,以便前端報表在呈現(xiàn)時能夠為分組行設置不同的顯示效果(如加粗、標紅)凉夯。

實現(xiàn)后的效果類似下面這樣:

取數(shù)線程不停地取數(shù)緩存货葬,呈現(xiàn)線程從緩存中讀取數(shù)據(jù)呈現(xiàn),總頁數(shù)不斷變化

通過上面的描述劲够,可以看到自己硬編碼雖然可以實現(xiàn)震桶,但復雜度很高。除了多線程編程征绎,還要考慮緩存數(shù)據(jù)存儲形式蹲姐、文件游標、分組讀取與匯總人柿,此外借助其他報表工具進行呈現(xiàn)時還要對方開放足夠靈活的接口柴墩,…,這些都是挑戰(zhàn)凫岖。

而且我們只考慮了呈現(xiàn)江咳,如果還要導出 Excel 怎么辦?如果還要打印怎么辦哥放?畢竟報表既然能查就應該能導出歼指,能打印。這些需求在金融甥雕、制造行業(yè)都是真實存在的踩身。

3使用支持大報表的報表工具

如果前端使用報表工具開發(fā)報表,選用一個直接支持大報表呈現(xiàn)社露、導出惰赋、打印的報表工具則更為直接。工具實現(xiàn)了兩個異步線程的大報表機制,同時解決上面我們提到的問題赁濒,這些方面都封裝好直接使用轨奄。

大數(shù)據(jù)時代要支持大報表,這應該是報表工具必備能力拒炎。

擴展閱讀:

大清單報表應當怎么做挪拟?

海量清單與分組報表的實現(xiàn)

如何實現(xiàn)海量數(shù)據(jù)清單和分組報表

秒級展現(xiàn)的百萬級大清單報表怎么做

7. 中間表是什么?和報表有什么關系击你?會帶來怎樣的問題玉组?

在數(shù)據(jù)庫中有一類用于保存中間計算結果的物理表,通常被稱為“中間表”丁侄。中間表主要跟 OLAP(在線聯(lián)機分析)業(yè)務有關惯雳,產(chǎn)生的原因主要有以下幾方面。

中間表來源

1.計算邏輯復雜

在 OLAP(報表或查詢)業(yè)務中鸿摇,有些計算邏輯很復雜石景,每次都從頭寫會導致報表開發(fā)過于繁瑣,而且有的計算用 SQL 很難寫出來拙吉。這時會采用中間表事先計算好潮孽,再基于預計算的中間結果開發(fā)報表。

計算邏輯復雜常見于報表業(yè)務中筷黔,以固定報表最為常見往史;多維分析則比較少見。

2.查詢性能差

當查詢涉及的數(shù)據(jù)量很大或者計算邏輯很復雜時查詢性能會很差佛舱。為了提升查詢性能椎例,增強用戶體驗,通常會把匯總結果實現(xiàn)計算出來存儲在中間表中请祖《┩幔基于預匯總的中間表查詢速度會快很多。

在實際業(yè)務中损拢,大部分提升查詢速度的中間表也都是為報表服務的。

3.ETL過程轉(zhuǎn)存

ETL 過程也會產(chǎn)生中間表撒犀。ETL 過程中常常會涉及到數(shù)據(jù)庫的數(shù)據(jù)福压,正常的 ETL 過程應當是 E、T或舞、L 這三個步驟逐步進行荆姆,也就是先清洗轉(zhuǎn)換之后再加載進數(shù)據(jù)庫,最后在數(shù)據(jù)庫中的只是合理的結果數(shù)據(jù)映凳。但是胆筒,E(清洗)和 T(轉(zhuǎn)換)這兩個步驟中會涉及到大量數(shù)據(jù)計算,而在數(shù)據(jù)庫外實施這些計算很不方便,所以實際情況就會是把涉及到的所有數(shù)據(jù)都先加載進來然后再進行清洗和轉(zhuǎn)換仆救,ETL 過程變成了 ELT 甚至 LET抒和。事先要加載的這些數(shù)據(jù)在關系數(shù)據(jù)庫中也必須以表的形式存儲,這就使數(shù)據(jù)庫中增加了許多并非最終需要的中間表彤蔽。

如果觀察一下這些跑批任務摧莽,你會發(fā)現(xiàn) ETL 任務很多都是為報表業(yè)務服務的。

4.多樣性數(shù)據(jù)源混合計算

另一種情況是多樣性數(shù)據(jù)源造成的顿痪,這也是為數(shù)據(jù)呈現(xiàn)(報表查詢)服務的∧髟現(xiàn)代應用中的數(shù)據(jù)呈現(xiàn)經(jīng)常會涉及數(shù)據(jù)庫外的數(shù)據(jù),目前一般的做法是把庫外數(shù)據(jù)定時導入到數(shù)據(jù)庫中蚁袭,然后就能和數(shù)據(jù)庫內(nèi)的數(shù)據(jù)一起運算產(chǎn)生報表征懈,否則很難實現(xiàn)數(shù)據(jù)庫內(nèi)外的數(shù)據(jù)的混合運算。這當然也會讓數(shù)據(jù)庫中多了一些表揩悄,而且卖哎,有些互聯(lián)網(wǎng)上取過來的數(shù)據(jù)常常是多層的 json 或 XML 格式,在關系數(shù)據(jù)庫中還要建立多個關聯(lián)的表來存儲虏束,會進一步加劇中間表過多的問題棉饶。

通過列舉的 4 個中間表產(chǎn)生的主要原因,我們發(fā)現(xiàn)一個共同點:中間表大部分情況都是為報表服務的镇匀。我們也知道照藻,實際業(yè)務中的報表數(shù)量非常多,而且報表業(yè)務業(yè)務不穩(wěn)定經(jīng)常會新增修改報表汗侵,這會導致中間表數(shù)量不斷增多幸缕。

中間表會帶來哪些問題

中間表是一把雙刃劍,提供很多便利的同時也會帶來一些問題晰韵。

我們曾在一個運營商的報表系統(tǒng)中发乔,發(fā)現(xiàn)了一個讓人吃驚的現(xiàn)象。在 DB2 數(shù)據(jù)倉庫中雪猪,有兩萬多個數(shù)據(jù)庫表栏尚!經(jīng)過深入了解發(fā)現(xiàn),真正的原始數(shù)據(jù)表只有幾百張只恨,剩下的大量的數(shù)據(jù)庫表都是為查詢和報表服務的中間表译仗。

像這種系統(tǒng)經(jīng)過幾年乃至十幾年的運行,數(shù)據(jù)庫中的中間表越來越多官觅,甚至出現(xiàn)這種上萬個的情況并不少見纵菌。大量中間表帶來的直接困擾是數(shù)據(jù)庫存儲空間不夠用,面臨頻繁的擴容需求休涤。中間表對應的存儲過程咱圆、觸發(fā)器等等需要占用數(shù)據(jù)庫的計算資源,也會造成數(shù)據(jù)庫的擴容壓力。

中間表過多還會帶來管理方面的問題序苏,對于成千上萬張中間表想要梳理清楚恐怕是一件非常頭疼的事情手幢。

那么,是不是可以清理掉一些不用的中間表杠览?一般的結論都是:搞不動弯菊。數(shù)據(jù)庫中的中間表是不同程序員制作的,有的是綜合查詢系統(tǒng)使用踱阿,有的是報表系統(tǒng)使用管钳。中間表之間還存在交叉引用,有些程序員看到有別人生成的中間表就直接使用了软舌。有時候一些查詢報表已經(jīng)廢棄不用了才漆,但是對應的中間表沒人敢刪,因為不知道刪掉之后會影響其他什么查詢或者報表佛点。

很多情況下醇滥,項目組只好為了越來越多的中間表去擴容數(shù)據(jù)庫。但是數(shù)據(jù)庫的擴容成本太昂貴了:不管是換更強的服務器(縱向擴容)超营,還是增加數(shù)據(jù)庫服務器的節(jié)點(橫向擴容)鸳玩,都不便宜。

總結來說演闭,中間表會帶來管理不跟、容量和性能三方面的問題。

如何解決中間表的問題米碰?

可以很容易想到的方式是使用庫外文件存儲中間表數(shù)據(jù)窝革,這樣中間表脫離了數(shù)據(jù)庫就不會對數(shù)據(jù)庫再產(chǎn)生影響。但是吕座,在實際應用中這種辦法卻很少使用虐译。為什么呢?

我們知道吴趴,中間表是要再計算的漆诽,基于中間表查詢的報表還要進行數(shù)據(jù)過濾,有的還要再次匯總锣枝,還可能涉及關聯(lián)計算厢拭,這些操作在數(shù)據(jù)庫里通過 SQL 完成很簡單。但是文件沒有計算能力惊橱,要實施這些計算只能硬編碼蚪腐,用 JAVA 來做箭昵,使用 JAVA 來做集合運算又非常麻煩税朴,遠沒有數(shù)據(jù)庫(SQL)方便。所以采用文件存儲中間表的方式使用并不廣泛,主要是由實現(xiàn)復雜度過高導致的正林。

那還有什么好的方式呢泡一?

使用支持文件源的報表工具

既然中間表大部分是為報表服務的,而通過將中間表外置到文件中可以解決中間表帶來的這些問題觅廓,那么直接使用支持文件源的報表工具是否就可以了呢鼻忠?

答案是肯定的。

我們來看一下要實現(xiàn)這個目標杈绸,報表工具要具備哪些能力帖蔓?

(1)豐富的計算類庫

要解決文本計算難的問題,報表工具要提供豐富的計算類庫瞳脓,除了能完成所有數(shù)據(jù)處理任務(都能算)以外塑娇,還要實現(xiàn)簡單,這是基礎劫侧,太復雜了沒法用埋酬;

(2)多樣性數(shù)據(jù)源接口

支持多樣性數(shù)據(jù)源以后,就可以不用通過數(shù)據(jù)庫中轉(zhuǎn)直接讀取多樣性數(shù)據(jù)源數(shù)據(jù)出報表烧栋;

(3)異構數(shù)據(jù)源混合計算能力

提供多樣性數(shù)據(jù)源接口后写妥,還要能夠進行異構源間的混合計算,這樣就可以徹底解決掉多樣性數(shù)據(jù)源帶來的中間表問題审姓;

(4)高性能

除了實現(xiàn)簡單以外珍特,計算性能也要有保障,從而滿足前端報表查詢的性能需要邑跪。

具體實現(xiàn)上可以在報表工具中增加計算模塊來對接“庫外中間表”次坡,結構類似這樣

其中庫外中間數(shù)據(jù)文件可以采用本地文件,也可以使用網(wǎng)絡或分布式文件系統(tǒng)画畅,或其他數(shù)據(jù)源砸琅。

要解決中間表問題,需要報表工具強化自身的計算能力才能實現(xiàn)轴踱!

擴展閱讀:

【數(shù)據(jù)蔣堂】第 14 期:計算封閉性導致臃腫的數(shù)據(jù)庫

【數(shù)據(jù)蔣堂】第 15 期:開放的計算能力為數(shù)據(jù)庫瘦身

有效減少數(shù)據(jù)庫中間表的報表開發(fā)方法

為什么會有這么多中間表症脂?

8. 報表熱切換是什么意思?

熱切換(Hot Swap)是指在系統(tǒng)不停機的情況下更換系統(tǒng)部件淫僻,在報表業(yè)務中則是指在不重啟報表及相關應用的情況下完成對報表的維護(新增诱篷、修改、刪除)雳灵,冷切換則恰好相反棕所。

報表業(yè)務很不穩(wěn)定,業(yè)務開展的過程中會刺激出更多查詢統(tǒng)計需求悯辙,如果每次需求實現(xiàn)后都要等系統(tǒng)空閑(往往是非工作時間)時重啟系統(tǒng)才能讓修改后的報表生效琳省,那將會對業(yè)務使用造成非常大影響(延遲)迎吵。因此在需求經(jīng)常會變化的報表業(yè)務中,熱切換顯得尤其重要针贬。

事實上击费,在報表業(yè)務中要實現(xiàn)熱切換并不難,只要在開發(fā)報表時選擇合適的技術手段桦他,避免使用諸如 JAVA 這樣的編譯型語言(雖然重寫類加載器可以變相實現(xiàn)熱加載蔫巩,但過于繁瑣,也沒從根本上解決問題)即可快压。

但在實際應用中我們卻看到大量使用 JAVA 來開發(fā)報表圆仔,造成無法熱切換的情況。為什么會這樣蔫劣?

報表業(yè)務有兩個特點荧缘,一個是報表業(yè)務很復雜。報表是一項負責綜合性統(tǒng)計的任務拦宣,將原始數(shù)據(jù)加工成業(yè)務需要的報表形式要走很長的路截粗,不僅數(shù)據(jù)處理邏輯繁瑣,報表呈現(xiàn)樣式也千奇百怪鸵隧,所謂中國式復雜報表绸罗。

另一個特點是嵌入使用。報表經(jīng)常會作為應用系統(tǒng)的一部分(模塊)嵌入到系統(tǒng)中使用豆瘫。

現(xiàn)在報表呈現(xiàn)格式方面的問題已經(jīng)基本得到解決珊蟀,以國內(nèi)成熟報表工具為主導的一批國產(chǎn)軟件可以很好地解決中國式復雜報表呈現(xiàn)的問題,而且這些工具大多數(shù)采用解釋執(zhí)行機制外驱,報表模板修改后可以實時生效育灸。

但數(shù)據(jù)準備階段的問題卻一直沒有解決,復雜的數(shù)據(jù)處理和業(yè)務邏輯控制讓開發(fā)人員不得采用硬編碼手段來實現(xiàn)昵宇。由于大部分應用系統(tǒng)都采用 JAVA 開發(fā)磅崭,既然報表是系統(tǒng)的一部分,業(yè)務邏輯又這么復雜瓦哎,硬編碼的首選自然是 JAVA 了砸喻。這是導致在報表中大量使用 JAVA 導致無法熱切換的原因。

那么如何解決這個問題蒋譬?

將報表的數(shù)據(jù)準備也工具化割岛!

早期,報表開發(fā)完全靠硬編碼的時代犯助,大家也普遍采用 JAVA 來“畫”報表癣漆,這樣勢必存在無法熱切換的問題,后來報表工具出現(xiàn)解決了呈現(xiàn)模板的熱切換問題剂买。所以惠爽,要徹底實現(xiàn)報表熱切換腰湾,將數(shù)據(jù)準備也工具化是一個可行的方向。

然而着倾,報表的數(shù)據(jù)準備和報表呈現(xiàn)兩個階段分別使用不同工具會造成報表開發(fā)和維護上的困擾氯迂,因此,最好的方式是增強報表工具自身的計算能力,將兩個階段都融入可以解釋執(zhí)行的報表模板中撵割,從而徹底實現(xiàn)報表熱切換。

我們知道远搪,報表工具本身具備一定的計算能力裤纹,在呈現(xiàn)模板的單元格中可以編寫分組、求和把跨、比值等表達式人弓,但由于格子的限制很難處理復雜的數(shù)據(jù)邏輯,這也是為什么在報表中需要數(shù)據(jù)集(JAVA/SQL)來準備數(shù)據(jù)的原因着逐。

一個可行的辦法是在報表工具中增加可解釋執(zhí)行的計算腳本(模塊)用于數(shù)據(jù)準備崔赌,這樣在計算模塊中可以實現(xiàn)任意復雜的數(shù)據(jù)處理邏輯,同時解釋執(zhí)行的腳本內(nèi)置在報表模板中實現(xiàn)熱切換耸别。

報表計算模塊(腳本)要具備這樣一些能力:1.解釋執(zhí)行

這是實現(xiàn)熱切換的基本能力健芭,數(shù)據(jù)準備和報表呈現(xiàn)內(nèi)置在一個報表模板中,采用解釋執(zhí)行機制運行秀姐;

2.計算體系完善

能實現(xiàn)所有的數(shù)據(jù)處理任務慈迈,原來在 JAVA 中的報表數(shù)據(jù)準備計算在腳本中都應該能完成,具備豐富的集合運算類庫省有;

3.易開發(fā)維護

實現(xiàn)上要足夠簡單痒留,這樣報表開發(fā)人員就能直接搞定數(shù)據(jù)準備和報表呈現(xiàn),而不再依賴其他專業(yè)程序員蠢沿;同時在一個報表模板里更易于維護伸头。

參考資料:

如何應對報表開發(fā)中的復雜邏輯

9. 報表沒完沒了是個什么狀況?

可以先想一下自己的部門或項目組是否面臨這些問題:

1. 投入很多技術力量做報表舷蟀,卻還是疲于應付

2. 用了高端報表工具和敏捷 BI熊锭,卻還是不夠用

3. 技術高手用來做報表,感覺很浪費 4. 對于頻繁多變的報表需求雪侥,需要低成本應對方案

專門用于統(tǒng)計分析的報表業(yè)務有一個特點碗殷,就是業(yè)務穩(wěn)定性非常差。在業(yè)務開展過程中會催生很多新的查詢需求速缨,而且已實現(xiàn)的查詢需求還會經(jīng)常變化锌妻,這就造成了沒完沒了的報表。所以經(jīng)常會有這么一段對話

報表沒完沒了是需求使然旬牲,無法規(guī)避仿粹,只能適應搁吓,而目前主要的是問題是普遍缺少一種低成本的方案來適應沒完沒了的報表。

為什么報表開發(fā)成本一直居高不下吭历?

我們知道堕仔,報表工具的主要作用是將報表呈現(xiàn)階段的開發(fā)工具化,使用報表工具可以將原本需要硬編碼的工作通過工具來提高生產(chǎn)效率晌区;但報表開發(fā)的另一個階段:數(shù)據(jù)準備摩骨,卻仍然在使用原始的硬編碼方式處理,有時我們要編寫非常復雜的 SQL朗若、存儲過程和 JAVA 程序恼五,這樣的工作通常要依賴高水平的技術人員才能完成。

另外哭懈,采用過于原始手段會帶來報表維護困難灾馒,復雜的代碼無論從編寫還是修改都比較困難,這樣又會加劇報表開發(fā)成本居高不下遣总!

除了技術原因外睬罗,還有應用結構和團隊管理方面的因素也會造成報表開發(fā)的成本居高不下。在許多應用系統(tǒng)中旭斥,報表是耦合在其中的一些功能傅物,而業(yè)務系統(tǒng)的技術環(huán)境很復雜,這就迫使報表開發(fā)人員也要熟悉這些東西琉预,也就很難把報表開發(fā)人員和業(yè)務系統(tǒng)的開發(fā)人員分開董饰,業(yè)務系統(tǒng)上線之后,開發(fā)人員仍然要繼續(xù)堅守開發(fā)報表圆米,很難把這項工作轉(zhuǎn)交給客戶方的運維人員卒暂。

開發(fā)過程中的有效溝通也會影響工作量。我們經(jīng)常會發(fā)現(xiàn)這樣的現(xiàn)象:業(yè)務人員提出報表需求娄帖,等技術人員做好后才發(fā)現(xiàn)某些概念術語的理解有誤也祠,統(tǒng)計口徑不一致,結果并不是業(yè)務人員想要的近速,然后也只能重做诈嘿,甚至反復多次才能正確實現(xiàn),嚴重浪費開發(fā)資源削葱。

如何解決報表開發(fā)成本過高奖亚?如何低成本地應對沒完沒了的報表?

可以嘗試通過如下五個步驟來解決這些問題析砸。

1.引入報表工具

先把最容易解決的問題解決掉昔字,通過引入專業(yè)的報表工具解放報表數(shù)據(jù)呈現(xiàn)階段的人力,報表工具可以完成包括中國式復雜報表在內(nèi)的各種圖表呈現(xiàn)首繁。選擇成熟且性價比高的工具是這個階段的主要目標作郭。

2.增加計算模塊

引入報表工具后陨囊,解放了數(shù)據(jù)呈現(xiàn)階段的人力,降低了一定的成本夹攒,但占主要部分的報表數(shù)據(jù)準備階段仍未解決蜘醋。

數(shù)據(jù)準備階段的特點是:1. 編碼困難,沒有普適的工具 2. 對人員要求高咏尝,需要高水平技術人員完成 3. 實現(xiàn)周期過長压语,難以適應多變的報表需求 4. 硬編碼耦合性高,依賴數(shù)據(jù)庫和 JAVA 都都會造成緊耦合 5. 運維過于復雜状土,修改維護成本提高

這時,我們需要沿著第一步的方向繼續(xù)前進伺糠,將數(shù)據(jù)準備階段也工具化蒙谓。比較好的方式是

在報表工具中增加用于數(shù)據(jù)準備的計算模塊,將原來使用 SQL/ 存儲過程 /JAVA 實現(xiàn)的數(shù)據(jù)準備算法训桶,全部通過計算模塊完成累驮,使得報表開發(fā)徹底工具化,簡化開發(fā)舵揭,降低成本谤专。

計算模塊的能力可以通過腳本來實現(xiàn),在腳本中內(nèi)置各種豐富的計算類庫午绳,讓報表開發(fā)人員獨立就能完成數(shù)據(jù)準備階段的工作置侍,從而全面接管報表的開發(fā),而不再依賴其他專業(yè)程序員拦焚。

這里尤其要注意蜡坊,報表計算模塊需要具備這樣一些能力。

1.易于編碼

包含豐富的計算類庫赎败,可以很方便地完成各類數(shù)據(jù)計算任務秕衙;必要時還能提供可視化的編輯調(diào)試環(huán)境進一步簡化這個階段的開發(fā);

2.支持熱切換

計算模塊需采用解釋執(zhí)行機制僵刮,這樣可以很好地和前端報表呈現(xiàn)模板結合在一起据忘,報表修改后可以實時生效,無需重啟整個應用搞糕;

3.支持多樣性數(shù)據(jù)源

提供 RDB勇吊、NoSQL、文本窍仰、Excel萧福、hadoop 等多樣性數(shù)據(jù)源接口,報表直接基于多言行數(shù)據(jù)源開發(fā)辈赋,也可以進行混合計算(如 Excel 和 RDB 的表 join)鲫忍;

4.高性能

計算模塊的計算性能不能低于原來 SQL/JAVA 的計算性能膏燕,最好高于原來的實現(xiàn)方式。

報表開發(fā)全面工具化以后悟民,就可以獲得更高的報表開發(fā)效率坝辫,進一步降低報表開發(fā)成本。

3.獨立報表模塊

報表開發(fā)全面工具化以后射亏,就可以著手梳理應用結構近忙,獨立報表模塊,從而將報表模塊從業(yè)務系統(tǒng)中解耦出來智润。

1.梳理數(shù)據(jù)源

首先梳理數(shù)據(jù)源及舍,將報表業(yè)務相關的數(shù)據(jù)源都整理出來,以后的報表開發(fā)只需要和這些數(shù)據(jù)源打交道窟绷;同時為下一步剝離報表業(yè)務做準備锯玛。

2.剝離報表業(yè)務

將數(shù)據(jù)源和業(yè)務應用中與報表相關的數(shù)據(jù)準備(復雜 SQL、存儲過程兼蜈、中間匯總表攘残、自定義 JAVA 類)全部轉(zhuǎn)移到報表工具中實現(xiàn);同時將這些內(nèi)容從數(shù)據(jù)庫和業(yè)務應用中清除为狸,完成報表業(yè)務剝離歼郭。

3.獨立報表模塊

報表業(yè)務完全剝離后,在報表工具中實現(xiàn)的報表在物理上就可以獨立于數(shù)據(jù)源和業(yè)務模塊存儲辐棒,不再與業(yè)務系統(tǒng)和數(shù)據(jù)源緊密耦合病曾,完全獨立報表模塊

4.調(diào)整應用結構

獨立報表模塊后,報表模塊與業(yè)務模塊共享數(shù)據(jù)存儲漾根;應用系統(tǒng)調(diào)用報表模塊為用戶輸出報表結果知态;同時解釋執(zhí)行報表模塊支持熱切換,即改即用立叛,無需重啟應用负敏。

獨立報表模塊以后,報表就可以單獨修改和維護秘蛇,清晰的應用結構會進一步降低報表開發(fā)成本其做。

4.建設報表團隊

報表模塊獨立后,建設專門的報表開發(fā)團隊赁还,不再需要高成本應用程序員或 DBA 參與報表開發(fā)妖泄,進一步降低報表開發(fā)成本。

報表開發(fā)人員就無需應對紛繁復雜的應用環(huán)境艘策,更無需關系應用架構蹈胡,只需根據(jù)已有架構開發(fā)報表就可以了。半年以上工作經(jīng)驗的技術人員就能勝任(其實,理工科應屆畢業(yè)生就可以了罚渐,甚至高中學歷都行)却汉。

簡化報表開發(fā)后,還可以嘗試將持續(xù)的報表開發(fā)工作移交給客戶方的本地運維人員荷并,這樣不僅能降低開發(fā)商的成本合砂,還能提高對客戶的響應速度。

5.完善溝通機制

最后就是建立有效的溝通機制源织,減少交流中的誤解翩伪。

一個簡單可行的辦法就是建立企業(yè)內(nèi)部的報表知識庫,技術形式上搞一個論壇即可谈息。把以前做過的報表收集到論壇上加以評注缘屹,并提供搜索功能。

當有了新的報表需求時侠仇,可以搜索歷史庫中是否曾經(jīng)做過類似的報表(出現(xiàn)過相同的業(yè)務術語)轻姿。歷史報表中保留有相關代碼或公式,而這些形式化的信息不會有歧義傅瞻,這就能幫助新的開發(fā)人員正確理解業(yè)務術語踢代。

甚至許多報表部分還可以被直接復用盲憎,在人員變動時也可以最大限度地保證業(yè)務知識的繼承嗅骄。

應對報表沒完沒了是一個長期的過程,是涉及技術饼疙、管理等諸多方面的綜合性事務溺森。當這些步驟完成以后就可以全方位應對沒完沒了的報表了。

擴展閱讀:

應對報表沒完沒了的五個步驟

一勞永逸地“解決”沒完沒了的報表開發(fā)

結語

報表做不完窑眯,都賴數(shù)據(jù)源屏积;報表開發(fā)快與慢,數(shù)據(jù)準備是關鍵磅甩。

通過提升報表工具的數(shù)據(jù)準備能力可以解決大部分報表開發(fā)過程中的深層問題炊林, 從而通過改進生產(chǎn)工具來提升生產(chǎn)效率。這樣卷要,在選擇報表工具時渣聚,除了能滿足呈現(xiàn)方面的需求外,也要關注工具本身的數(shù)據(jù)準備能力僧叉,自然是越強越好奕枝。

關于當前主流報表工具在這方面的能力,可以搜索“十大活躍報表深度點評”瓶堕,其中有深入的評論隘道。

我們還將持續(xù)關注報表開發(fā)中遇到的各類難題,對這方面感興趣的同學可以再搜索“乾學院”上的免費商業(yè)智能課程,進一步了解和學習谭梗。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末忘晤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子默辨,更是在濱河造成了極大的恐慌德频,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缩幸,死亡現(xiàn)場離奇詭異壹置,居然都是意外死亡,警方通過查閱死者的電腦和手機表谊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門钞护,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人爆办,你說我怎么就攤上這事难咕。” “怎么了距辆?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵余佃,是天一觀的道長。 經(jīng)常有香客問我跨算,道長爆土,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任诸蚕,我火速辦了婚禮步势,結果婚禮上,老公的妹妹穿的比我還像新娘背犯。我一直安慰自己坏瘩,他們只是感情好,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布漠魏。 她就那樣靜靜地躺著倔矾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪柱锹。 梳的紋絲不亂的頭發(fā)上哪自,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天,我揣著相機與錄音奕纫,去河邊找鬼提陶。 笑死,一個胖子當著我的面吹牛匹层,可吹牛的內(nèi)容都是我干的隙笆。 我是一名探鬼主播锌蓄,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼撑柔!你這毒婦竟也來了瘸爽?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤铅忿,失蹤者是張志新(化名)和其女友劉穎剪决,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體檀训,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡柑潦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了峻凫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渗鬼。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖荧琼,靈堂內(nèi)的尸體忽然破棺而出譬胎,到底是詐尸還是另有隱情,我是刑警寧澤命锄,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布堰乔,位于F島的核電站,受9級特大地震影響脐恩,放射性物質(zhì)發(fā)生泄漏镐侯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一被盈、第九天 我趴在偏房一處隱蔽的房頂上張望析孽。 院中可真熱鬧搭伤,春花似錦只怎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至拍鲤,卻和暖如春贴谎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背季稳。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工擅这, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人景鼠。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓仲翎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子溯香,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355