我需要将二进制文件存储在SQL Server 2005上的varbinary(max)列中,如下所示:
FileInfo与FileContent具有一对一的关系。 FileText用于在没有要上载的文件时使用,并且仅为项目手动输入文本。我不确定有多少百分比的项目会有二进制文件。
我应该创建第二个表吗?两个表设计会有任何性能改进吗?有任何合理的好处吗?
我找到了this page,但不确定它是否适用于我的情况。
答案 0 :(得分:6)
没有表现也没有运作优势。从SQL 2005开始,引擎在单独的分配单元(单独的b树)中为已存储了LOB类型。如果您研究SQL Server的Table and Index Organization,您将看到每个分区最多有3个分配单元:数据,LOB和行溢出:
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)