【发布时间】:2020-09-22 09:36:08
【问题描述】:
我继承了一个包含 .png 图像的数据库,这些图像已转换为byte[],最后是ToBase64String,并保存在一个包含许多重复图像的表中。我想清理它创建一个具有唯一图像的新表,但原始表没有与图像相关的主键。我提出了以下想法,但希望得到一些关于可行性的反馈或更好的建议。
i) 创建包含 2 列的新表
PrimaryKey varchar(64)
ImageBinary varbinary(MAX)
ii) 将 Base64String 转换回图像 byte[] 并在 SQL 中存储为ImageBinary varbinary(MAX)
iii) 使用HASHBYTES('SHA2_256', ImageBinary) 散列图像并在SQL 中存储为PrimaryKey varchar(64)
iv) 任何新图像都将被散列并与现有的主键散列进行比较。
目前的统计数据大约
- 数据库中的图像大约 200,000 个
- db 70,000 中的唯一图像
- db 1,000,000 中潜在的未来独特图像
- SQL 中 ToBase64String 的当前数据字符长度 Min:2,900 Max: 170,000
两个主要问题
-
散列图像的原因是我认为它可以通过比较新图像散列与现有图像散列来加快检查重复项。另一种方法是比较完整图像并使用整数作为主键。散列更好吗?
-
如果首选散列,我真的不需要加密散列,SQL 中可以为此使用的最快/最短散列是什么?
【问题讨论】:
-
块越大,算法越快,所以MD5比SHA1慢,SHA1比SHA256慢。如果您将图像存储在数据库中,则无论如何都不能使用数据库未提供的任何算法,因此您不能使用任何非加密哈希
-
您使用的是哪个版本? SQL Server 2017 添加了对 Python 的支持,这意味着您可以使用 Python 包进行散列或图像比较 - 事实上,添加 Python 是为了启用此类 ML 场景。将其用作通用扩展机制是一种奖励
-
这是服务器上的 SQL Server 2016,它与 C# 集成,我很好地根据不同的编码复制 SQL/C# 之间的哈希。
-
SQL Server 2016 为您提供 R,它还包含用于散列和 ML 的包。 SQLCLR 本质上是 .NET 3.5+ 或 .NET 4-:它不理解 Tasks 或 NuGet。我怀疑在 R 中找到 CityHash 或 MurmurHash 实现比在 C# 中更容易
-
检查Data.HashFunction。它支持许多哈希算法,但 SQLCLR 对 NuGet 一无所知。您必须创建自己的 SQLCLR 项目,添加 NuGet 包并希望没有不兼容
标签: sql sql-server