閆濤++朱希安
摘要: 醫(yī)藥采購系統(tǒng)的用戶數(shù)量很多,每個用戶每年采購的藥品數(shù)量龐大。數(shù)據(jù)庫存儲的數(shù)據(jù)過多會極大的影響系統(tǒng)的性能,查詢的速率會降低。為了提升系統(tǒng)的性能,該文從數(shù)據(jù)聚合、動態(tài)建表,按年存儲這兩個角度進(jìn)行了設(shè)計與實(shí)現(xiàn)。從而提升了系統(tǒng)的查詢速率、系統(tǒng)的性能得到了優(yōu)化。
關(guān)鍵詞:數(shù)據(jù)聚合;動態(tài)建表;按年存儲
中圖分類號:TP311 文獻(xiàn)標(biāo)識碼:A 文章編號:1009-3044(2015)09-0263-02
醫(yī)藥系統(tǒng)的業(yè)務(wù)用戶有市衛(wèi)生局、鎮(zhèn)衛(wèi)生院、村衛(wèi)生室、供貨商。涉及到的采購單位是一個市下屬的各個村衛(wèi)生室、社區(qū)醫(yī)院。一個大的市下屬的村和社區(qū)大概有個3000左右。一個采購單位每月分上中下旬采購藥品,每次保守采購100個藥品。一年采購量:3000*100*3*12=10800000,一年下來采購量估計在千萬級。系統(tǒng)上線后,運(yùn)行幾年后會存儲量很大。存儲隨著年復(fù)一年,日復(fù)一日,存儲量會非常大。 為此我們選用了Oracle數(shù)據(jù)庫,Oracle 是海量存儲的數(shù)據(jù)庫,比Mysql要強(qiáng)很多,Mysql最多存儲量大概是二百萬左右,如果再多就超出它的能力范圍。所以,我們使用Oracle海量存儲。Oracle海量存儲可以存很多,但是,如果存儲很多,我們要做一些查詢、統(tǒng)計分析,查詢的效率很低,系統(tǒng)反應(yīng)很慢。
我們可以對表進(jìn)行一些優(yōu)化,比如說:加一些索引,我們可以使用Oracle的一些分區(qū)表,可以做一些sql語句的優(yōu)化。但是,這些都是治標(biāo)不治本的。治本的解決需要待查詢的表存儲的數(shù)據(jù)少,我們現(xiàn)在需要對系統(tǒng)進(jìn)行一個根本的解決。
1 解決方案的設(shè)計與實(shí)現(xiàn)
本文主要從數(shù)據(jù)聚合、動態(tài)建表,按年存儲這兩個角度對系統(tǒng)的性能進(jìn)行優(yōu)化。數(shù)據(jù)聚合針對系統(tǒng)的統(tǒng)計分析功能模塊進(jìn)行的設(shè)計;動態(tài)建表、按年存儲涉及到系統(tǒng)的核心功能模塊--采購單模塊,對系統(tǒng)采購單模塊相關(guān)的表進(jìn)行存儲,全部是按年存儲。
1.1 數(shù)據(jù)聚合
1.1.1問題的提出
采購系統(tǒng)有個功能模塊是統(tǒng)計分析。系統(tǒng)有市衛(wèi)生局、衛(wèi)生院、衛(wèi)生室、供貨商四個業(yè)務(wù)用戶。市衛(wèi)生局查詢本市所有醫(yī)院及供貨商的交易明細(xì),衛(wèi)生室查詢本地區(qū)所有醫(yī)院與供貨商的交易明細(xì),醫(yī)院查詢本醫(yī)院的交易明細(xì),供貨商查詢與自己供貨相關(guān)的交易明細(xì)。
根據(jù)用戶的需求,統(tǒng)計分析模塊中按交易明細(xì)的統(tǒng)計效果圖2所示:
從圖中我們可以看出明細(xì)查詢涉及到:采購單明細(xì)、入庫信息、退貨信息、結(jié)算信息。采購單明細(xì)是必須顯示出來,入庫信息有則顯示沒有不顯示,退貨信息有則顯示沒有不顯示,結(jié)算信息有則顯示沒有不顯示。
1.1.2 一般的解決思路及存在問題
思路:采用采購單明細(xì)表分別和入庫表、退貨表、結(jié)算表左連接查詢。
存在問題:采購單明細(xì)一年下來上百萬,入庫表也是上百萬,退貨表少,結(jié)算表上百萬數(shù)據(jù)大,進(jìn)行關(guān)聯(lián)查詢速度很慢。
1.1.3 采用數(shù)據(jù)聚合進(jìn)行優(yōu)化
將采購單明細(xì)、入庫信息、退貨信息、結(jié)算信息的數(shù)據(jù)融合到一張表里,這時去查詢速度很快,不用進(jìn)行關(guān)聯(lián)查詢。創(chuàng)建一張表:YYBUSINESS,此表匯集了那幾張表所有的字段.
同步數(shù)據(jù)時機(jī):
對于采購單明細(xì)數(shù)據(jù),采購單審核通過后開始向交易明細(xì)表(yybusiness)插入數(shù)據(jù)。將該采購單下的采購藥品信息插入yybusiness表。由于有業(yè)務(wù)邏輯采購單審核通過,所以采用service層修改代碼實(shí)現(xiàn)數(shù)據(jù)同步。
對于入庫信息、退貨信息、結(jié)算信息這三張表數(shù)據(jù)采用采用觸發(fā)器實(shí)現(xiàn)數(shù)據(jù)同步。
入庫表上建立的觸發(fā)器源代碼如下:
create or replace trigger yycgdrk2014_insert after insert on yycgdrk2014 for each row
declare begin update Yybusiness2014 t set t.rkl = :new.rkl,t.rkje = :new.rkje,t.ypph = :new.ypph,t.cgzt = :new.cgzt,t.rkdh = :new.rkdh,t.ypyxq = :new.ypyxq,t.rktime = :new.rktime where t.yycgdid = :new.yycgdid and t.ypxxid = :new.ypxxid; end yycgdrk2014_insert;
這樣,本系統(tǒng)將藥品的采購信息、入庫信息、退貨信息、結(jié)算信息全部聚合在一張交易明細(xì)表中,統(tǒng)計分析時在該表(交易明細(xì)表)上進(jìn)行統(tǒng)計分析。由原來的多表關(guān)聯(lián)改為單表查詢,速度提升。
1.2 動態(tài)建表,按年存儲
1.2.1 動態(tài)建表
動態(tài)建表是創(chuàng)建定時任務(wù),由定時任務(wù)去執(zhí)行存儲過程。由存儲過程自動創(chuàng)建所有用到業(yè)務(wù)表(動態(tài)表)及與表相關(guān)的觸發(fā)器、外鍵、索引、序列。如果讓人去創(chuàng)建,顯然是不合理,時機(jī)也不好把握。
創(chuàng)建定時任務(wù)的三種方法:1)java 程序啟動一個定時任務(wù);2)數(shù)據(jù)庫上建立一個定時任務(wù);3)在操作系統(tǒng)上創(chuàng)建一個定時任務(wù)。
本系統(tǒng)采用第三種方法去創(chuàng)建定時任務(wù)。創(chuàng)建的定時任務(wù),是到點(diǎn)去執(zhí)行Oracle.bat文件。Bat文件的內(nèi)容是連接到數(shù)據(jù)庫,執(zhí)行sql。Bat文件內(nèi)容是:
sqlplus yycg0406/yycg0406_192.168.56.101 @c:\test.sql。test.sql的內(nèi)容是執(zhí)行存儲過程。具體內(nèi)容是:call create_tableJob();
create_tableJob的原代碼如下:
create or replace procedure create_tableJob Authid Current_User as
year1 varchar2(4);
year2 varchar2(4);
begin
select to_char(sysdate,'yyyy')into year1 from dual;
select to_char(to_char(sysdate,'yyyy')+1)into year2 from dual;
create_businesstable(year1);
create_businesstable(year2);
end create_tableJob;
create or replace procedure create_businesstable(year in varchar2) Authid Current_User as
begin
create_business(year);
create_businesscgd(year);
create_businesscgdmx(year);
create_businesscgdrk(year);
create_businessthd(year);
create_businessthdmx(year);
create_businessjsd(year);
create_businessjsdmx(year);
end create_businesstable;
1.2.2按年存儲
動態(tài)分表的策略一定是根據(jù)用戶的需求決定。因?yàn)橛脩舨樵儾少弳蔚慕y(tǒng)計信息,一般都是按年進(jìn)行查詢的。沒有動態(tài)分表,系統(tǒng)就是一個表。按年存儲采購單后面加年份。年份是4位。例如:yycgd2014,yycgdmx2014。如果是按年存儲,需要對自動生成的mapper.xml
進(jìn)行修改。例如:Yycgd變成yycgd${businessyear},通過mapper中的傳入?yún)?shù)擴(kuò)充businessyear字段來實(shí)現(xiàn)。擴(kuò)充后,可以將參數(shù)傳入mapper中的sql語句中。
具體操作步驟:
1)按照原來生成規(guī)則生成mapper及po類,是根據(jù)模版表生成.
2)修改mapper.xml文件中的內(nèi)容
將表名后邊加:${businessyear}
3)修改生成的po類,XXX Example類
繼承BusinessBasePo類
BusinessBasePo類擴(kuò)充businessyear字段。
2 結(jié)束語
本文針對開發(fā)的醫(yī)藥采購系統(tǒng)中存在的大數(shù)量存儲的問題導(dǎo)致的系統(tǒng)查詢效率低下問題,從數(shù)據(jù)聚合、動態(tài)建表,按年存儲角度進(jìn)行了設(shè)計與實(shí)現(xiàn)。數(shù)據(jù)聚合解決了多表關(guān)聯(lián)從而導(dǎo)致的查詢慢的問題。將數(shù)據(jù)聚合到一張表上,從一張表查詢統(tǒng)計的數(shù)據(jù)。動態(tài)建表是由定時任務(wù)定時去創(chuàng)建相關(guān)的表。采購的相關(guān)信息按年進(jìn)行了存儲。從而用戶從頁面查詢時選擇查詢的年份,查詢出相關(guān)年份的信息。這樣解決了查詢效率低下的問題。從一定程度上對系統(tǒng)的性能進(jìn)行了優(yōu)化。
參考文獻(xiàn):
[1] 閻冰潔, 萬亮, 肖敏. 高性能查詢分頁技術(shù)的研究與應(yīng)用[J]. 電腦知識與技術(shù), 2006(14): 74.
[2] 王焜, 李翠華. 基于J2EE的高校教學(xué)管理系統(tǒng)的性能優(yōu)化設(shè)計[J]. 計算機(jī)與現(xiàn)代化, 2008(11): 134.
[3] 武志鵬. web服務(wù)的性能優(yōu)化研[D]. 廈門: 廈門大學(xué), 2007.
[4] 魏璞. web優(yōu)化的研究及其應(yīng)用[D].北京: 北京郵電大學(xué), 2008.