BLOB文件(二进制大对象)是二进制数据,换而言之,就是非文本数据。像MP3、可执行文件、图片等都是BLOB文件。这些类型的文件通常是大型数据库项目的一个组成部分。问题也就随之而来了:要怎样存储这些文件呢?而将它们存到哪里呢?存在文件系统里还是放到SQL Server数据库内部呢?无论采用哪种存储方法,都有其各自的道理。笼统一点说来,如果文件比较小,就将它们存放在SQL Server数据库内部。而且,支持将二进制数据存储在SQL Server内部的另一个原因是有利于事务控制。例如,如果你在进行下一个处理步骤之前需要确认已经更新或删除了某张图片,那可以通过SQL Server内部控制这些过程。而另一方面,如果二进制文件很大,或者是视频流文件,那存储在Windows的文件系统中比存储在SQL Server内部对数据库的性能更有利。再者,文件系统对碎片的处理要优于SQL Server。
在本系列的前三篇文章中,主要为大家介绍了如何将BLOB文件存储在SQL Server内部。第一篇文章SQL Server:存储图像和BLOB文件(一)简单介绍了BLOB的定义和VARCHAR的数据类型家族,并讨论了将BLOB插入到SQL Server的一些简单方法。第二篇文章SQL Server:存储图像和BLOB文件(二)介绍了如何利用Response.BinaryWrite将从数据库读出的图片显示到浏览器网页上。在第三篇文章SQL Server:存储图像和BLOB文件(三)中,通过创建ASPX页面来接受来自网页的图片并直接将其存储到SQL Server当中。本文将为大家介绍第二种存储BLOB文件的方法,也就是把BLOB文件存储到Windows文件系统当中,并利用SQL Server从一个网页对这些文件进行管理。
文件系统实例
首先,我们要构建一个可以用在前面的文章中所举例子的控件——文件上传(File Upload)控件。该控件可以嵌入到网页当中,并搜集文件信息,例如某测试图片的文件名、目录路径,最终将这些信息传递给SQL Server。具体操作就是,创建一个名为FileSystemIn.aspx的代码分离新页面,将四个控件拖拽到该页面上,包括一个文件上传控件、一个按钮控件(button)和两个标签(label),如下图所示:
为了便于解释,在例图上使用的是默认控件名,实际应用中可自行更改。
在代码分离页面上,我们将搜集文件名和目录路径,并将它们分别显示到两个标签上。创建点击事件,并插入如下代码:
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName.ToString()
);
Label2.Text = ystem.IO.Path.GetDirectoryName(FileUpload1.PostedFile.FileName.ToString());
}
当点击button按钮,就会显示通过文件上传控件浏览上传的文件,如下图所示:
我们还可以通过一个存储过程将该数据传递给SQL Server,这样数据库就可以成为我们的图片管理器了。首先,传见一个文本数据库来保存上述文件信息,T-SQL脚本如下:
USEmaster;
GO
CREATEDATABASEBLOBTest4;
GO
USEBLOBTest4;
GO
CREATETABLEFileInfo
(
TheNamevarchar(50),
DirPathvarchar(50)
);
然后,我们创建一个存储过程,以便网页用来插入信息:
CREATEPROCEDUREFileSystemIn
(
@TheNamevarchar(50),
@DirPathvarchar(50)
)
AS
INSERTINTOFileInfo
(TheName,DirPath)
VALUES
(@TheName,@DirPath);
接下来,用存储过程代码来替换代码分离页面代码。现在,文件信息就存储在SQL Server内部,而不是显示在标签上了。
stringsTheName,sDirPath;
sTheName=System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName.ToString());
sDirPath=System.IO.Path.GetDirectoryName(FileUpload1.PostedFile.FileName.ToString());
stringsConn=@"server=.;database=BLOBTest4;IntegratedSecurity=True";
SqlConnectionobjConn=newSqlConnection(sConn);
objConn.Open();
SqlCommandobjCmd=newSqlCommand("FileSystemIn",objConn);
objCmd.CommandType=CommandType.StoredProcedure;
SqlParameterpTheName=objCmd.Parameters.Add("@TheName",SqlDbType.VarChar,50);
pTheName.Direction=ParameterDirection.Input;
pTheName.Value=sTheName;
SqlParameterpDirPath=objCmd.Parameters.Add("DirPath",SqlDbType.VarChar,50);
pDirPath.Direction=ParameterDirection.Input;
pDirPath.Value=sDirPath;
objCmd.ExecuteNonQuery();
objConn.Close();
测试该网页,对FileInfo表使用SELECT语句来选择一个对象;结果将返回如下图所示的行:
请查阅本系列的第三篇文章,会有关于onclick存储过程代码的详细解释,在那篇文章中也使用了相同的SQL连接和指令对象。这里,可以通过创建一个网页来从SQL Server数据库获取路径信息以便查看图像。
SQL Server 2008 的文件流数据类型(FILESTREAM)
以上这些方法在实施的过程中还会出现一些问题。首先,如果不是通过网页应用程序而是通过其他方法删除或添加文件的话,SQL Server就无法察觉,因此不能做到和文件系统同步。第二个就是备份问题。实施上述方法后,我们不仅需要备份SQL Server,还需要备份文件存储的目录路径。此外,对于这些文件的安全问题,SQL Server也无法控制。
SQL Server 2008提供了解决这些问题的方法,那就是采用新的FILESTREAM数据类型。FILESTREAM文件就和标准的MDF或LDF文件一样,是存放在Windows的NTFS分区中的,不过FILESTREAM文件是专门为存储二进制数据而设计的。用CREATEDATABASE命令来创建一个特殊的文件组,并将其标记为“流(stream)”。创建该数据库后,可以将表内的一个列指定为“VARBINARY(MAX) FILESTREAM”数据类型。想要从文件系统访问存储在FILESTREAM内的BLOB是不可行的。我们无法打开Windows文件浏览器并访问这些文件,这意味着其安全是由SQL Server数据库负责处理的。此外,可以对这些BLOB文件使用标准的插入、更新和删除指令进行操作。因此对于大型的BLOB文件或像视频流这样性能要求很高的BLOB文件,SQL Server现在就有了一个可行的办法来处理这种类型的文件了。
总结
SQL Server提供了多个方法来管理BLOB二进制数据文件,如SQL Server 2005中的VARBINARY (MAX),更老版本中的IMAGE数据类型、以及 SQL Server 2008中新的FILESTREAM选项。与标准的数据类型相比,要熟练运用这些数据类型需要稍微努把力了,不过使用的方法和使用的对象都还是比较简单易用的。需要留意,在上述的例子中并没有包括错误检查。实际应用当中,必须确保文件上传控件测试上传没有问题之后,再将数据传送到SQL Server数据库。
当点击button按钮,就会显示通过文件上传控件浏览上传的文件,如下图所示:
我们还可以通过一个存储过程将该数据传递给SQL Server,这样数据库就可以成为我们的图片管理器了。首先,传见一个文本数据库来保存上述文件信息,T-SQL脚本如下:
USEmaster;
GO
CREATEDATABASEBLOBTest4;
GO
USEBLOBTest4;
GO
CREATETABLEFileInfo
(
TheNamevarchar(50),
DirPathvarchar(50)
);
然后,我们创建一个存储过程,以便网页用来插入信息:
CREATEPROCEDUREFileSystemIn
(
@TheNamevarchar(50),
@DirPathvarchar(50)
)
AS
INSERTINTOFileInfo
(TheName,DirPath)
VALUES
(@TheName,@DirPath);
接下来,用存储过程代码来替换代码分离页面代码。现在,文件信息就存储在SQL Server内部,而不是显示在标签上了。
stringsTheName,sDirPath;
sTheName=System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName.ToString());
sDirPath=System.IO.Path.GetDirectoryName(FileUpload1.PostedFile.FileName.ToString());
stringsConn=@"server=.;database=BLOBTest4;IntegratedSecurity=True";
SqlConnectionobjConn=newSqlConnection(sConn);
objConn.Open();
SqlCommandobjCmd=newSqlCommand("FileSystemIn",objConn);
objCmd.CommandType=CommandType.StoredProcedure;
SqlParameterpTheName=objCmd.Parameters.Add("@TheName",SqlDbType.VarChar,50);
pTheName.Direction=ParameterDirection.Input;
pTheName.Value=sTheName;
SqlParameterpDirPath=objCmd.Parameters.Add("DirPath",SqlDbType.VarChar,50);
pDirPath.Direction=ParameterDirection.Input;
pDirPath.Value=sDirPath;
objCmd.ExecuteNonQuery();
objConn.Close();
测试该网页,对FileInfo表使用SELECT语句来选择一个对象;结果将返回如下图所示的行:
请查阅本系列的第三篇文章,会有关于onclick存储过程代码的详细解释,在那篇文章中也使用了相同的SQL连接和指令对象。这里,可以通过创建一个网页来从SQL Server数据库获取路径信息以便查看图像。
SQL Server 2008 的文件流数据类型(FILESTREAM)
以上这些方法在实施的过程中还会出现一些问题。首先,如果不是通过网页应用程序而是通过其他方法删除或添加文件的话,SQL Server就无法察觉,因此不能做到和文件系统同步。第二个就是备份问题。实施上述方法后,我们不仅需要备份SQL Server,还需要备份文件存储的目录路径。此外,对于这些文件的安全问题,SQL Server也无法控制。
SQL Server 2008提供了解决这些问题的方法,那就是采用新的FILESTREAM数据类型。FILESTREAM文件就和标准的MDF或LDF文件一样,是存放在Windows的NTFS分区中的,不过FILESTREAM文件是专门为存储二进制数据而设计的。用CREATEDATABASE命令来创建一个特殊的文件组,并将其标记为“流(stream)”。创建该数据库后,可以将表内的一个列指定为“VARBINARY(MAX) FILESTREAM”数据类型。想要从文件系统访问存储在FILESTREAM内的BLOB是不可行的。我们无法打开Windows文件浏览器并访问这些文件,这意味着其安全是由SQL Server数据库负责处理的。此外,可以对这些BLOB文件使用标准的插入、更新和删除指令进行操作。因此对于大型的BLOB文件或像视频流这样性能要求很高的BLOB文件,SQL Server现在就有了一个可行的办法来处理这种类型的文件了。
总结
SQL Server提供了多个方法来管理BLOB二进制数据文件,如SQL Server 2005中的VARBINARY (MAX),更老版本中的IMAGE数据类型、以及 SQL Server 2008中新的FILESTREAM选项。与标准的数据类型相比,要熟练运用这些数据类型需要稍微努把力了,不过使用的方法和使用的对象都还是比较简单易用的。需要留意,在上述的例子中并没有包括错误检查。实际应用当中,必须确保文件上传控件测试上传没有问题之后,再将数据传送到SQL Server数据库。
当点击button按钮,就会显示通过文件上传控件浏览上传的文件,如下图所示:
我们还可以通过一个存储过程将该数据传递给SQL Server,这样数据库就可以成为我们的图片管理器了。首先,传见一个文本数据库来保存上述文件信息,T-SQL脚本如下:
USEmaster;
GO
CREATEDATABASEBLOBTest4;
GO
USEBLOBTest4;
GO
CREATETABLEFileInfo
(
TheNamevarchar(50),
DirPathvarchar(50)
);
然后,我们创建一个存储过程,以便网页用来插入信息:
CREATEPROCEDUREFileSystemIn
(
@TheNamevarchar(50),
@DirPathvarchar(50)
)
AS
INSERTINTOFileInfo
(TheName,DirPath)
VALUES
(@TheName,@DirPath);
接下来,用存储过程代码来替换代码分离页面代码。现在,文件信息就存储在SQL Server内部,而不是显示在标签上了。
stringsTheName,sDirPath;
sTheName=System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName.ToString());
sDirPath=System.IO.Path.GetDirectoryName(FileUpload1.PostedFile.FileName.ToString());
stringsConn=@"server=.;database=BLOBTest4;IntegratedSecurity=True";
SqlConnectionobjConn=newSqlConnection(sConn);
objConn.Open();
SqlCommandobjCmd=newSqlCommand("FileSystemIn",objConn);
objCmd.CommandType=CommandType.StoredProcedure;
SqlParameterpTheName=objCmd.Parameters.Add("@TheName",SqlDbType.VarChar,50);
pTheName.Direction=ParameterDirection.Input;
pTheName.Value=sTheName;
SqlParameterpDirPath=objCmd.Parameters.Add("DirPath",SqlDbType.VarChar,50);
pDirPath.Direction=ParameterDirection.Input;
pDirPath.Value=sDirPath;
objCmd.ExecuteNonQuery();
objConn.Close();
测试该网页,对FileInfo表使用SELECT语句来选择一个对象;结果将返回如下图所示的行:
请查阅本系列的第三篇文章,会有关于onclick存储过程代码的详细解释,在那篇文章中也使用了相同的SQL连接和指令对象。这里,可以通过创建一个网页来从SQL Server数据库获取路径信息以便查看图像。
SQL Server 2008 的文件流数据类型(FILESTREAM)
以上这些方法在实施的过程中还会出现一些问题。首先,如果不是通过网页应用程序而是通过其他方法删除或添加文件的话,SQL Server就无法察觉,因此不能做到和文件系统同步。第二个就是备份问题。实施上述方法后,我们不仅需要备份SQL Server,还需要备份文件存储的目录路径。此外,对于这些文件的安全问题,SQL Server也无法控制。
SQL Server 2008提供了解决这些问题的方法,那就是采用新的FILESTREAM数据类型。FILESTREAM文件就和标准的MDF或LDF文件一样,是存放在Windows的NTFS分区中的,不过FILESTREAM文件是专门为存储二进制数据而设计的。用CREATEDATABASE命令来创建一个特殊的文件组,并将其标记为“流(stream)”。创建该数据库后,可以将表内的一个列指定为“VARBINARY(MAX) FILESTREAM”数据类型。想要从文件系统访问存储在FILESTREAM内的BLOB是不可行的。我们无法打开Windows文件浏览器并访问这些文件,这意味着其安全是由SQL Server数据库负责处理的。此外,可以对这些BLOB文件使用标准的插入、更新和删除指令进行操作。因此对于大型的BLOB文件或像视频流这样性能要求很高的BLOB文件,SQL Server现在就有了一个可行的办法来处理这种类型的文件了。
总结
SQL Server提供了多个方法来管理BLOB二进制数据文件,如SQL Server 2005中的VARBINARY (MAX),更老版本中的IMAGE数据类型、以及 SQL Server 2008中新的FILESTREAM选项。与标准的数据类型相比,要熟练运用这些数据类型需要稍微努把力了,不过使用的方法和使用的对象都还是比较简单易用的。需要留意,在上述的例子中并没有包括错误检查。实际应用当中,必须确保文件上传控件测试上传没有问题之后,再将数据传送到SQL Server数据库。