VastbaseE100

基于开源技术的HTAP数据库管理系统。性能优异,稳定可靠,提供诸多专属领域特性。

Menu

处理大数据类型

二进制类型

Vastbase E100提供两种不同的方法存储二进制数据。二进制数据可以使用二进制数据类型BYTEA存储在表中,或者使用大对象特性以一种特殊的格式将二进制数据存储在一个独立的表中,然后通过在表中保存一个类型为 OID 的值来引用该表。

为了判断哪种方法比较合适,必须理解每种方法的局限。 BYTEA数据类型并不适合存储非常大数量的二进制数据。虽然类型为BYTEA的字段可以存储最多 1G 字节的二进制数据,但是这样它会要求巨大的内存(RAM)来处理这样巨大的数据。用于存储二进制数据的大对象方法更适合存储非常大的数据,但也有自己的局限,具体来说,删除一个引用大数据的行时并不会删除大对象,删除大对象需要单独操作。大对象还有一些安全性的问题,因为连接到数据库的任何用户都可以查看或修改任何大对象,即使他们没有权限查看或修改包含大对象引用的行。

BYTEA

使用BYTEA类型存储二进制数据,可以用.NET自身提供的byte[]类型的操作方式进行读写。

例如:

CREATE TABLE images (imgname text, img bytea);

插入记录

可以通过直接将参数赋值,直接将数据传入Vastbase E100。

FileStream fs = new FileStream(fileUrl, FileMode.Open, FileAccess.Read);
  try
  {
    byte[] buffur = new byte[fs.Length];
    fs.Read(buffur, 0, (int)fs.Length);   //读取二进制文件
                Int Len = (int)fs.Length;
               //关闭资源 
       fs.Close();

               .......  //建立连接
             
     NpgsqlCommand cmd = new NpgsqlCommand();  
               cmd.CommandType = CommandType.Text;    //指明为文本
              cmd.CommandText = "insert into image values (‘I1’, @content)";   //SQL语句
 
              NpgsqlParameter p = new NpgsqlParameter("@content", DbType.Image, Len); 
               p.Value = buffur ; 
              cmd.Parameters.Add(p);   //给cmd添加参数

              cmd.ExecuteNonQuery();     //执行
              ......
  }

还有一种方式,就是上述提到的通过DataSet与数据库连接的方式,通过DataSet,可以直接将数据传入数据库:

DataSet tempDataSet=new DataSet();
string sql = "SELECT * FROM images  WHERE 1=0";   //不会有内容,只有表头
NpgsqlDataAdapter objAdapter = new NpgsqlDataAdapter(sql, conn);
objAdapter .Fill(tempDataSet,”temp”);  //与数据库建立了连接,并在tempDataSet创建一个空表

//'在DataSet的表中插入一条记录 
DataRow tempDataRow = tempDataSet.Tables[“temp”].NewRow(); //创建表的新行
tempDataRow["imgname "] =”Image1”;  //给新行的imgname 赋值
tempDataRow["img "] =buffur ;   //给新行的img 赋值,为二进制数据

//更新至数据库
tempDataSet.Tables[“temp”].Rows.Add(tempDataRow);
tempAdapter.Update(tempDataSet);

读取记录

using(NpgsqlCommand cmd = new NpgsqlCommand("select * from images '", conn));
using(NpgsqlDataReader dr = cmd.ExecuteReader();{

         While(dr.Read()){
               byte[] imageData = (byte[])dr[“img ”];
               ......               //其它处理
}
}

在这里,二进制数据被读取为byte[]。

大对象功能

使用大对象功能存储二进制数据,需要开启事务来进行读写,使用到LargeObjectManager 类对象与LargeObject类对象 。

例如:

CREATE TABLE imageslo (imgname text, imgoid oid);

插入记录

......    //建立conn连接
int noid;
using (NpgsqlTransaction trans = conn.BeginTransaction()){    //开启事务
try{
LargeObjectManager lom = new LargeObjectManager(conn);   //创建大对象管理器
byte[] buf = new byte[8192];
int readIn = 0;
int noid = lom.Create(LargeObjectManager.WRITE);   //创建大对象oid
LargeObject lo = lom.Open(noid, LargeObjectManager.WRITE);  //创建大对象
using (FileStream fs = File.OpenRead(fileName)){   //读取文件二进制流
while ((readIn = fs.Read(buf, 0, buf.Length)) > 0){   //写入大对象
lo.Write(buf, 0, readIn);
}
}
Lo.Close();   //写完大对象,关闭

string sql = string.Format( "insert into test values ({0},{1})", “Image1”,noid);  //格式化字符串构建语句
NpgsqlCommand cmd = new NpgsqlCommand(sql, conn);   
cmd .ExecuteNonQuery();    //执行插入记录

trans.Commit();   //事务提交
}

读取记录

......    //建立conn连接

using (NpgsqlTransaction trans = conn.BeginTransaction()){   //开启事务
/*获取大对象oid*/
int  loOid = 0;
    string sql = "select  imgoid from imageslo where ......";   
     using (var cmd = new NpgsqlCommand(sql,conn))    {
       loOid  = Convert.ToInt32(objCommand.ExecuteScalar());    //将结果转换成整数
}

LargeObjectManager lom = new LargeObjectManager(conn);     //创建大对象管理器
LargeObject lo = lom.Open(loOid , LargeObjectManager.READ);   //打开大对象文件
using (FileStream fs = File.OpenWrite(@"MyFile")){   //创建目的文件,将数据写入
int tempmax = lo.Size();
int tempread = 0;
int temppos = 0;

do{
byte[] buf = lo.Read(8192);    //一次性从大对象读取8192个字节
tempread = buf.Length;
if (tempread > 0){
fs.Write(buf, 0, tempread);
temppos += tempread;
lo.Seek(temppos);    //当前读取位置更新
}
} while (tempread > 0);
fs.Flush();
}

lo.Close(); //读取完毕,关闭大对象
trans.Commit();  //提交事务
}

字符串类型

Vastbase E100中TEXT类型与VARCHAR类型都是可变长的字符串类型,区别在于VARCHAR类型通过VARCHAR(n)中的n来限制最大长度,而TEXT类型没有。TEXT类型与VARCHAR类型几乎没有性能差别,TEXT类型最多可存储1G数据。

使用TEXT类型存储数据时,可用.NET中的Convert功能将二进制数据与文本数据之间来进行转换。例如:

CREATE TABLE images (id int, msg text);

插入记录

Stream s = File.Open(MapPath("MyImage.jpg"), FileMode.Open);
 int leng = (int)s.Length;
 byte[] by = new byte[leng];
  s.Read(by, 0, leng);//把图片读到字节数组中
  s.Close();
 string str = Convert.ToBase64String(by);//把字节数组转换成字符串

string sql = string.Format( "insert into test values ({0},{1})", “Image1”,noid);  //格式化字符串构建语句
NpgsqlCommand cmd = new NpgsqlCommand(sql, conn);   
cmd .ExecuteNonQuery();    //执行插入记录

读取记录

在读取记录时,按照获取字符串的方式,就可以获取到在数据库中的TEXT数据。

using (var cmd = new NpgsqlCommand("SELECT  * FROM  images  WHERE id = 1;",conn))   
using (NpgsqlDataReader reader = cmd.ExecuteReader()){
while (reader.Read()) {
// Read 
         string  fieldValue = reader["msg "]; // 获得指定字段的值
         ......  //后期处理
}
    }
reader.Close();
}

在这里,TEXT数据被读取为string。