SQL Server - 比较大量MD5哈希值

时间:2018-04-08 20:10:16

标签: sql-server join hash filter md5

假设我在SQL Server中有一个存储客户电子邮件的表(几百万条记录) - 为简单起见,看起来有点如下:

CREATE TABLE [Emails]
(
    [Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [email] [nvarchar](1000) NOT NULL
)

我的客户向我发送了每个数百万条记录的客户电子邮件列表,但所有MD5-Hash都已加密,因此列表看起来如下:

0x3B46E0E53842A74172BA678974E93BBB
0xACAC5843E184C85AA6FF641AAB0AA644
0xD3C7BA16E02BE75142761894E8E4A125
...

我必须想出一个快速的方法来查看我的表格中存在哪些电子邮件。

基于我在网上/这里看到的一些答案,我提出了以下逻辑来做到这一点:

  1. 我创建了Emails表的索引视图,其中MD5-Hash列为索引:

    CREATE VIEW dbo.vw_Emails
    WITH SCHEMABINDING
    AS
        SELECT 
            Id
             , email
             , CONVERT(VARBINARY(16), HASHBYTES('MD5', LOWER(email))) AS MD5
        FROM 
            dbo.Emails
    GO
    
    CREATE UNIQUE CLUSTERED INDEX Idx_vw_Emails ON vw_Emails (MD5)
    GO
    
  2. 我创建了一个存储过程,它将BulkImport给出的列表,将其转换为临时表,将其连接到我的视图并返回任何匹配的行,如下所示:

    CREATE PROCEDURE Import_ReturnMatches
    (
        @PathToCSVFile VARCHAR(8000)
    )
    
    AS
    
    DECLARE @fieldsep CHAR(1) = ',';
    DECLARE @recordsep CHAR(1) = CHAR(10);
    
    DECLARE @Emails TABLE 
    (
        MD5 VARCHAR(MAX) NOT NULL
    );
    
    DECLARE @sql VARCHAR(8000) = 
        'CREATE TABLE #tmp 
        (
              MD5 varchar(max) NOT NULL
        );
    
        BULK INSERT #tmp
        FROM ''' + @PathToCSVFile + '''
        WITH (FIRSTROW = 1, FIELDTERMINATOR = ''' + @fieldsep + ''', ROWTERMINATOR = ''' + @recordsep + ''');
    
        SELECT *
        FROM #tmp';
    
    INSERT INTO @Emails
    EXEC (@sql);
    
    SELECT 
        r.*
    FROM 
        @Emails l
        JOIN vw_Email_Dim r 
        ON l.MD5 = r.MD5
    
  3. 正如您所看到的,我将导入的列类型设置为VARCHAR(MAX),但这只是因为没有其他功能真正起作用......这就是我被困住的地方。它似乎总是返回一个空集,即使我已将记录放在我的文件中应该匹配。

    我的问题是:

    1. 我做错了什么/我该如何解决?
    2. 我是否使用正确的数据类型进行存储/索引/导入?
    3. 这只是一个整体的坏主意吗?有没有更好的方法来完成我想做的事情?

2 个答案:

答案 0 :(得分:0)

您的问题可能就是这个值:

LOWER(email)

如果您不确定使用哪种情况或编码(Windows 1252,UTF8,UTF16,UTF16LE?)从您的来源的电子邮件生成MD5哈希,那么您正在考虑需要测试所有组合匹配的哈希值。考虑我们将LOWER更改为UPPER的位置 - 生成完全不同的MD5哈希值:

MD5 hashes of emails with different casing

您需要控制在源处生成MD5哈希的方式,或者向导入添加元数​​据(另一个字段)以描述输入的装入和编码方式。

答案 1 :(得分:0)

检查这个答案。您需要将varchar与varchar进行比较 - 我认为不是varbinary。

Generate MD5 hash string with T-SQL

相关问题