根据crypt()文档,salt需要是字母"./0-9A-Za-z"的22个64位.
这是他们给出的代码示例:
crypt('rasmuslerdorf', '$2a$07$usesomesillystringforsalt$');
Run Code Online (Sandbox Code Playgroud)
第一个令人困惑的部分是盐有25个字符,而不是22个字符.
问题1:这是不是意味着盐应该是更长的超过22个字符?
然后我自己测试了这个功能并发现了一些东西 如果我使用20个字符的盐,我会得到这个
// using 20 char salt: 00000000001111111111
crypt('rasmuslerdorf', '$2a$07$00000000001111111111$');
// $2a$07$00000000001111111111$.6Th1f3O1SYpWaEUfdz7ieidkQOkGKh2
Run Code Online (Sandbox Code Playgroud)
因此,当我使用20个字符的盐时,整个盐都在输出中.这很方便,因为我不必将盐存放在一个单独的地方.(我想使用随机盐).我将能够从生成的哈希中读取盐.
但是,如果我使用22字符盐作为文档说明,或者更长的盐,最后将盐切断.
// using 22 char salt: 0000000000111111111122
crypt('rasmuslerdorf', '$2a$07$0000000000111111111122$');
// $2a$07$000000000011111111112uRTfyYkWmPPMWDRM/cUAlulrBkhVGlui
// 22nd character of the salt is gone
// using 25 char salt: 0000000000111111111122222
crypt('rasmuslerdorf', '$2a$07$0000000000111111111122222$');
// $2a$07$000000000011111111112uRTfyYkWmPPMWDRM/cUAlulrBkhVGlui
// Same hash was generated as before, 21 chars of the salt are in the hash
Run Code Online (Sandbox Code Playgroud)
问题2:那么,盐的长度到底是多少?20?22?更长?
问题3:此外,在检查密码时,从哈希中读取盐是否是个好主意?而不是将盐存储在单独的字段中并从那里读取.(这似乎是多余的,因为盐似乎包含在哈希中).
我正在开发一个工作项目,我需要根据性能原因创建和维护摘要表.我认为正确的术语是物化视图.
我有两个主要原因:
非规范化
我尽可能地对表格进行了规范化.因此,有些情况下我必须加入许多表来提取数据.我们使用MySQL Cluster,它在JOIN方面的性能非常差.
所以我需要创建可以运行更快的SELECT的非规范化表.
总结数据
例如,我有一个包含几百万条记录的Transactions表.交易来自不同的网站.应用程序需要生成报告,以显示每日或每月的交易计数以及每个网站的总收入金额.我不希望报告脚本每次都计算这个,所以我需要生成一个按[site,date]分类的摘要表.
这只是一个简单的例子.我需要生成和维护许多不同类型的汇总表.
在过去,我通过编写几个cron脚本来完成这些工作,以保持每个汇总表的更新.但在这个新项目中,我希望能够实现更优雅,更合适的解决方案.
我更喜欢基于PHP的解决方案,因为我不是服务器管理员,当我可以通过我的应用程序代码控制所有内容时,我感觉最舒服.
我考虑过的解决方案:
复制VIEW
如果结果表可以表示为单个SELECT查询,我可以生成VIEW.由于它们很慢,因此可以有一个cronjob将此VIEW复制到一个真实的表中.
但是,这些SELECT查询中的一些可能非常慢,即使对于cronjobs也是如此.如果旧行甚至没有更新,那么重新创建整个摘要数据的效率不高.
每个摘要表的自定义Cronjobs
这是我之前使用过的解决方案,但现在我尽量避免使用它.如果有许多汇总表,维护起来可能很麻烦.
MySQL触发器
可以向主表添加触发器,以便每次有INSERT,UPDATE或DELETE时,汇总表都会相应地更新.
没有cronjobs,摘要将是实时的.但是,如果需要从头开始重建汇总表,则必须使用另一个解决方案(可能是上面的#1).
使用ORM挂钩/触发器
我使用Doctrine作为我的ORM.有一种方法可以添加将在INSERT/UPDATE/DELETE上触发内容的事件侦听器,而后者又可以更新汇总表.从某种意义上说,这个解决方案类似于上面的#3,但我将更好地控制这些触发器,因为它们将在PHP中实现.
实施注意事项:
完成重建
我希望避免重建摘要表,以提高效率,并且只更新新数据.但是如果出现问题,我需要能够使用主表上的现有数据从头开始重建汇总表.
忽略旧数据的更新/删除
某些摘要可以假定永远不会更新或删除旧记录,但只会插入新记录.摘要过程可以通过假设它不需要检查旧数据的更新来节省大量工作.
但是,这当然不适用于所有表格.
记录日志
我们假设我无法访问或不想使用二进制MySQL日志.
为了总结新数据,摘要过程只需要记住它汇总的最后记录的最后一个主键ID.下次运行时,它可以汇总该ID之后的所有内容.但是,为了跟踪已更新/删除的旧记录,它需要另一个日志,以便它可以返回并重新汇总该数据.
我将不胜感激任何可以提供帮助的策略,建议或链接.谢谢!