在数据库中存储 BLOB 数据的缺点

来源:互联网 发布:淘宝怎么用手机上架 编辑:程序博客网 时间:2024/06/05 02:06

在数据库中存储 BLOB 数据的缺点

请认真考虑哪些资源存储在文件系统中可能比存储在数据库中更好。通常通过 HTTP HREF 引用的图像就是很好的例子。这是因为:

从数据库中检索图像会导致比使用文件系统更大的开销。

数据库 SAN 上的磁盘存储通常比 Web 服务器场中使用的磁盘上的存储更为昂贵。

通过精心设计元数据策略,可以消除在数据库中存储图像、电影甚至 Microsoft Office 文档之类资源的需要。元数据可以编入索引,并可以包含指向文件系统中存储的资源的指针。

将 BLOB 数据写入数据库

以下代码说明了如何使用 ADO.NET 将从文件中得到的二进制数据写入 SQL Server 中的 image 字段。

public void StorePicture( string filename ){  // Read the file into a byte array  using(FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))  {    byte[] imageData = new Byte[fs.Length];    fs.Read( imageData, 0, (int)fs.Length );  }  using( SqlConnection conn = new SqlConnection(connectionString) )  {    SqlCommand cmd = new SqlCommand("StorePicture", conn);    cmd.CommandType = CommandType.StoredProcedure;    cmd.Parameters.Add("@filename", filename );    cmd.Parameters["@filename"].Direction = ParameterDirection.Input;    cmd.Parameters.Add("@blobdata", SqlDbType.Image);    cmd.Parameters["@blobdata"].Direction = ParameterDirection.Input;    // Store the byte array within the image field    cmd.Parameters["@blobdata"].Value = imageData;    conn.Open();    cmd.ExecuteNonQuery();  }}

从数据库中读取 BLOB 数据

在通过 ExecuteReader 方法创建 SqlDataReader 对象以读取包含 BLOB 数据的行时,请使用 CommandBehavior.SequentialAccess 枚举值。如果不使用该枚举值,读取器会每次一行地将数据从服务器提取到客户端。如果行中包含 BLOB 列,可能需要占用大量内存。通过使用枚举值,可以进行更精确的控制,因为仅在 BLOB 数据被引用(例如,通过 GetBytes 方法,该方法可用于控制所读取的字节数)时才会进行提取。以下代码片段对此进行了说明。

// Assume previously established command and connection// The command SELECTs the IMAGE column from the tableconn.Open();using(SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)){  reader.Read();  // Get size of image dataa€“pass null as the byte array parameter  long bytesize = reader.GetBytes(0, 0, null, 0, 0);  // Allocate byte array to hold image data  byte[] imageData = new byte[bytesize];  long bytesread = 0;  int curpos = 0;  while (bytesread < bytesize)  {    // chunkSize is an arbitrary application defined value     bytesread += reader.GetBytes(0, curpos, imageData, curpos, chunkSize);    curpos += chunkSize;  }}// byte array 'imageData' now contains BLOB from database

使用 CommandBehavior.SequentialAccess 时,要求按照严格的顺序次序访问列数据。例如,如果 BLOB 数据位于第 3 列,并且您还需要第 1 列和第 2 列中的数据,则必须在读取第 3 列之前读取第 1 列和第 2 列。

 
原创粉丝点击