10

モバイル アプリによって提供される登録 ID を格納するために MySQL を使用して、Google クラウド メッセージング メカニズムのサーバー側をセットアップしています。Google は最大 4,000 の登録 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 を受け取るたびに検索を実行することもできますが、これは非常にパフォーマンスの低い操作になると思います。

その問題に直面しているのは私だけではないと確信していますが、良い解決策が見つかりません。どうすればこれを解決できますか?

4

1 に答える 1

13
  • 登録 ID 自体を格納するには、VARBINARY(4096) 列を使用することをお勧めします。登録 ID を効率的な文字セット (UTF-8 など) でエンコードすると、TEXT よりも効率的です。

  • 効率的な検索のために、追加のインデックス付きハッシュ列 (BINARY(32)) が必要です。SHA-256ダイジェスト アルゴリズムを使用して、登録 ID から 32 バイトのハッシュを取得します。ハッシュ列は一意である必要はありません。衝突は非常にまれである必要があり、たとえ衝突が発生したとしても、クエリは同じハッシュを共有する少数の登録 ID を提供するため、Java コードでそれらのどれを (もしあれば) テストしてもパフォーマンスが低下することはありません。探している登録 ID と実際に一致します。

  • 一意のデバイス ID を保存してそれに基づいて検索する場合は、各デバイスに独自の ID を割り当てることをお勧めします。その識別子は (たとえば) BIGINT (Java では long) にすることができます。最初の起動時にアプリケーションがサーバーを呼び出して一意の識別子を取得するように要求できます。デバイスの外部ストレージに保存できるため、アプリをアンインストールしてから再インストールしたデバイスでも同じ識別子が保持されます。

于 2013-10-09T16:18:18.620 に答える