在单独的1-1表中使用varbinary字段有什么好处?

时间:2009-09-25 14:39:22

标签: sql-server sql-server-2005 performance database-design varbinary

我需要将二进制文件存储在SQL Server 2005上的varbinary(max)列中,如下所示:

的FileInfo

  • FileInfoId int,PK,identity
  • FileText varchar(max)(可以为null)
  • FileCreatedDate datetime等。

FileContent

  • FileInfoId int,PK,FK
  • FileContent varbinary(max)

FileInfo与FileContent具有一对一的关系。 FileText用于在没有要上载的文件时使用,并且仅为项目手动输入文本。我不确定有多少百分比的项目会有二进制文件。

我应该创建第二个表吗?两个表设计会有任何性能改进吗?有任何合理的好处吗?

我找到了this page,但不确定它是否适用于我的情况。

3 个答案:

答案 0 :(得分:6)

没有表现也没有运作优势。从SQL 2005开始,引擎在单独的分配单元(单独的b树)中为存储了LOB类型。如果您研究SQL Server的Table and Index Organization,您将看到每个分区最多有3个分配单元:数据,LOB和行溢出:

Table Organization

LOB字段(varchar(max),nvarchar(max),varbinary(max),XML,CLR UDT以及不推荐使用的类型text,ntext和image)将在数据记录本身中,在聚簇索引中,只有非常小的占用空间:指向LOB分配单元的指针,请参阅Anatomy of a Record

通过将LOB明确存储在单独的表中,您绝对不会获得。您只需添加不必要的复杂性,因为以前的原子更新现在必须将它们自己分配到两个单独的表中,从而使应用程序和应用程序事务结构复杂化。

如果LOB内容是整个文件,那么您可能应考虑升级到SQL 2008并使用FILESTREAM

答案 1 :(得分:2)

这个双表设计没有真正的逻辑优势,因为关系是1-1,您可能拥有FileInfo表中捆绑的所有信息。但是,有严重的操作和性能优势,特别是如果您的二进制数据平均大小超过几百字节。

编辑:正如Remus Rusanu所指出的,在一些DBMS实现(如SQL2005)上,大对象类型透明地存储到一个单独的表中,有效地减轻了拥有大记录的实际缺点。此功能的引入隐含地证实了[true]单表方法的弱点。

我只是扫描了这个问题中引用的SO帖子。我通常认为,虽然其他发布会产生一些有效点,例如内在数据完整性(因为对给定项目的所有CRUD操作都是原子的),但总的来说,除非是相对非典型的用例(例如使用项目)表作为一次主要查询单个项目的存储库),性能优势是使用两个表方法(“header”表上的索引将更有效,不需要二进制数据的查询将更快地返回等等等等。)

如果设计演变为在不同的上下文中提供不同类型的二进制对象,则这两种表方法具有进一步的好处。例如,假设这些项目是图像(GIF,JPG等)。在以后您还希望提供这些图像的小预览版本(和/或高分辨率版本),这种选择由上下文驱动(用户偏好,低带宽客户端,订户与访客等等。)。在这种情况下,不仅与单表方法相关的操作问题变得更加尖锐,模型变得更加通用。

答案 2 :(得分:0)

它可以帮助将IMAGE,(N)TEXT,(N)VARCHAR(max)和VARBINARY(max)列从更宽的表中分离出来,纯粹是为了SQL Server的某些限制。 例如,在2012年之前,如果它包含LOB,则无法在线重建聚簇表。另一方面,您可能不关心这些限制,因此设置表格就像您的数据相关是更好的事情。 如果您实际上想要将LOB数据保留在表分配单元之外,您仍然可以设置“超出行的大值类型”表选项。