首页 > 解决方案 > 在表中存储唯一的图像

问题描述

我继承了一个数据库,其中包含已转换byte[]并最终ToBase64String保存在包含许多重复图像的表中的 .png 图像。我想清理它创建一个具有唯一图像的新表,但原始表没有与图像相关的主键。我提出了以下想法,但想要一些关于可行性的反馈或更好的建议。

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) 任何新图像都将被散列并与现有的主键散列进行比较。

目前的统计数据大约

两个主要问题

  1. 散列图像的原因是我认为它可以通过比较新图像散列与现有图像散列来加快检查重复项。另一种方法是比较完整图像并使用整数作为主键。散列更好吗?

  2. 如果首选散列,我真的不需要加密散列,那么可以在 SQL 中为此使用的最快/最短散列是什么?

标签: sqlsql-server

解决方案


  1. 我会存储一个整数 uid - 如果您需要加入,比较 4 个字节比 16 个字节或更多字节快得多。如果需要,您仍然可以存储一个哈希,如果哈希不是主键,您还可以在哈希上放置一个唯一的约束。
  2. 我会说MD5。SHA-1 可能稍快一些,但它使用更多空间(20 字节而不是 16 PER HASH)。

最后,我不会在数据库中存储 100 万个文件。
看看filestream,这样您就可以通过数据库访问图像,但它存储在数据库之外。否则,进行数据库备份将成为问题。

查看 Red-Gate 的文件流教程: https ://www.red-gate.com/simple-talk/sql/learn-sql-server/an-introduction-to-sql-server-filestream/

MD5 示例:

SET IMG_MD5 = LOWER(SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('MD5', FIELD_NAME)), 3, 32) ) 
   ,IMG_SHA1 = sys.fn_varbintohexsubstring(0, HashBytes('SHA1', FIELD_NAME), 1, 0)

推荐阅读