我正在查看SQL Server中的FILESTREAM属性以将文件存储在其中。据我所知,它将文件存储在硬盘上,并将文件指针/路径信息存储在DB中。此外,在流程中保持事务一致性。
对于FILESTREAM属性,似乎还存在“FILESTREAM数据只能存储在本地磁盘卷上”的限制。
如果我预计我的网络应用程序每次存储200,000张1-2mb的图像,我需要大约200GB的硬盘空间来存储图像。由于FILESTREAM要求所有数据仅按照限制存储在本地磁盘上,因此无法在单个硬盘驱动器上存储数百万个文件,因为存储要求非常大。
我对限制的理解是正确还是我在这里遗漏了什么?
如果这个限制是正确的,我会将其作为普通blob存储在db中,然后将我的数据库存储在我的数据库中以增加存储要求,这对于FILESTREAM来说似乎是不可能的。
请分享您的想法!
更新:
关于FILESTREAM的更多问题: -
答案 0 :(得分:19)
FILESTREAM实际上不需要本地存储,只需要SMB网络存储。 iSCSI或光纤通道SAN可以正常存储FILESTREAM数据。每个表还可以有多个文件流文件组,实质上是对数据进行分区。如果您严格针对sql server 2008,则没有理由不将文件流用于大型二进制数据。有一篇Microsoft白皮书描述了文件流分区here。
答案 1 :(得分:4)
关于本地磁盘卷要求
不要太字面地使用 local 。虽然确实要求MSSQL“看到”与FILESTREAM数据相关联的文件组作为本地驱动器,但这种存储通常是通过NAS或其他存储技术提供的,这些技术会让Windows认为这些是本地NTFS磁盘(通过iSCSI等方式)。对于企业应用程序尤其如此,您提到的空间要求水平。
完全使用FILESTREAM ......
仔细权衡利弊。你的问题提到了相当大的(MB大小)图像(我假设图形图像,而不是各种逻辑图像),这意味着它们相当原子地使用它们。文件服务器设置需要外部(到SQL服务器)管理和同步,但这似乎是一个相对较小的成本,以保持您的自由,而不是相对于SQL Server / Microsoft,而且你的能力为了扩展/带宽目的,更容易移动东西。
答案 2 :(得分:2)
使用SQL群集不会为您提供任何额外的存储可用性,因为群集需要SAN存储。您也可以简单地创建LUN或LUN,以便在非聚簇实例上用作FILESTREAM存储。
答案 3 :(得分:1)
在sql server 2008中逐步实施本地文件流
在sql server中配置文件流:
在SQL Server 2008中执行以下脚本:
EXEC sp_configure filestream_access_level, 2 RECONFIGURE
为文件流创建数据库:
CREATE DATABASE MyFsDb
ON
PRIMARY ( NAME = MyFsDat,
FILENAME = 'c:\data\myfsdat.mdf'),
FILEGROUP MyFsGroup CONTAINS FILESTREAM( NAME = MyFs,
FILENAME = 'c:\data\myfs1')
LOG ON ( NAME = MyFsLog,
FILENAME = 'c:\data\myfslog.ldf')
GO
创建表:
CREATE TABLE MyFsTable
(
fId INT IDENTITY PRIMARY KEY,
fData VARBINARY(MAX) FILESTREAM NULL,
fName NVARCHAR(300),
RowGuid UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL UNIQUE DEFAULT NEWID()
)
在表格中添加数据的步骤:
ALTER PROCEDURE [dbo].[uspAddFile]
@fData VARBINARY(Max),
@ fName varchar(50),
AS
BEGIN
INSERT INTO MyFsTable (fData, fName, RowGuid) VALUES (@Item, @ItemName, DEFAULT)
END
让我们使用C#从前端添加一些数据:
Public void AddFile()
{
string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["connectionstring"].ToString();
con = new System.Data.SqlClient.SqlConnection(connectionString);
cmd = new System.Data.SqlClient.SqlCommand("uspAddFile", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@fData", SqlDbType.Binary).Value = GetByte(TempPath);
cmd.Parameters.Add("@fName", SqlDbType.VarChar).Value = tempFile;
con.Open();
result = cmd.ExecuteNonQuery();
con.Close();
}