<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
可以在Java應用中嵌入的資料引擎看起來比較豐富,但其實並不容易選擇。Redis計算能力很差,只適合簡單查詢的場景。Spark架構複雜沉重,部署維護很是麻煩。H2HSQLDBDerby等內嵌資料庫倒是架構簡單,但計算能力又不足,連基本的視窗函數都不支援。
相比之下,SQLite在架構性和計算能力上取得了較好的平衡,是應用較廣的Java嵌入資料引擎。
SQLite架構簡單,其核心雖然是C語言開發的,但封裝得比較好,對外呈現為一個小巧的Jar包,能方便地整合在Java應用中。SQLite提供了JDBC介面,可以被Java呼叫:
Connection connection = DriverManager.getConnection("jdbc:sqlite::memory:"); Statement st = connection.createStatement(); st.execute("restore from d:/ex1"); ResultSet rs = st.executeQuery("SELECT * FROM orders");
SQLite提供了標準的SQL語法,常規的資料處理和計算都沒有問題。特別地,SQLite已經能支援視窗函數,可以方便地實現很多組內運算,計算能力比其他內嵌資料庫更強。
SELECT x, y, row_number() OVER (ORDER BY y) AS row_number FROM t0 ORDER BY x; SELECT a, b, group_concat(b, '.') OVER ( ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS group_concat FROM t1;
SQLite的優點亮眼,但對於複雜應用場景時還是有些缺點。
Java應用可能處理的資料來源多種多樣,比如csv檔案、RDB、Excel、Restful,但SQLite只處理了簡單情況,即對csv等文字檔案提供了直接可用的命令列載入程式:
.import --csv --skip 1 --schema temp /Users/scudata/somedata.csv tab1
對於其他大部分資料來源,SQLite都沒有提供方便的介面,只能硬寫程式碼載入資料,需要多次呼叫命令列,整個過程很繁瑣,時效性也差。
以載入RDB資料來源為例,一般的做法是先用Java執行命令列,把RDB庫錶轉為csv;再用JDBC存取SQLite,建立表結構;之後用Java執行命令列,將csv檔案匯入SQLite;最後為新表建索引,以提高效能。這個方法比較死板,如果想靈活定義表結構和表名,或通過計算確定載入的資料,程式碼就更難寫了。
類似地,對於其他資料來源,SQLite也不能直接載入,同樣要通過繁瑣地轉換過程才可以。
SQL接近自然語言,學習門檻低,容易實現簡單的計算,但不擅長複雜的計算,比如複雜的集合計算、有序計算、關聯計算、多步驟計算。SQLite採用SQL語句做計算,SQL優點和缺點都會繼承下來,勉強實現這些複雜計算的話,程式碼會顯得繁瑣難懂。
比如,某隻股票最長的上漲天數,SQL要這樣寫:
select max(continuousDays)-1 from (select count(*) continuousDays from (select sum(changeSign) over(order by tradeDate) unRiseDays from (select tradeDate, case when price>lag(price) over(order by tradeDate) then 0 else 1 end changeSign from AAPL) ) group by unRiseDays)
這也不單是SQLite的難題,事實上,由於集合化不徹底、缺乏序號、缺乏物件參照等原因,其他SQL資料庫也不擅長這些運算。
業務邏輯由結構化資料計算和流程控制組成,SQLite支援SQL,具有結構化資料計算能力,但SQLite沒有提供儲存過程,不具備獨立的流程控制能力,也就不能實現一般的業務邏輯,通常要利用Java主程式的判斷和迴圈語句。由於Java沒有專業的結構化資料物件來承載SQLite資料表和記錄,轉換過程麻煩,處理過程不暢,開發效率不高。
前面提過,SQLite核心是C程式,雖然可以被整合到Java應用中,但並不能和Java無縫整合,和Java主程式交換資料時要經過耗時的轉換才能完成,在涉及資料量較大或互動頻繁時效能就會明顯不足。同樣因為核心是C程式,SQLite會在一定程度上破壞Java架構的一致性和健壯性。
對於Java應用來講,原生在JVM上的esProc SPL是更好的選擇。
esProc SPL是JVM下開源的嵌入資料引擎,架構簡單,可直接載入資料來源,可以通過JDBC介面被Java整合呼叫,並方便地進行後續計算。
SPL架構簡單,無須獨立服務,只要引入SPL的Jar包,就可以部署在Java環境中。
直接載入資料來源,程式碼簡短,過程簡單,時效性強。比如載入Oracle:
A | |
1 | =connect("orcl") |
2 | =A1.query@x("select OrderID,Client,SellerID,OrderDate,Amount from orders order by OrderID") |
3 | >env(orders,A2) |
對於SQLite擅長載入的csv檔案,SPL也可以直接載入,使用內建函數而不是外部命令列,穩定且效率高,程式碼更簡短:
=T("/Users/scudata/somedata.csv")
多種外部資料來源。除了RDB和csv,SPL還直接支援txtxls等檔案,MongoDB、Hadoop、redis、ElasticSearch、Kafka、Cassandra等NoSQL,以及WebService XML、Restful Json等多層資料。比如,將HDSF裡的檔案載入到記憶體:
A | |
1 | =hdfs_open(;"hdfs://192.168.0.8:9000") |
2 | =hdfs_file(A1,"/user/Orders.csv":"GBK") |
3 | =A2.cursor@t() |
4 | =hdfs_close(A1) |
5 | >env(orders,A4) |
JDBC介面可以方便地整合。載入的資料量一般比較大,通常在應用的初始階段執行一次,只須將上面的載入過程存為SPL指令碼檔案,在Java中以儲存過程的形式參照指令碼檔名:
Class.forName("com.esproc.jdbc.InternalDriver"); Connection conn =DriverManager.getConnection("jdbc:esproc:local://"); CallableStatement statement = conn.prepareCall("{call init()}"); statement.execute();
SPL的計算能力更強大
SPL提供了豐富的計算函數,可以輕鬆實現日常計算。SPL支援多種高階語法,大量的日期函數和字串函數,很多用SQL難以表達的計算,用SPL都可以輕鬆實現,包括複雜的有序計算、集合計算、分步計算、關聯計算,以及帶流程控制的業務邏輯。
豐富的計算函數。SPL可以輕鬆實現各類日常計算:
A | B | |
1 | =Orders.find(arg_OrderIDList) | //多鍵值查詢 |
2 | =Orders.select(Amount>1000 && like(Client,"*S*")) | //模糊查詢 |
3 | = Orders.sort(Client,-Amount) | //排序 |
4 | = Orders.id(Client) | //去重 |
5 | =join(Orders:O,SellerId; Employees:E,EId).new(O.OrderID, O.Client,O.Amount,E.Name,E.Gender,E.Dept) | //關聯 |
標準SQL語法。SPL也提供了SQL-92標準的語法,比如分組彙總:
$select year(OrderDate) y,month(OrderDate) m, sum(Amount) s,count(1) c from {Orders} Where Amount>=? and Amount<? ;arg1,arg2
函數選項、層次引數等方便的語法。功能相似的函數可以共用一個函數名,只用函數選項區分差別,比SQL更加靈活方便。比如select函數的基本功能是過濾,如果只過濾出符合條件的第1條記錄,可使用選項@1:
T.select@1(Amount>1000)
二分法排序,即對有序資料用二分法進行快速過濾,使用@b:
T.select@b(Amount>1000)
有序分組,即對分組欄位有序的資料,將相鄰且欄位值相同的記錄分為一組,使用@b:
T.groups@b(Client;sum(Amount))
函數選項還可以組合搭配,比如:
Orders.select@1b(Amount>1000)
結構化運算函數的引數有些很複雜,比如SQL就需要用各種關鍵字把一條語句的引數分隔成多個組,但這會動用很多關鍵字,也使語句結構不統一。SPL使用層次引數簡化了複雜引數的表達,即通過分號、逗號、冒號自高而低將引數分為三層:
join(Orders:o,SellerId ; Employees:e,EId)
更豐富的日期和字串函數。除了常見函數,比如日期增減、擷取字串,SPL還提供了更豐富的日期和字串函數,在數量和功能上遠遠超過了SQL,同樣運算時程式碼更短。比如:
季度增減:elapse@q(“2020-02-27”,-3) //返回2019-05-27
N個工作日之後的日期:workday(date(“2022-01-01”),25) //返回2022-02-04
字串類函數,判斷是否全為數位:isdigit(“12345”) //返回true
取子串前面的字串:substr@l(“abCDcdef”,“cd”) //返回abCD
按豎線拆成字串陣列:“aa|bb|cc”.split(“|”) //返回[“aa”,“bb”,“cc”]
SPL還支援年份增減、求季度、按正規表示式拆分字串、拆出SQL的where或select部分、拆出單詞、按標記拆HTML等大量函數。
簡化有序運算。涉及跨行的有序運算,通常都有一定的難度,比如比上期和同期比。SPL使用"欄位[相對位置]"參照跨行的資料,可顯著簡化程式碼,還可以自動處理陣列越界等特殊情況,比SQL視窗函數更加方便。比如,追加一個計算列rate,計算每條訂單的金額增長率:
=T.derive(AMOUNT/AMOUNT[-1]-1: rate)
綜合運用位置表示式和有序函數,很多SQL難以實現的有序運算,都可以用SPL輕鬆解決。比如,根據考勤表,找出連續 4 周每天均出勤達 7 小時的學生:
A | |
1 | =Student.select(DURATION>=7).derive(pdate@w(ATTDATE):w) |
2 | =A1.group@o(SID;~.groups@o(W;count(~):CNT).select(CNT==7).group@i(W-W[-1]!=7).max(~.len()):weeks) |
3 | =A2.select(weeks>=4).(SID) |
簡化集合運算,SPL的集合化更加徹底,配合靈活的語法和強大的集合函數,可大幅簡化複雜的集合計算。比如,在各部門找出比本部門平均年齡小的員工:
A | |
1 | =Employees.group(DEPT; (a=~.avg(age(BIRTHDAY)),~.select(age(BIRTHDAY)<a)):YOUNG) |
2 | =A1.conj(YOUNG) |
計算某支股票最長的連續上漲天數:
A | |
1 | =a=0,AAPL.max(a=if(price>price[-1],a+1,0)) |
簡化關聯計算。SPL支援物件參照的形式表達關聯,可以通過點號直觀地存取關聯表,避免使用JOIN導致的混亂繁瑣,尤其適合複雜的多層關聯和自關聯。比如,根據員工表計算女經理的男員工:
=employees.select(gender:"male",dept.manager.gender:"female")
方便的分步計算,SPL集合化更加徹底,可以用變數方便地表達集合,適合多步驟計算,SQL要用巢狀表達的運算,用SPL可以更輕鬆實現。比如,找出銷售額累計佔到一半的前n個大客戶,並按銷售額從大到小排序:
A | B | |
2 | =sales.sort(amount:-1) | /銷售額逆序排序,可在SQL中完成 |
3 | =A2.cumulate(amount) | /計算累計序列 |
4 | =A3.m(-1)/2 | /最後的累計即總額 |
5 | =A3.pselect(~>=A4) | /超過一半的位置 |
6 | =A2(to(A5)) | /按位元置取值 |
流程控制語法。SPL提供了流程控制語句,配合內建的結構化資料物件,可以方便地實現各類業務邏輯。
分支判斷語句:
A | B | |
2 | … | |
3 | if T.AMOUNT>10000 | =T.BONUS=T.AMOUNT*0.05 |
4 | else if T.AMOUNT>=5000 && T.AMOUNT<10000 | =T.BONUS=T.AMOUNT*0.03 |
5 | else if T.AMOUNT>=2000 && T.AMOUNT<5000 | =T.BONUS=T.AMOUNT*0.02 |
迴圈語句:
A | B | |
1 | =db=connect("db") | |
2 | =T=db.query@x("select * from sales where SellerID=? order by OrderDate",9) | |
3 | for T | =A3.BONUS=A3.BONUS+A3.AMOUNT*0.01 |
4 | =A3.CLIENT=CONCAT(LEFT(A3.CLIENT,4), " co.,ltd.") | |
5 | … |
與Java的迴圈類似,SPL還可用break關鍵字跳出(中斷)當前迴圈體,或用next關鍵字跳過(忽略)本輪迴圈,不展開說了。
計算效能更好。在記憶體計算方面,除了常規的主鍵和索引外,SPL還提供了很多高效能的資料結構和演演算法支援,比大多數使用SQL的記憶體資料庫效能好得多,且佔用記憶體更少,比如預關聯技術、平行計算、指標式複用。
SPL支援JDBC介面,程式碼可外接於Java,耦合性更低,也可內建於Java,呼叫更簡單。SPL支援解釋執行和熱切換,程式碼方便移植和管理運營,支援內外存混合計算。
外接程式碼耦合性低。SPL程式碼可外接於Java,通過檔名被呼叫,既不依賴資料庫,也不依賴Java,業務邏輯和前端程式碼天然解耦。
對於較短的計算,也可以像SQLite那樣合併成一句,寫在Java程式碼中:
Class.forName("com.esproc.jdbc.InternalDriver"); Connection conn =DriverManager.getConnection("jdbc:esproc:local://"); Statement statement = conn.createStatement(); String arg1="1000"; String arg2="2000" ResultSet result = statement.executeQuery(=Orders.select(Amount>="+arg1+" && Amount<"+arg2+"). groups(year(OrderDate):y,month(OrderDate):m; sum(Amount):s,count(1):c)");
解釋執行和熱切換。業務邏輯數量多,複雜度高,變化是常態。良好的系統構架,應該有能力應對變化的業務邏輯。SPL是基於Java的直譯語言,無須編譯就能執行,指令碼修改後立即生效,支援不停機的熱切換,適合應對變化的業務邏輯。
方便程式碼移植。SPL通過資料來源名從資料庫取數,如果需要移植,只要改動組態檔中的資料來源設定資訊,而不必修改SPL程式碼。SPL支援動態資料來源,可通過引數或宏切換不同的資料庫,從而進行更方便的移植。為了進一步增強可移植性,SPL還提供了與具體資料庫無關的標準SQL語法,使用sqltranslate函數可將標準SQL轉為主流方言SQL,仍然通過query函數執行。
方便管理運營。由於支援庫外計算,程式碼可被第三方工具管理,方便團隊共同作業;SPL指令碼可以按檔案目錄進行存放,方便靈活,管理成本低;SPL對資料庫的許可權要求類似Java,不影響資料安全。
內外存混合計算。有些資料太大,無法放入記憶體,但又要與記憶體表共同計算,這種情況可利用SPL實現內外存混合計算。比如,主表orders已載入到記憶體,大明細表orderdetail是文字檔案,下面進行主表和明細表的關聯計算:
A | |
1 | =file("orderdetail.txt").cursor@t() |
2 | =orders.cursor() |
3 | =join(A1:detail,orderid ; A2:main,orderid) |
4 | =A3.groups(year(main.orderdate):y; sum(detail.amount):s) |
SQLite使用簡單方便,但資料來源載入繁瑣,計算能力不足。SPL架構也非常簡單,並直接支援更多資料來源。SPL計算能力強大,提供了豐富的計算函數,可以輕鬆實現SQL不擅長的複雜計算。SPL還提供多種優化體系結構的手段,程式碼既可外接也可內建於Java,支援解釋執行和熱切換,方便移植和管理運營,並支援內外存混合計算。
到此這篇關於Java 嵌入資料引擎從 SQLite 到 SPL的文章就介紹到這了,更多相關Java 嵌入資料引擎內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45