Pat*_*k M 5 mysql string hash user-agent
我需要将用户代理字符串存储在数据库中,以跟踪和比较不同浏览器之间的客户行为和销售业绩。一个很普通的用户代理字符串大约100个字符长。决定使用varchar(1024)来将用户代理数据保存在数据库中。(我知道这太过分了,但这是个主意;应该在以后的几年中容纳用户代理数据,并且某些设备,工具栏,应用程序已经将500个字符推入了长度。)包含这些字符串的表将被规范化(每个不同的用户代理字符串只会存储一次),并像缓存一样对待,因此我们不必一遍又一遍地解释用户代理。
典型的用例是:
注意:我倾向于说“搜索”数据库中的用户代理字符串,因为它不是简单的查找。但需要明确的是,查询将使用“ =”运算符,而不是正则表达式或LIKE%语法。
因此,查找用户代理字符串的速度至关重要。我已经探索了几种确保其性能良好的方法。出于大小原因,索引整个列是正确的。部分索引不是一个好主意,因为大多数用户代理最后都具有区别信息。部分索引必须相当长才能使其值得使用,这时它的大小会引起问题。
因此归结为哈希函数。我的想法是对Web服务器代码中的用户代理字符串进行哈希处理,然后运行select在数据库中查找哈希值。我觉得这样可以最大程度地减少数据库服务器上的负载(而不是让它计算哈希),尤其是因为如果找不到哈希,则代码会转过来并要求数据库在插入时再次计算哈希。
散列为整数值将提供最佳性能,但有发生更高冲突的风险。我期望最多看到成千上万的用户代理。即使是100,000个用户代理,也可以很好地适合2 ^ 32大小的整数,并且几乎没有冲突,而这些冲突可以由Web服务在对性能的影响最小的情况下进行解密。即使您认为整数哈希不是一个好主意,使用32字符摘要(例如SHA-1,MD5)也应比原始字符串快得多,对吗?
我的数据库是MySQL InnoDB引擎。Web代码最初将来自C#,随后将来自php(在我们整合了一些托管和身份验证之后)(不是Web代码应该有很大的不同)。
如果您认为这是la脚的“选择我的哈希算法”问题,请允许我在此道歉。我真的很希望能从以前做过类似事情的人那里获得一些意见,并在他们的决策过程中得到一些意见。因此,问题是:
Your idea of hashing long strings to create a token upon which to lookup within a store (cache, or database) is a good one. I have seen this done for extremely large strings, and within high volume environments, and it works great.
"Which hash would you use for this application?"
"Would you compute the hash in code or let the db handle it?"
"Is there a radically different approach for storing/searching long strings in a database?"
表建议(仅用于示范):
user
user_agent_history
user_id int(11) 无符号非空agent_hash varchar(255) 不为空agent
agent_hash varchar(255) 不为空browser varchar(100) 不为空agent 文本不为空关于架构的几点说明:
从您的 OP 来看,您似乎需要用户和代理之间的 M:M 关系,因为用户可能在工作中使用 Firefox,但随后可能在家中切换到 IE9。因此需要数据透视表。
用于的 varchar(255) 有待agent_hash讨论。MySQL建议使用 varbinary 列类型来存储散列,其中有几种类型。
我还建议创建agent_hash一个主键,或者至少向列添加一个 UNIQUE 约束。