我有一个大型SQL服务器表,看起来像这样:
ImageId int Page int FSPath varchar(256) ImageFrame int ...
该表存储了许多图像文件的每个页面的条目。这样做是为了使表能够表示每个页面由不同文件表示的图像,以及包含同一文件中的页面的多页图像文件。当我处理多页设置时,FSPath列的值与同一文档中的每个页面完全重复,这占用了大量空间(此表目前仅为5GB)。以这种方式复制数据似乎非常浪费,但我无法找到我满意的替代解决方案。
此表的使用模式由基于路径(和其他列)的主键(ImageId / Page)的查找控制,但我还需要能够有效地处理新数据的插入和偶尔的删除。
如果我为路径元素创建一个查找表并将一个路径元素id插入到pages表中,我需要通过Id和路径对它进行索引,这会影响存在不同路径段的场景对于每个页面,并且在查找表中可能存在或不存在路径的新数据的插入变得复杂。此外,删除主页表中的任何行都需要清除相关的路径条目(如果不再使用它)。
我一直希望我可以创建一个可更新的连接表视图,让SQL Server为我做了一些魔术,但是我收到了消息:视图或函数'Scrap.dbo.PageView'不可更新,因为修改影响多个基表。试图执行插入。
有没有合理的方法做到这一点,我只是想念,或者我运气不好?
答案 0 :(得分:1)
这不会攻击重复条目问题,因为我无法100%理解你的架构,但这里有一个想法我必须减少潜在的大小,假设你也存储路径信息as filesize。
文件系统是什么样的?如果它是一个深层目录树,有没有什么方法可以将它抽象到一个单独的查找表,而不是每次都存储路径信息?例如,像:
表格路径:
ID PATHNAME PARENT int varchar(128) int, FK on PATHS.ID --- ------------ -------------------- 1 / NULL 2 images 1 3 dir1 2 4 dir2 2
或者为了更快地重建路径,只需存储整个事物,只要您只保存一次路径即可。这样你就不用担心每次都会递归到root来组装路径:
ID PATHNAME int varchar(128) --- ------------ 1 / 2 /images 3 /images/dir1 4 /images/dir2
然后您可以将表的定义更改为:
ImageId int Page int FileName varchar(256) Path int, FK to PATHS.ID ImageFrame int ...
并且可能节省一点空间,特别是如果它非常深。
答案 1 :(得分:0)
我认为你是对的 - 创建一个新表只是为了存储唯一路径实际上可能比在原始表中留下重复数据需要更多的空间。此外,它使查询和更新变得复杂。这当然取决于重复的数量。
答案 2 :(得分:0)
我对实际问题感到困惑?你有性能问题还是5演出真的那么贵?如果性能是问题,则较小的表可能不是解决方案。我会调查将FSPath更改为char(256)。它将占用更多空间,但您的数据将在硬盘驱动器上排得更好,而应该帮助提高性能。 我也支持你所描述的更改架构,但如果它不可行,因为消费者不能/不会改变代码,你可能需要构建一些测试来证明改变是值得的。