最近在做基于标签的圈人,使用了开源的Roaringbitmap。Greenplum安装完Roaringbitmap插件后,可以构建roaringbitmap,不过这些操作都是在数据库内完成。如果在程序中构建RoaringBitmap,如何将数据写入GP?
其实很简单,使用官方自己到JDBC驱动,将roaringbitmap序列化后,就可以写入了。
1.首先在gp数据库中建表
create table btable(id int,userids bytea);注意 这里是bytea 二进制类型。
2.在程序中序列化roaringbitmap,将二进制数据写入数据库
public static String url = "jdbc:pivotal:greenplum://127.0.0.1:5432;DatabaseName=gpadmin";
// 数据库用户名
public static String username = "gpadmin";
// 数据库密码
public static String password = "gpadmin";
public static Connection conn = null;
static {
try {
try {
conn = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
Class.forName("com.pivotal.jdbc.GreenplumDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
String insql = "INSERT INTO btest(id,bs) VALUES (?,?)";
PreparedStatement addstmt = conn.prepareStatement(insql);
RoaringBitmap mrb = RoaringBitmap.bitmapOf(1, 2, 3, 1000);
System.out.println("starting with bitmap " + mrb);
mrb.runOptimize(); //to improve compression
byte[] array = new byte[mrb.serializedSizeInBytes()];
try {
mrb.serialize(new java.io.DataOutputStream(new java.io.OutputStream() {
int c = 0;
@Override
public void close() {
}
@Override
public void flush() {
}
@Override
public void write(int b) {
array[c++] = (byte) b;
}
@Override
public void write(byte[] b) {
write(b, 0, b.length);
}
@Override
public void write(byte[] b, int off, int l) {
System.arraycopy(b, off, array, c, l);
c += l;
}
}));
} catch (IOException ioe) {
// should never happen because we write to a byte array
throw new RuntimeException("unexpected error while serializing to a byte array");
}
addstmt.setInt(1,1);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(array);
addstmt.setBinaryStream(2,byteArrayInputStream);
addstmt.executeUpdate();
3.将二进制数据转化成roaringbitmap,这也是最为关键的一步。
select cast( cast(userids as varchar) as roaringbitmap) from btale
至此,已经可以将roaringbitmap写入数据库。
至于,如何从数据中读取roaringbitmap,暂时还没有找到方法。