做了n多年的J2EE应用以后,如何做客户端的BI确实让我一下子摸不到门路。近期的一个客户要求我们给他做基于客户端的BI分析,客户是对外提供重要数据的单位,有很多的客户每年购买他的数据。可以说人家的数据库,每行每列都是钱。在这种情况下,他们非常害怕入侵,甚至数据都不会放在网上。之前提过很多的方案,从标准的BI平台到客户端采用Web service方式连接服务器获得数据,但是最终都因为“要让数据放在网上”而被枪毙了。
最终确定的设计是采用客户端,也就是说,将客户端的BI工具分发给客户的客户,每月再由客户通过邮件、光盘等方式将付费的数据采用加密的方式传递给数据使用单位。这些单位收到数据后,在客户端打开,客户端负责解密和展示。
BI部分我轻车熟路,由于要“分发”,所以只能选择Opne Source的,我比较看好Jasper Report,可以培训他们使用Ireport做报表,然后将做好的定义文件打包一起分发;客户端程序也不复杂,只需要修改Jasper的viewer就可以了。
除了担心Ireport太次,容易让客户使着使着抓狂(这就是后话了,实在逼得不行,只能围绕IReport再作开发了,好在都有源码)之外,近期最让我烦恼的就是如何选性数据库。要说BI平台数据库的选型,参加革命一两年的同志就可以说出一大堆各种数据库的对比,但是那些都是大型的,反而小型的这次把我难住了。
研究了一圈以后,获得提名的数据库是他们几个:
行了,言归正传,最后firebird胜出,很荣幸的成为这个项目的数据库。原因有这么几个:
最后附上embedded的连接例子吧:
long start = Calendar.getInstance().getTimeInMillis(); org.firebirdsql.pool.FBWrappingDataSource dataSource = new org.firebirdsql.pool.FBWrappingDataSource(); // 设定数据库文件 dataSource.setDatabase("TEST.FDB"); // 可以不设 dataSource.setDescription("An example database of test"); // 设定EMBEDDED就行了,说明上写着另外两种type是TYPE2和type4,干什么用的没研究,谁知道回一个阿 dataSource.setType("EMBEDDED"); try { dataSource.setLoginTimeout(10); // 这个地方是最让我痛苦的,设定了密码没用!下面会说。 java.sql.Connection c = dataSource.getConnection("user_1", ""); java.sql.Statement stmt = c.createStatement(); // 100万的大数据量 java.sql.ResultSet rs = stmt.executeQuery("SELECT count(id) FROM largedata"); if(rs.next()) { System.out.println("count: " + rs.getString(1)); } stmt.close(); c.close (); } catch (java.sql.SQLException e) { e.printStackTrace(); System.out.println("sql exception: " + e.getMessage()); } System.out.println("==>" + (Calendar.getInstance().getTimeInMillis() - start)/1000); // 在对id作了索引的情况下,你猜多久?1秒钟!同时做一个count和sum的group by,在没有索引的情况下40秒
补充一把:嵌入式数据库的让我最痛苦的是没有办法做安全设定,一位仁兄说得好:数据文件都给人家了,做什么也没用。
我觉得太有道理了,就拿Derby来说,完全没有安全性设定,谁都可以打开,FB呢,稍微好一点儿,不知道用户名就打不开(这是授权的事,说白了还是没认证),上面的例子,明明数据库的用户是user_1,密码123,但是不论你用什么密码,都能访问数据,但是如果你不知道用户名,就没戏了。
算是瘸子里拔将军吧。
后来,我还煞有介事的google了一把“firebird破解”,你猜怎么着,有高人出的高招:不知道用户名也能照样打开。怎么弄我不说了,万一让“客户的客户们”谁看到了,又要逼着换方案,这谁受得了。
不过说真的,要是谁知道embedded FB怎么保证安全,赶紧给我支两招,我都快疯了。