星期三, 9月 16, 2009

記憶體資料庫訪問

前幾天收到iThome編輯的電郵,他們最近正在研究in memory DB, 已採訪IBM SolidDBOracle TimesTen,問能否安排採訪MemDB


因為iThome是台灣雜誌,所以我請了合作開發連鎖零售系統流水碼版的台灣伙伴李生去接受採訪,不過對MemDB的技術,始終都是由我來解說好了.

看了之前iThome對IBM SolidDB和 Oracle TimesTen的訪問,對in Memory DB技術其實沒有解說.一般人以為只要把所有資料放在memory就是memory db.其實當中有很多技術的分別.

舉一個簡單的例子,因為傳統的資料庫所有資料都放在disk,要做indexing尋找,最花時間是disk access和locking,所以減少以上次數是當時要研究和使用的技術,才使用B-Tree.但對memory db,以上的假設已不存在,很多不同的技術研究也做了,改為用T-tree.這是當時我讀碩士所做的研究,按此可看論文.

要介紹MemDB的技術和其他資料庫的不同,最好是利用為台灣度身開發的連鎖零售系統流水碼版作一個例子.

MemDB是一個Embeded DB,和應用系統結合,所以整個系統只有一個EXE檔案.不用安裝任何系統,直接執行EXE就可以 (Green Software).執行後會產生一個MEM資料庫檔,系統會把所有資料Load上Memory,所以所有query都能在memory執行,不需要任何disk access,當然所有update都要改memory和disk.

介紹一下流水碼系統的設計和應用.流水碼系統替每件貨品設立一個流水碼,例如10件相同的CPU,入貨時會給每個CPU一個流水碼,1,2,3,..,10.好處是你可以隨時查詢CPU水碼2是何時入貨,銷售,調貨,維修,供應商回佣等等,能加強零售電腦硬件店的管理.

傳統的Relational DB,需要以下Product和Product_Serial兩個Table:

Product:  product_id, barcode, name ...
data.        11001,  110010010, CPU...

Product_Serial: product_id, serial, status .....
data:                   11001       , 1, 0,...
                            11001       , 2,1, ...
                             ..... .................
                            11001       , 10, 0,...

流水碼系統經常要尋找流水碼,例如要找CPU水碼2的status,就要在db做

select status from Product_Serial where product_id=11001 and serial=2

要在Product_Serial做一個query,假設十萬個流水碼,做一個lsearch要花相同多的時間,當中涉及很多程序,如disk access,disk locking,load上memory,release memory等等.

但在MemDB,因為它是Object-oriented DB,而且所有資料都存放在memory (所有object都有pointer指著),所以可以直接用pointer取到CPU水碼2的memory address.以下是Product class的設計:

class Product
{
     ...
     int product_id;
     char* barcode
     Array<ProductStatus> productSerials;
     ...
};

假設已取到CPU product的pointer資料,要找流水碼2,只要用array就能取回:

ProductSerial *serial;
serial=product->productSerials[2];
if(serial->status==IS_SOLD)
...
注意,以上是在應用系統直接取到serial的pointer,不像傳統的資料庫,要應用系統用SQL Statement call資料庫系統,如果要查看serial的status,要把整個結果由資料庫系統傳回到應用系統.

在流水碼應用系統,有很多功能和報表,都要經常找個別流水碼,以上一個例子,可看出流水碼系統配合MemDB的優勢,也解釋了MemDB和傳統資料庫的分別.