使用PHP为任何给定的输入获取唯一的哈希值

4

我需要定期检查很多(数十万)行数据,并检查它们的当前状态是否与另一个数据库中存储的最新版本相同。是否有一种方法可以获取某些唯一值来匹配这些行,或者我必须逐列手动检查这些行?

源数据库是 SQL Server 2005 数据库,表格没有用于创建、更新和/或删除操作的时间戳机制。我已经查看了可用的行信息,但唯一可用的是伪列 %%lockres%%行信息,但这不提供日期和/或时间信息。

我的工具受限,但我有一个运行 Apache 和 PHP 的 Web 服务器,以及对源和目标数据库的直接访问权限。我只对源数据库具有读取权限。

在源数据库上,最有效的比较数据和维护性能的方法是什么?


1
哇,人们仍然在这里提出好问题吗? - Hanky Panky
不太清楚您想要什么。 如果您不知道要比较哪些行,如何将一个数据库中的某些行与另一个数据库中的行进行比较? - Erwin Moller
由于工具和资金的限制,我可能会创建自己的ETL工具。表格不应该整体更新,而是只更新更改的行(这将导致目标数据库中维度表中的新行)。@ErwinMoller,由于识别键,比较是可能的。我只想(高效地)比较行,因为数据量很大。 - Ben Fransen
1
@Ben 在这种情况下,我会在两个表中都添加一个简单的列,该列基于所有可更新字段(可能是所有字段)计算出一个简单的哈希值。然后,您可以选择实现触发器来更新哈希值,或者在比较之前手动运行它一次。当您必须确保将所有列转换为正确的类型时,请使用HashBytes('MD5', col1+col2+col3)。 - Erwin Moller
@Ben 如果这样的话,我担心你只能将来自两个源的所有数据都获取到PHP中,并进行比较。:-/ 但我猜你已经自己想到了这一点。当然,你也可以在PHP中使用MD5哈希技巧,但如果你已经可以比较源数据了,那用MD5哈希就没有太多意义了吧? - Erwin Moller
显示剩余7条评论
2个回答

1
很简单。只需在该表中创建一个列,将其命名为 anything ,在我的情况下,我使用了令牌名称。 现在,如果您希望此代码在用户注册时自动生成,则可以通过以下方式使用它:
$token = bin2hex(random_bytes(20));
$sql_query = "INSERT INTO `table_name` (`token`) VALUES ('$token')";

这里的bin2hex()函数表示二进制转十六进制。random_bytes()函数用于生成随机字节,你可以在其中指定想要选择的随机字符长度。

或者,您可以直接在表中运行此查询。

$token = bin2hex(random_bytes(20));
"UPDATE `table_name` SET `token`='$token'";

如果到现在为止,您的问题还没有解决。您可以再次向我咨询。然后,我将告诉您另一种解决此问题的方法。


0

由于您没有访问数据库的权限,我建议使用“替代”数据库来存储信息。我可以想到几种不同的方法,每种方法都有不同的优缺点。

方法1

要在表外使用哈希进行修改检查,需要始终查询所有数据,这会使操作变得非常缓慢,我会使用单独的表来存储哈希值,在那里您可以始终首先检查值是否匹配,然后再进行更新。

基本上,在插入数据时,您可以从该数据计算出本地哈希,然后将其与辅助数据库进行比较,如果它们不匹配,则知道数据不同步,并且可以将数据更新到实际数据库并将新哈希保存到辅助数据库中。

优点:

  • 只有必要更新实际数据库

缺点:

  • 比使用数据库中的哈希值更慢

方法2

始终在实际数据库中更新记录。这是最简单的解决方案,除非您需要同时更新数千条记录并且远程数据库可以处理额外的负载,否则性能影响不应太大。这只是简单的更新操作。

优点:

  • 简单易操作

缺点:

  • 会给真实数据库增加额外负担

方法三

获取修改远程数据库的权限。如果您将长时间维护该数据库,这可能是未来最好的选择。

优点:

  • 速度最快

缺点:

  • 需要获取修改表的权限

当我说数据库时,最简单的情况可能只是一个纯文本文件、SQLite 数据库或任何允许您处理本地操作的东西。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接