10

我正在设置谷歌云消息传递机制的服务器端,使用 MySQL 存储移动应用程序提供的注册 ID。鉴于 Google 最多可以发布 4k 个注册 ID,我不得不将它们存储在 TEXT 字段中。到目前为止一切都很好,问题是我必须处理这样的情况:

  1. 用户登录应用程序
  2. 该应用程序向谷歌请求注册 ID
  3. 应用将新的注册 id 发送到应用服务器
  4. 服务器存储该注册 ID 并将其链接到当前登录的用户
  5. 该用户注销并且新用户登录
  6. 应用程序向服务器发送与以前相同的注册 ID
  7. 服务器必须能够看到注册 id 已经在数据库中但链接到另一个用户
  8. 服务器将注册 id 与前一个用户取消链接,并将其链接到新登录的用户

所以问题是我必须确保数据库中注册 ID 的唯一性,但我无法为该 TEXT 字段添加唯一索引。

我能想到的可能解决方案:

  • 计算注册 id 的哈希并强制该哈希是唯一的,但可能存在冲突。
  • 我可以将唯一的设备 ID 与注册 ID 一起存储,并强制该设备 ID 是唯一的。我看到的问题是我不知道 android 设备 id 可以多长时间,而且我认为在某些情况下它不可用。
  • 每次收到新的注册 ID 时,我都可以执行搜索,但我认为这最终会导致性能非常差的操作。

我确信我不是唯一面临这个问题的人,但我找不到好的解决方案。关于如何解决这个问题的任何想法?

4

1 回答 1

13
  • 为了存储注册 ID 本身,最好使用 VARBINARY(4096) 列。如果您使用有效的字符集(例如 UTF-8)对注册 ID 进行编码,它比 TEXT 更有效。

  • 为了高效搜索,您仍然应该有一个额外的索引散列列 (BINARY(32)) - 我们使用SHA-256摘要算法从注册 ID 中获取 32 字节散列。哈希列不必是唯一的。冲突应该是非常罕见的,即使它们发生,您的查询也会为您提供少量共享相同哈希的注册 ID,因此在您的 Java 代码中测试其中一个(如果有)不会影响性能实际上与您要查找的注册 ID 匹配。

  • 如果您选择存储唯一的设备 ID 并基于它进行搜索,我建议您为每个设备分配自己的标识符。该标识符可以是(例如)BIGINT(java 中的 long)。您可以要求应用程序在首次启动时调用您的服务器以获取唯一标识符。您可以将其存储在设备的外部存储中,以便卸载应用程序然后重新安装的设备仍具有相同的标识符。

于 2013-10-09T16:18:18.620 回答