【发布时间】:2012-02-09 06:33:36
【问题描述】:
我需要将用户代理字符串存储在数据库中,以便跟踪和比较不同浏览器之间的客户行为和销售业绩。一个非常简单的用户代理字符串大约有 100 个字符长。决定使用varchar(1024) 在数据库中保存用户代理数据。 (我知道这有点矫枉过正,但这就是想法;它应该容纳未来几年的用户代理数据,并且一些设备、工具栏、应用程序已经推送了 500 个字符的长度。)包含这些字符串的表将被规范化(每个不同的用户代理字符串只会存储一次)并被视为缓存,因此我们不必一遍又一遍地解释用户代理。
典型的用例是:
- 用户访问我们的网站,被检测为新访客
- 为此用户创建了新的会话信息
- 确定我们是否需要分析用户代理字符串,或者我们是否对它进行了有效的分析
- 如果我们有,很好,如果没有,请分析它(目前,我们计划调用第 3 方 API)
- 将相关信息(浏览器名称、版本、操作系统等)存储在与现有用户会话信息相关联并指向缓存条目的连接表中
注意:我倾向于说“搜索”数据库中的用户代理字符串,因为这不是简单的查找。但需要明确的是,查询将使用 '=' 运算符,而不是正则表达式或 LIKE % 语法。
因此,查找用户代理字符串的速度至关重要。我已经探索了一些确保它具有良好性能的方法。出于大小原因,索引整个列是正确的。部分索引也不是一个好主意,因为大多数用户代理最后都有区分信息。部分索引必须相当长才能使其值得,此时它的大小会导致问题。
所以它归结为一个散列函数。我的想法是在 Web 服务器代码中对用户代理字符串进行哈希处理,然后运行选择以查找数据库中的哈希值。我觉得这会最大限度地减少数据库服务器上的负载(而不是让它计算散列),特别是因为如果找不到散列,代码会转过来并要求数据库在插入时再次计算散列.
散列到整数值将提供最佳性能,但存在更高冲突的风险。我预计最多会看到数千或数万个用户代理;即使是 100,000 个用户代理也可以相当好地放入一个 2^32 大小的整数中,并且很少有冲突,这些冲突可以被 web 服务破译而对性能的影响最小。即使您认为整数哈希不是一个好主意,使用 32 个字符的摘要(例如 SHA-1、MD5)也应该比原始字符串快得多,对吧?
我的数据库是 MySQL InnoDB 引擎。 Web 代码将首先来自 C#,然后来自 php(在我们整合了一些托管和身份验证之后)(并不是说 Web 代码应该有很大的不同)。
如果您认为这是一个蹩脚的选择我的哈希算法问题,请让我在此道歉。我真的希望从以前做过类似事情的人那里得到一些意见,以及他们的决策过程。那么问题来了:
- 您会为此应用程序使用哪个哈希?
- 您是在代码中计算哈希值还是让数据库处理它?
- 是否有完全不同的方法在数据库中存储/搜索长字符串?
【问题讨论】:
标签: mysql string hash user-agent