標籤:程式設計語言 資料類型 集算器
程式語言根據其設計目的不同,其側重的基礎資料型別 (Elementary Data Type)也不同。JAVA、C#等語言被設計用來進行通用的應用程式開發,其基礎資料型別 (Elementary Data Type)是字串、數字、布爾等原子資料類型,以及數組和通用對象。而SQL、PowerBuilder、R、集算器esProc等語言被設計用來進行資料處理,其基礎資料型別 (Elementary Data Type)是有結構的二維資料表對象。比如這句SQL:SELECT T1.id,T1.name,T1.value FROM T1 LEFT JOIN T2 ON T1.id=T2.id,這裡的T1,T2以及計算結果就是這種資料類型。用多個欄位組成一條記錄,由多條結構相同的記錄組成二維資料,這樣的資料及其欄位名的組合就是有結構的二維資料表對象。
資料處理處理語言為什麼不用原子類型和通用對象作為基本類型?嘗試把上面那句SQL裡的T1,T2用JAVA中的數組或者ArrayList對象來表示,你會發現:複雜度立刻增加數倍,代碼的長度更會陡增幾十倍!
資料處理語言中的基礎資料型別 (Elementary Data Type)都是有結構的二維資料表對象,這並非巧合,而是有著深刻的原因。
對應真實業務。現實世界中的業務資料大都是結構化資料,比如工資表,有員工編號、員工姓名、部門、日期、稅前工資、稅後工資等等;比如零售記錄,有訂單時間、門店編號、收銀台編號、收銀員編號、商品名稱、單價等等;再比如網站日誌,有瀏覽時間、URL、訪問者IP、瀏覽器版本等屬性。這些屬性相當於欄位,每條資料結構都一樣,雖然其儲存方式經常是文本而非資料庫,但實質上仍然是結構化資料,用有結構的二維資料表對象來表示是再自然不過的事情了。有結構的二維資料表對象可以最直觀地呈現業務資料,最真實的表達實際業務,不論是儲存、計算、交換還是分享,這種形式的資料都是最方便最容易理解的。
易於實現批量處理。業務資料通常是結構相同的資料,比如之前提過的工資表、零售記錄、網站日誌。處理這類資料時,個別情況下會針對某條記錄的某個欄位,但絕大多數情況下都是以記錄為單位對所有資料進行處理的,比如:根據稅前工資計算出稅後工資;根據單價和商品數量計算出金額;統計出每天每個IP的線上時間長度。上述處理方式就是批量處理。實現批處理,可以像JAVA那樣按行號列號迴圈遍曆數組的每個成員,也可以像SQL、集算器esProc那樣直接按業務欄位名操作資料,後者簡單易用無需迴圈語句,更利於程式員從業務角度直觀方便地操作資料,相應的代碼也更加簡短易讀。
符合關係代數。關係代數是E.F. Codd專門為資料處理和資料查詢而設計的底層理論,它用基本運算、串連運算、彙總運算、除法運算詳盡地描述了業務資料之間的關聯關係和運算規律,理論上可以完成資料處理和資料查詢中任意難度的計算問題。由於關係代數簡潔而完備,資料庫因而大都是按照這一理論來設計的,E.F. Codd更被稱為關係型資料庫之父。有結構的二維資料表對象正是E.F. Codd推薦的資料類型,它可以比較完美地表達關係代數中的各類運算,從而輕鬆實現資料處理中的計算問題。事實上,資料庫結果集就是最早的有結構的二維資料表對象。
可以看到,由於可以對應真實的業務資料,易於實現批處理計算,符合關係代數理論,因此各類資料處理程式語言不約而同地使用有結構的二維資料表對象作為基礎資料型別 (Elementary Data Type)。使用二維資料表對象,代碼簡潔易懂,開發效率更高,下面再舉幾個例子說明這一點:
SQL的結果集(resultSet):按圖書類型分組,求平均價格大於15元的圖書,它們的均價是多少?
select avg(price),type frombooks group by type having avg(price)>15
集算器esProc的序表(TSeq):按部門分組,求各部門銷量前10的產品。
products.group(department).(~.top(quantity;10)
PowerBuilder的資料視窗(datawindow):將訂單按照價格排序
Order.SetSort(‘value d‘)
Order.Sort()
R語言的資料框(data.frame):將orders表和customer表按照customerID進行左關聯。
merge(A1,B1,by.x="CustomerID",by.y="CustomerID",all.x=TRUE)
SQL、集算器esProc、R的代碼對比:將訂單資料按照部門分組,匯總各部門的訂單數量和銷售額。
SQL:
Selectcount(*),sum(sales) from orders group by Dept
集算器esProc:
orders.groups(Dept; count(~),sum(sales))
R語言:
result<-aggregate(orders$sales,list(orders $ Dept),sum)
result$count<-tapply(orders$ sales, orders $ Dept,length)
結果集、序表、資料視窗、資料框,它們雖然都是有結構的二維資料表對象,功能也基本相同,但它們之間還是有著細微的差別的。
SQL結果集資料豐富,使用範圍廣泛,通用性較好,簡單易用,是資料處理語言中最主流的資料類型。但SQL沒有完全實現關係代數,導致有些運算不夠方便,比如集合除法。
資料視窗一般會從SQL取數,最終結果也會返回資料庫,它的主要功能是打通了資料和UI控制項之間的隔閡,讓程式員可以快速設計出互動性優異的資料庫應用程式。DataWindow的主要功能是資料呈現和編輯,只有針對單表的計算,資料處理能力比較弱。
資料框具有一定的結構化計算能力,但從上面的例子可以看出,它的文法較難理解,實現同樣的功能相對複雜。這是因為R主要的功能是科學統計計算,重點的資料類型是數列和矩陣,資料框是後來為了實現結構化資料計算才新增的資料類型。從這一點來看,資料框的專業性不如其他三種。
序表在資料處理方面比較專業,它具有SQL結果集的一般優點,對關係代數實現得也比較徹底。序表還具有有序的特點,適合解決資料處理中和順序有關的難題,比如:比上期、同期比,排名、相對區間計算等。序表還具有泛型的特點,建立資料之間的關聯關係更加容易,可以用對象的形式來輕鬆訪問多級關聯的資料。與SQL相比,序表的缺點在於它是純記憶體對象,無法直接處理大資料。
可以看到,有結構的二維資料表對象和資料處理程式語言的專業程度直接相關,前者的功能越強,後者的專業程度也越高。反之也一樣,如果一門語言缺乏有結構的二維資料表對象,那這門語言的在資料處理方面就很難稱得上專業。考察一門程式設計語言是否能夠高效開發資料分析處理的程式,關鍵就是看其有沒有專業的二維資料表對象以及相應的類庫。
Perl常被用於字串檢索,具有一定的資料處理能力,但其代碼冗長複雜,算不上是專業的資料處理語言。比如進行最簡單的分組匯總時,Perl的代碼如下:
%groups=();
foreach(@carts){
$name = $_->[1];
if($groups{$name} == null){
$groups{$name}=[$_];
}
else{
push($groups{$name},$_);
}
}
my @result=();
foreach(keys(%groups)){
$value=0;
while($row=pop $groups{$_}){
$value+= $row->[2];
}
push @result,[$_,$value];
}
Python的寫法稍簡單些,但和SQL、集算器esProc、R來比,開發效率上仍有量級的差異。範例程式碼如下:
result=[]
for key, items ingroupby(data, itemgetter(0)):
value1=0
value2=0
for subitem in items:
value1+=subitem[1]
value2+=subitem[2]
result.append([key,value1,value2])
print(result)
Perl和Python在資料處理方面不夠專業,最重要的原因就是缺乏有結構的二維表資料對象。
集算器esProc序表不僅是有結構的二維表資料對象,而且還具備有序、泛型、分步計算等特性,比同類語言的專業性更強。比如實現一個較複雜的計算目標:找出連續上漲超過5天的股票。集算器esProc的代碼如下:
650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/49/9B/wKioL1QWgUqRP7llAAFP2LAgJy0623.jpg" title="2014-09-15_140326.jpg" alt="wKioL1QWgUqRP7llAAFP2LAgJy0623.jpg" />
資料處理程式語言中的基礎資料型別 (Elementary Data Type)