Tsql 如何在T-SQL中将filestream中的varbinary(max)转换为实际的varbinary(max)

Tsql 如何在T-SQL中将filestream中的varbinary(max)转换为实际的varbinary(max),tsql,blob,filestream,Tsql,Blob,Filestream,我有一个数据库,它被设置为在varbinary(max)字段上对音频文件使用blob FileStream。它的大小在80GB以上,我面临性能问题 环顾四周后,我发现我的平均斑点大小约为180k。由于根据文件流应该用于1MB以上的对象,我正在重新评估如何存储这些blob。MSDN还指出,“对于较小的对象,在数据库中存储varbinary(max)blob通常可以提供更好的流性能。”因此,我正在考虑从使用filestream的varbinary(max)改为仅使用varbinary(max)字段

我有一个数据库,它被设置为在varbinary(max)字段上对音频文件使用blob FileStream。它的大小在80GB以上,我面临性能问题

环顾四周后,我发现我的平均斑点大小约为180k。由于根据文件流应该用于1MB以上的对象,我正在重新评估如何存储这些blob。MSDN还指出,“对于较小的对象,在数据库中存储varbinary(max)blob通常可以提供更好的流性能。”因此,我正在考虑从使用filestream的varbinary(max)改为仅使用varbinary(max)字段


所以我的问题是,有没有一种很好的方法可以使用sql脚本将每个filestream blob从filestream移动到实际的varbinary字段本身?另一种方法,我在决定询问之前一直在研究,就是让c#app查询数据库中的blob,并将每个blob写入文件系统。然后手动从数据库中删除filestream内容。然后让c#应用程序从文件系统中读取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())
)
然后您可以创建第二个表:

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
(请注意,第二个表中的
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
完成后,可以删除原始表,并将新表重命名为原始表的名称:

DROP TABLE audioFiles
GO

EXECUTE sp_rename N'dbo.audioBlobs', N'audioFiles', 'OBJECT' 
GO
或者,您可以在原始表中的
FILESTREAM
列旁边创建第二个
VARBINARY(MAX)
列,只需使用旧列的数据更新新列的值。请注意,无论采用哪种方式,您的总磁盘空间使用量都将增加一倍以上——将实际音频数据的空间增加一倍,将其从FILESTREAM文件组迁移到主文件组(或主数据文件所在的任何位置),加上事务日志中的大量空间。

NEWID()不适合索引。最好改用NEWSEQUENTIALID()。