【问题标题】:How to stream large binary data to SQL Server如何将大型二进制数据流式传输到 SQL Server
【发布时间】:2023-03-23 20:20:01
【问题描述】:

我有一个用 ASP.NET MVC 编写的带有 SQL Server 后端的 Web 服务。客户端可以在调用 Web 服务时发送大量数据,每个数据大约为 10 兆字节。

在服务器端,我想读取 HTTP 请求流并将其写入 SQL 表中的 VARBINARY 字段。 如何在不将整个流读入内存数组的情况下做到这一点?

我担心内存的原因是这个系统需要扩展到 1000 个并发客户端(至少)。

我目前正在使用 Linq to SQL,它看起来不支持数据流,因为 Linq Binary 类型只能使用字节数组进行初始化。

还有其他方法可以使用 Linq to SQL 做到这一点吗?

如果使用 Linq to SQL 无法做到这一点,我该如何使用 ADO.NET 或其他方法做到这一点?

【问题讨论】:

  • 你用的是什么版本?建议使用 Filestream,而不是在数据文件中以 blob 形式存储大数据。
  • @Martin - 什么文件流?如果没有进一步的阐述,您的评论并不是很有用。
  • @Peter:这里的一些人认为读者足够聪明,可以在文档的搜索中输入一个术语。
  • @TomTom - SO 具有类似 wiki 的简单功能,可以轻松添加带有相关内容链接的快速阅读答案。不使用这些功能只是懒惰。此外,称人们愚蠢并不能成为一个非常有建设性的论点。在这种特定情况和上下文中,我至少可以想到两个Filestreams。要求每个读者猜测@Martin 指的是哪一个非常有用吗?国际海事组织,没有。

标签: sql-server asp.net-mvc linq-to-sql ado.net scalability


【解决方案1】:

您可以将数据流式传输到磁盘,然后使用OPENROWSET 执行数据的批量导入。例如:

INSERT INTO YOURTABLE(binaryColumnName) 
SELECT * FROM 
OPENROWSET(BULK N'C:\data.bin', SINGLE_BLOB)

您可以使用temp file APIs 来避免管理磁盘上数据的生命周期...一旦不再使用,它​​将被删除。

【讨论】:

  • 不确定如果 IIS 和 SQL Server 部署在不同的机器上是否有效,因为我需要将文件存储在共享中。
  • 这就是 SqlServer 中的 FileStream 所支持的。客户端通过 SMB 将数据传输到 sql server,sql server 在任何配置存储数据的地方管理数据。优点是您不必将文件保存在 Web 服务器上,然后将其传输到 sql 服务器。 Sql server 还根据 sql server 规则动态管理安全性。缺点是您必须允许 Windows 身份验证,并且您的 Web 服务器和 SMB 的 sql 服务器之间没有防火墙限制。
【解决方案2】:

我相信您可以使用 UPDATE 语句的 .WRITE 子句来进行分块数据插入。如果您使用 LINQ,您将从数据上下文对象创建两个命令。第一个创建(插入)将包含数据的行。第二个是使用 .WRITE 子句的 UPDATE 语句。参数化数据和偏移值。循环,执行 UPDATE 语句的次数与“块”一样多。

插入 XrayImages (HeaderId, ImageBytes) VALUES(@headerId, @imageValue)

更新 XrayImages SET ImageBytes.WRITE(@imageChunk, NULL, @chunkLength WHERE ImageId = @imageId;

更多信息,请查看这篇 MSDN 文章:http://msdn.microsoft.com/en-us/library/bb399384.aspx


我很确定当您的控制器代码被调用时,整个请求已经被接收(并且在内存中)。我基于 Request.Files 集合已经知道有多少文件以及它们的长度。对于多部分表单,我知道如何确定这一点的唯一方法是阅读整个请求。我不知道如何在 MVC 中更改它,因此您可能必须编写一个处理程序来执行实际文件上传本身。

这里有很多变量需要考虑。根据将同时上传数据的 1000 个并发客户端的数量,您需要在数据库服务器和 Web 服务器之间使用多个 GB 网卡。您还需要数据库服务器上的 I/O 功能,这超出了我的经验。

我会认真考虑将文件保存到基于文件系统的位置并将元信息保存在数据库中,特别是如果您可以将文件保存在 Web 服务器上。否则,我认为使用 SqlServer 的 FileStream 功能将比纯表解决方案更具可扩展性。

希望有帮助!

【讨论】:

  • 我正在使用 Request.InputStream 它不应该将所有内容缓冲到内存中。我没有使用 Request.Files,因为客户端没有使用 HTML 上传功能(客户端是服务,而不是运行 Web 浏览器的用户)。您提出了一些好的观点,但我可能需要在进行任何架构更改之前进行测量。
  • 一个可能的快速测试是进行上传,在控制器动作的早期设置一个断点。查看内存使用量(可能应该使用 IIS 而不是 Web 开发服务器)是否随着上传大小而增加。使用更大的文件会使这一点更加明显。
猜你喜欢
  • 1970-01-01
  • 2014-09-25
  • 2012-08-27
  • 2010-12-03
  • 1970-01-01
  • 2016-02-11
  • 1970-01-01
  • 2016-12-24
相关资源
最近更新 更多