袁海龍,董 建,鄧小超,張昊彤,李 鋒,王 堅,金 革
(1中國科學(xué)技術(shù)大學(xué)近代物理系,安徽 合肥 230026;2中國科學(xué)院國家天文臺,北京 100012)
大面積天區(qū)多目標(biāo)光纖光譜天文望遠(yuǎn)鏡(LAMOST[1])是目前多目標(biāo)光纖光譜觀測中最先進(jìn)的望遠(yuǎn)鏡,具備優(yōu)越的巡天能力,能同時觀測4000個目標(biāo),每個觀測夜能觀測上萬顆星,預(yù)計年觀測量能上百萬。LAMOST巡天的主要科學(xué)目標(biāo)有星系紅移巡天、類星體巡天、恒星與銀河系觀測計劃和多波段巡天的光學(xué)證認(rèn)[2],進(jìn)行巡天的星表由天文研究人員根據(jù)研究的需要進(jìn)行篩選。巡天戰(zhàn)略系統(tǒng)(SSS[3])的主要任務(wù)是根據(jù)天文學(xué)家的觀測需求和觀測約束條件,管理觀測星表,制定觀測計劃,部署望遠(yuǎn)鏡的巡天過程,以盡可能高的效率完成巡天。
在巡天觀測系統(tǒng)的體系架構(gòu)中,星表數(shù)據(jù)庫處于中心位置。星表數(shù)據(jù)記錄了每個觀測目標(biāo)的坐標(biāo)、自行、星等、觀測要求等重要信息。星表數(shù)據(jù)來源于世界各地天文臺的“成像巡天”,天文研究人員根據(jù)研究的需要選擇觀測對象,并匯總到觀測星表數(shù)據(jù)庫統(tǒng)一規(guī)劃。然而,數(shù)據(jù)來源往往分散存儲在各個不同類型的數(shù)據(jù)庫系統(tǒng),并且經(jīng)常有各自不同的數(shù)據(jù)格式,傳統(tǒng)的執(zhí)行方案是針對各個數(shù)據(jù)庫安裝不同的數(shù)據(jù)訪問終端、篩選觀測目標(biāo)、導(dǎo)出數(shù)據(jù)、使用輔助工具轉(zhuǎn)換格式、使用SSS數(shù)據(jù)庫的終端導(dǎo)入星表,這是一個費時費力的過程。因此,提供一個方便簡潔的星表選擇和錄入環(huán)境是有必要和有意義的。
為了建立友好的數(shù)據(jù)訪問和星表錄入支持環(huán)境,本文以JDBC(Java Database Connectivity,Java數(shù)據(jù)庫連接)技術(shù)為基礎(chǔ),首先分析了用戶層的具體功能,然后對用戶層的具體功能建立模塊進(jìn)行設(shè)計,接著對底層的核心問題逐個解決,最終組合完成整個系統(tǒng)的功能。在具體實現(xiàn)中應(yīng)用了面向?qū)ο蟮木幊淘瓌t和模塊化的編程思想,保證了系統(tǒng)的健壯性和擴(kuò)展性。
望遠(yuǎn)鏡巡天觀測是一個多方合作、業(yè)務(wù)分工的運行過程,參與的角色主要有:天文研究人員、天文研究人員數(shù)據(jù)處理助手、巡天觀測管理人員、巡天觀測軟件助手以及望遠(yuǎn)鏡觀測操作人員。天文研究人員根據(jù)具體的科研課題,在天文研究人員數(shù)據(jù)處理助手的協(xié)助下,選擇一批觀測目標(biāo),并向巡天觀測管理人員提交;巡天觀測管理人員為每一批觀測目標(biāo)劃分觀測時間和制定優(yōu)先策略,然后由巡天觀測軟件助手入庫;巡天觀測軟件助手根據(jù)觀測約束條件制定觀測計劃,然后遞交給觀測操作人員;觀測操作人員根據(jù)觀測計劃進(jìn)行觀測并獲得觀測數(shù)據(jù)。針對這樣一個運行環(huán)境,對系統(tǒng)的功能進(jìn)行了規(guī)劃:
(1)具備多種數(shù)據(jù)庫類型驅(qū)動支持,以及對新類型的擴(kuò)展性
(2)有效管理多個數(shù)據(jù)庫星表服務(wù),實現(xiàn)數(shù)據(jù)服務(wù)器的地址簿
(3)協(xié)作用戶建立數(shù)據(jù)庫連接,提供數(shù)據(jù)庫服務(wù)的基本信息一覽
(4)搭建SQL語句編輯的友好環(huán)境
(5)數(shù)據(jù)查詢結(jié)果顯示平臺
(6)輸出星表選擇結(jié)果到數(shù)據(jù)文件
(7)建立數(shù)據(jù)源到本地星表數(shù)據(jù)庫的數(shù)據(jù)映射關(guān)系
(8)輸出星表選擇結(jié)果到本地數(shù)據(jù)庫
用戶層模塊之間既相互獨立又存在一定的依賴性。每一個模塊有自己的核心功能,對外提供開放的接口,同時隱藏具體實現(xiàn);為了實現(xiàn)某些高級功能,部分模塊需要引用其他模塊的功能,同時確保自身不失去獨立性,保證了模塊的內(nèi)聚性。
將用戶功能進(jìn)行劃分,最終還要進(jìn)行組合。用戶層框架負(fù)責(zé)將各個具體的功能模塊組合起來,在需要的情況下調(diào)整業(yè)務(wù)邏輯關(guān)系。用戶層框架可以是圖形界面形式,也可以是文本會話形式。前者直觀形象,后者流暢便捷。
本系統(tǒng)的具體設(shè)計分兩個層次、兩條線路進(jìn)行。一個層次是用戶層,設(shè)計的線路為分析羅列具體功能、設(shè)計和實現(xiàn)子功能模塊、組合功能模塊成為整體;另一層次是關(guān)鍵問題解決,線路是發(fā)現(xiàn)問題、解決問題、發(fā)現(xiàn)問題、解決問題的這樣一個循環(huán)交替的持續(xù)過程。在前面的具體功能模塊已經(jīng)討論了第一個層次的設(shè)計,接下來將逐步對一些具體的問題進(jìn)行分析和解決。
系統(tǒng)的設(shè)計采用Java語言,一切面向?qū)ο螅趯崿F(xiàn)系統(tǒng)功能的同時,保證了可維護(hù)性和復(fù)用性。在一個軟件項目的開發(fā)周期中,項目的維護(hù)比項目的開發(fā)可能要花費更多時間和費用,因此從一開始就提高可維護(hù)性和復(fù)用性是必要的。為了保證系統(tǒng)的可維護(hù)性和復(fù)用性,設(shè)計過程堅持接口隔離原則和迪米特法則。接口隔離原則,也稱為角色劃分原則。它表示在一個系統(tǒng)中,一個接口代表一個角色。每個角色有自己的接口,避免重疊。迪米特法則(Law of Demeter,LoD),即最少知識原則(Least Knowledge Principal,LKP),表示一個對象對其他對象盡可能了解的少。模塊之間聯(lián)系越多,開發(fā)和維護(hù)的費用就越多。
JDBC是Java語言訪問數(shù)據(jù)庫的標(biāo)準(zhǔn),目前已經(jīng)發(fā)展成熟并得到了各數(shù)據(jù)庫廠商的驅(qū)動支持,例如:Oracle、MySQL、SQL Server、DB2、Sybase和informix等等。JDBC采用分層設(shè)計,上層是JDBC API,這是標(biāo)準(zhǔn)的訪問接口,下層是JDBC驅(qū)動程序API,這是由具體的數(shù)據(jù)庫生產(chǎn)廠商按照一定的標(biāo)準(zhǔn)提供的。同時,JDBC也可以通過JDBC/ODBC橋連接,訪問ODBC驅(qū)動程序,繼而訪問數(shù)據(jù)庫?;镜腏DBC數(shù)據(jù)庫訪問步驟為:
(a)獲取數(shù)據(jù)庫訪問信息:ip、端口、SID、用戶和密碼
(b)獲得連接對象Connection
(c)創(chuàng)建會話Statement
(d)執(zhí)行SQL語句得到結(jié)果集ResultSet
(e)處理結(jié)果集
(f)回收內(nèi)存資源 (包括ResultSet、Statement、Connection)
JDBC的設(shè)計貫徹了面向接口編程的思想,這是用一個程式訪問各個類型數(shù)據(jù)庫的基礎(chǔ)。對于應(yīng)用程序,JDBC都采用標(biāo)準(zhǔn)的上層API,這些都是標(biāo)準(zhǔn)的接口,而具體的設(shè)計由每個數(shù)據(jù)庫相關(guān)的驅(qū)動程序?qū)崿F(xiàn),因此對于應(yīng)用程序而言,底層實現(xiàn)的差異幾乎是不受影響的。應(yīng)用程序可以采用一致的運行方式對不同類型的數(shù)據(jù)庫進(jìn)行訪問。
基于面向?qū)ο蟮木幊趟枷?,從?shù)據(jù)庫訪問領(lǐng)域提取出數(shù)據(jù)類型這個通用語言,并構(gòu)建類,命名為DBType。它包含描述一個基于JDBC的數(shù)據(jù)庫類型的所有必要信息,包括驅(qū)動類完整類名、數(shù)據(jù)庫訪問URL、簡要描述信息。類對象分為實體類和值對象,這里為DBType增加一個標(biāo)識符字段,作為實體類設(shè)計。在這個基礎(chǔ)上實現(xiàn)資源庫,應(yīng)用了工廠模式中的多例模式,這個類命名為DBTypeData。DBTypeData的業(yè)務(wù)功能包括工廠構(gòu)造方法、資源庫的管理方法、數(shù)據(jù)持久性業(yè)務(wù)方法。數(shù)據(jù)庫類型具有持久保存的價值,需要持久性業(yè)務(wù)。按照MVC構(gòu)件規(guī)則,將數(shù)據(jù)模型與視圖控制分開設(shè)計,使得業(yè)務(wù)邏輯條理清晰。相關(guān)類圖見圖1。
圖1 數(shù)據(jù)庫類型DBType相關(guān)類類圖Fig.1 Class diagram of related classes of the DBType
由于有JDBC的良好支持,訪問不同數(shù)據(jù)庫的差異體現(xiàn)在代碼參數(shù)上,不需要代碼結(jié)構(gòu)的變動。JDBC的數(shù)據(jù)庫訪問需要給出兩個主要參數(shù):數(shù)據(jù)庫驅(qū)動類路徑和數(shù)據(jù)庫訪問URL。同時根據(jù)需要給出用戶名和密碼。程序自動判斷在給出的URL參數(shù)中是否具有用戶和密碼內(nèi)容。如果有,則在運行時用實際內(nèi)容替換;否則,使用獨立的語句說明用戶與密碼。
擴(kuò)展系統(tǒng)對一個新類型的數(shù)據(jù)庫的訪問變得非常容易。首先,獲取數(shù)據(jù)庫廠商針對這個數(shù)據(jù)庫的驅(qū)動程序;然后,根據(jù)驅(qū)動程序的說明文檔獲得驅(qū)動類路徑、訪問URL結(jié)構(gòu)等信息;將驅(qū)動程序庫文件添加到軟件程序的類路徑中;調(diào)用數(shù)據(jù)庫類型管理模塊的DBTypeDataEditor組件,添加新的數(shù)據(jù)庫類型,配置這個類型的標(biāo)識名、驅(qū)動類及訪問URL,然后保存。這樣系統(tǒng)就能識別新的數(shù)據(jù)庫類型,并采用相應(yīng)的訪問手段進(jìn)行連接。圖2是數(shù)據(jù)庫支持類型管理器界面。
為了訪問具體的數(shù)據(jù)庫,在數(shù)據(jù)庫類型類之上,建立一個數(shù)據(jù)庫服務(wù)類,命名為DBServic,用于描述一個具體數(shù)據(jù)服務(wù)的所有連接信息。以此為出發(fā)點,進(jìn)一步實現(xiàn)數(shù)據(jù)庫服務(wù)的增加、刪除、查詢以及持久性業(yè)務(wù)。相關(guān)類的關(guān)系圖見圖3。
這樣的構(gòu)造方式實際上為系統(tǒng)建立一個數(shù)據(jù)庫服務(wù)的地址簿,方便重復(fù)使用。數(shù)據(jù)庫服務(wù)類DBService為實體對象,具有一個標(biāo)識name字段,具有唯一性。數(shù)據(jù)庫服務(wù)實例對象通過type字段信息,獲得數(shù)據(jù)庫類型的實例對象,從而建立關(guān)聯(lián)性。圖4是數(shù)據(jù)庫服務(wù)管理器界面。
圖2 數(shù)據(jù)庫類型管理器Fig.2 Class Manager of the database
圖3 數(shù)據(jù)庫服務(wù)類DBService相關(guān)類圖Fig.3 Class diagram of related classes of the DBService
結(jié)構(gòu)化查詢語言SQL(Structured Query Language)是訪問數(shù)據(jù)庫的標(biāo)準(zhǔn)語言,向普通的數(shù)據(jù)用戶提供友好的語句編輯環(huán)境是必要的。由于SQL語言本身功能靈活多變,難以簡單概括,并且不同的數(shù)據(jù)庫在一些細(xì)微的特性上有不同的實現(xiàn),支持編輯的環(huán)境著重于概括最基本的業(yè)務(wù)。根據(jù)系統(tǒng)的需求,選擇提供了以下功能:
(a)顯示當(dāng)前數(shù)據(jù)庫連接中,具備訪問權(quán)限的表名、視圖的名稱、結(jié)構(gòu)信息;
(b)顯示當(dāng)前選取的若干表和視圖的屬性列的信息;
(c)自動生成基本的SQL查詢語句;
(d)保存與載入SQL語句腳本的功能。
圖5和圖6分別是SQL語句編輯界面和記錄查詢界面。
圖4 數(shù)據(jù)庫服務(wù)管理器Fig.4 Service Manager of the database
圖5 數(shù)據(jù)庫SQL語句編輯器Fig.5 SQL Query String Editor
圖6 數(shù)據(jù)集獲取與顯示界面Fig.6 Result Set Generation and Display Interface
星表數(shù)據(jù)轉(zhuǎn)移可以分3個步驟完成:從源數(shù)據(jù)庫得到結(jié)果集(ResultSet);建立源數(shù)據(jù)與目標(biāo)數(shù)據(jù)的屬性列映射關(guān)系并進(jìn)行轉(zhuǎn)換;將轉(zhuǎn)換后的記錄(Record)插入目標(biāo)數(shù)據(jù)庫。這里的目標(biāo)數(shù)據(jù)庫就是巡天戰(zhàn)略系統(tǒng)當(dāng)前的星表數(shù)據(jù)庫。為實現(xiàn)數(shù)據(jù)映射,需要一個通用接口,它描述了3層基本信息:目標(biāo)數(shù)據(jù)庫表名;目標(biāo)數(shù)據(jù)表有哪些屬性列;每一個屬性如何根據(jù)結(jié)果集取值。在描述這3層基本信息的同時,需要考慮幾個輔助特性:數(shù)據(jù)模型與視圖控制分開設(shè)計;提供結(jié)果集可選列作為參考信息;可為部分列設(shè)置常量值;可選擇自動生成ID(例如應(yīng)用于LAMOST的HTM[4]級數(shù));目標(biāo)數(shù)據(jù)表及其結(jié)構(gòu)存在一定程度上的可變性。
為實現(xiàn)這些功能和特性,建立了類DBReflection作為數(shù)據(jù)模型。DBReflection以獨立的表名描述目的數(shù)據(jù)表的類型;采用HashMap作為描述各個屬性列的轉(zhuǎn)換方式,允許在本地數(shù)據(jù)庫結(jié)構(gòu)發(fā)生變化的情況下以最低的費用實現(xiàn)升級。視圖控制類由DBReflectionEditor實現(xiàn),支持面向用戶的編輯功能。
目前,主要為系統(tǒng)實現(xiàn)了3個類型的映射:觀測目標(biāo)、天光星和流量定標(biāo)星。三者的數(shù)據(jù)結(jié)果略有不同,編輯器DBReflectionEditor在不需要進(jìn)行深層次代碼修改的情況下,能夠動態(tài)地反映DBReflection數(shù)據(jù)的變化。
通常星表數(shù)據(jù)庫的數(shù)據(jù)量都是上千萬甚至上億,在用戶選擇具體數(shù)據(jù)庫之前是不能預(yù)知的,確保程序不會因為數(shù)據(jù)量過大而導(dǎo)致內(nèi)存溢出是很重要的。Java虛擬機(jī)本身從系統(tǒng)安全考慮對溢出進(jìn)行了合理處理,但是有必要在軟件實現(xiàn)上采用合理的方式避免溢出,這是杜絕異常的根本手段。
從工作流程的角度來看,需要重點進(jìn)行內(nèi)存管理的階段有3個:查詢源數(shù)據(jù)庫獲得結(jié)果集;轉(zhuǎn)換結(jié)果集為目標(biāo)數(shù)據(jù)結(jié)構(gòu);將轉(zhuǎn)換后的結(jié)果存儲到目標(biāo)數(shù)據(jù)庫??刂泼看翁幚淼挠涗洈?shù)量是避免溢出的關(guān)鍵。具體做法有如下幾條。
(a)執(zhí)行SQL查詢時,為Statement設(shè)置FetchSize,即每次從數(shù)據(jù)庫服務(wù)器提取的記錄數(shù)量,這樣執(zhí)行查詢就能避免結(jié)果集ResultSet產(chǎn)生溢出;對一般性的查詢,可針對查詢會話Statement限制每次查詢的最大記錄數(shù),即設(shè)置MaxRow,以限制內(nèi)存使用量。
(b)從結(jié)果集映射到目標(biāo)數(shù)據(jù),建立一個數(shù)據(jù)緩存,對緩存的大小進(jìn)行限制;數(shù)據(jù)轉(zhuǎn)換結(jié)果暫存到緩存,當(dāng)緩存滿時則一次處理緩存數(shù)據(jù),然后清空緩存并繼續(xù)原來的工作。
(c)針對一些具體數(shù)據(jù)庫類型,采用特殊的手段。JDBC采用橋接設(shè)計模式,將上層用于程序員的標(biāo)準(zhǔn)API與下層由數(shù)據(jù)庫廠商實現(xiàn)的驅(qū)動分離開來,上層負(fù)責(zé)接口,下層負(fù)責(zé)實現(xiàn)。對于不同的數(shù)據(jù)庫,在實現(xiàn)上可能有些細(xì)微的差別。例如標(biāo)準(zhǔn)JDBC接口可以針對會話語句Statement,設(shè)置每次從數(shù)據(jù)庫端提取到本地內(nèi)存的記錄數(shù)量,以控制內(nèi)存空間,這個量即FetchSize;配置合理的FetchSize,即使一次搜索的記錄數(shù)量上萬,甚至上億,都能確保內(nèi)存不溢出;而MySQL數(shù)據(jù)庫由于驅(qū)動實現(xiàn)上的原因,不能自由地設(shè)置FetchSize,只能選擇一次獲得全部結(jié)果集或者一次取一條記錄。因此,使用MySQL搜索大數(shù)據(jù)量時建議采用如下語句:
(d)嚴(yán)格處理數(shù)據(jù)庫資源(Connection、Statement和ResultSet)的申請和釋放。在正常運行的情況下,程序按照一定的步驟創(chuàng)建資源、使用資源、釋放資源。在運行異常的情況下,也要主動釋放資源,作為善后工作。例如,在Try-Catch語句之后,配合Finally語句,確保資源的釋放。Java虛擬機(jī)本身提供了自動垃圾回收功能,能夠自動釋放大部分虛擬機(jī)資源,但是由于SQL驅(qū)動的情況較為特殊,而且牽連到具體實現(xiàn),有些資源需要主動釋放。
(e)使用資源共享和重復(fù)利用。例如,使用連接池技術(shù)和準(zhǔn)備好會話(PreparedStatement)。下面是一段數(shù)據(jù)庫訪問代碼示例:
為了實際測驗選星和數(shù)據(jù)錄入的功能,本文進(jìn)行了一組數(shù)據(jù)錄入測試。分別選用MySQL、SQL Server和Oracle作為源數(shù)據(jù)庫,數(shù)據(jù)記錄數(shù)目為1295 134,分別設(shè)置數(shù)據(jù)格式轉(zhuǎn)換緩存的記錄數(shù)為1、50和500,目標(biāo)星表ID分別使用直接引用和自動生成HTM級數(shù)兩種方式,比較不同情況下將數(shù)據(jù)進(jìn)行轉(zhuǎn)移花費的時間。測試在Windows XP平臺進(jìn)行,虛擬機(jī)版本為1.6,虛擬機(jī)內(nèi)存大小為默認(rèn)設(shè)置,忽略網(wǎng)絡(luò)質(zhì)量產(chǎn)生的影響。測試結(jié)果見表1。
表1 選星和星表錄入工具功能測試結(jié)果Table 1 Test results of object selection and data-entry input
根據(jù)測試的結(jié)果可知:第一,數(shù)據(jù)格式轉(zhuǎn)換緩存的大小在約50時,耗費的時間基本穩(wěn)定,而設(shè)置較小的緩存時,每次處理的數(shù)據(jù)塊較小,在發(fā)生數(shù)據(jù)異常時能避免丟失大量的正常數(shù)據(jù),所以選擇緩存為50最為合適,處理速度為20×104/min;第二,LAMOST巡天觀測將采用HTM的22級數(shù)作為星表ID,計算過程需要耗費較長的時間,處理速度為1×104/min;第三,3種不同類型的數(shù)據(jù)庫之間的傳輸測試結(jié)果區(qū)別不大??紤]到實際情況下,數(shù)據(jù)量將會更大,而且運行的網(wǎng)絡(luò)環(huán)境可能不穩(wěn)定,先進(jìn)行ID的直接引用,然后再進(jìn)行處理比較合適。
本文以JDBC技術(shù)為基礎(chǔ),設(shè)計和實現(xiàn)了一個通用數(shù)據(jù)庫訪問與星表錄入工具,能在分布式網(wǎng)絡(luò)環(huán)境中訪問各種類型的數(shù)據(jù)資源,使用結(jié)構(gòu)化查詢語言選擇數(shù)據(jù)記錄,配置數(shù)據(jù)轉(zhuǎn)換的映射關(guān)系,實現(xiàn)大數(shù)據(jù)量的星表數(shù)據(jù)轉(zhuǎn)移。研究人員可以利用此系統(tǒng),訪問已有的星表數(shù)據(jù)庫,根據(jù)要求選擇需要的星表,在配置數(shù)據(jù)轉(zhuǎn)換映射關(guān)系后,實現(xiàn)數(shù)據(jù)遷移,為巡天觀測提供觀測目標(biāo)、天光和流量定標(biāo)星。作為常規(guī)的數(shù)據(jù)庫訪問終端,本系統(tǒng)不限操作系統(tǒng)平臺,不限數(shù)據(jù)庫類型,以用戶圖形界面的形式,具備協(xié)助非專家級用戶連接數(shù)據(jù)庫、查詢數(shù)據(jù)、高級數(shù)據(jù)管理、導(dǎo)出數(shù)據(jù)和錄入數(shù)據(jù)等多種通用功能,具有較好的容錯性和大數(shù)據(jù)量處理能力。
[1]Wang Shouguan,Su Dingqiang,Chu Yaoquan,et al.Special Configuration of a very Large Schmitt Telescope for Extensive Astronomical Spectroscopic Observation [J].Applied Optics,1996,35(25):5155-5161.
[2]褚耀泉.LAMOST科學(xué)觀測計劃 [J].中國科學(xué)技術(shù)大學(xué)學(xué)報,2007,37(6):591-595.Chu Yaoquan.Scientific Projects of LAMOST [J].Journal of University of Science and Technology of China,2007,37(6):591-595.
[3]Yuan Hailong,Ren Jian,Wang Jian,et al.Design and Realization of Survey Strategy System[C]//Brissenden Roger J,Silva David R.Observatory Operations:Strategies,Processes,and Systems II.Proceedings of the SPIE,2008,7016:44.
[4]Peter Z Kunszt,Alexander S Szalay,Aniruddha R Thakar.The Hierarchical Triangular Mesh[C]//A J Banday,S Zaroubi,M Bartelmann.ESO Astrophysics Symposia.Springer-Verlag,2001:631-637.