Lev*_*kon 3 t-sql blob filestream
我有一个数据库,设置为使用blob FileStream在varbinary(max)字段上的音频文件.它的尺寸增加了80GB以上,我面临性能问题.
做了一些环顾四周后,我发现我的平均斑点大小约为180k.因为根据MSDN文件流应该用于超过1MB的对象,我正在重新评估我如何存储这些blob.MSDN还指出,"对于较小的对象,在数据库中存储varbinary(max)BLOB通常可以提供更好的流式传输性能." 所以我正在考虑从varbinary(max)到文件流,再到使用varbinary(max)字段.
所以我的问题是,有没有一种很好的方法使用sql脚本将每个文件流blob从文件流移动到实际的varbinary字段本身?在我决定要求之前,我一直在研究的另一种方法是让ac#app查询数据库中的blob并将每个blob写入文件系统.然后从数据库中手动删除文件流内容.然后让c#app从文件系统中读取blob并写回数据库.我认为必须有一个更简单的方法.
假设您的源表如下所示:
CREATE TABLE audioFiles
(
AudioID INT IDENTITY NOT NULL PRIMARY KEY,
[Name] VARCHAR(50) NOT NULL,
[AudioData] VARBINARY(MAX) FILESTREAM NULL,
RowGuid UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL UNIQUE DEFAULT(NEWID())
)
Run Code Online (Sandbox Code Playgroud)
然后你可以创建第二个表:
CREATE TABLE audioBlobs
(
AudioID INT IDENTITY NOT NULL PRIMARY KEY,
[Name] VARCHAR(50) NOT NULL,
[AudioData] VARBINARY(MAX) NULL,
RowGuid UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL UNIQUE DEFAULT(NEWID())
)
GO
Run Code Online (Sandbox Code Playgroud)
(请注意,AudioData第二个表中的列中缺少FILESTREAM ...导致二进制数据与页面的其余部分一起存储在页面上,而不是存储在单独的FILESTREAM文件组中.)
然后,您只需将数据从一个表插入另一个表:
SET IDENTITY_INSERT audioBlobs ON
INSERT INTO audioBlobs (AudioID, Name, AudioData, RowGuid)
SELECT AudioID, Name, AudioData, RowGuid FROM audioFiles
SET IDENTITY_INSERT audioBlobs OFF
Run Code Online (Sandbox Code Playgroud)
完成后,您可以删除原始表,并将新表重命名为原始表的名称:
DROP TABLE audioFiles
GO
EXECUTE sp_rename N'dbo.audioBlobs', N'audioFiles', 'OBJECT'
GO
Run Code Online (Sandbox Code Playgroud)
或者,您可以在原始表中的VARBINARY(MAX)列旁边创建第二列FILESTREAM,只需使用旧列的数据更新新列的值.请注意,无论您采用哪种方式,您的磁盘空间使用量都会增加一倍以上 - 实际音频数据的空间增加一倍,将其从FILESTREAM文件组迁移到PRIMARY文件组(或主数据文件所在的位置),另外还有事务日志中有很多空间.