如何将GCM注册ID唯一地存储到MySQL中

10
我正在设置一个使用MySQL存储移动应用程序提供的注册ID的Google云消息传递机制的服务器端。考虑到Google可以发出高达4k个注册ID,我被迫将它们存储在TEXT字段中。到目前为止一切顺利,但问题是我必须处理这种情况:
  1. 用户登录应用程序
  2. 应用程序从Google请求注册ID
  3. 应用程序将新的注册ID发送到应用程序服务器
  4. 服务器存储该注册ID并将其链接到当前已登录的用户
  5. 该用户退出登录,另一个用户登录
  6. 应用程序再次将相同的注册ID发送到服务器
  7. 服务器必须能够看到该注册ID已经存在于数据库中,但链接到其他用户
  8. 服务器取消链接以前的用户与该注册ID的关联,并将其链接到新登录的用户
所以问题是我必须确保数据库中的注册ID唯一性,但我无法为该TEXT字段添加UNIQUE索引。
我想到的可能的解决方案如下:
  • 计算注册ID的哈希值并强制使其唯一,但可能会产生冲突。
  • 我可以将唯一设备ID与注册ID一起存储,并强制该设备ID唯一。但问题是我不知道Android设备ID有多长,而且我认为在某些情况下它不可用。
  • 每次接收到新的注册ID时都进行搜索,但我认为这将导致非常低效的操作。
我确信我不是唯一面临这个问题的人,但我找不到好的解决方案。您有什么想法可以解决此问题吗?
1个回答

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

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

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


我在某处读到,4k并非必需,只有在负载方面需要。如果您只想将GCM ID存储在MySQL中,则varchar 256已经足够好了。请参阅https://groups.google.com/forum/#!msg/android-gcm/q2PzJTP71TY/DNX4lvDu5X4J。 - Aman Satija

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