12

環境

Web アプリケーション、PHP 5、MySQL 5.0.91

問題

最近、一部のテーブルの主キーとして、自動インクリメント整数の使用から UUID の使用に切り替えました。MySQL のUUID()関数を介して UUID を生成する場合、それらは互いに非常に似ています。

| uuid                                 |
----------------------------------------
| 1e5988da-afec-11e1-9877-5464f7aa6d24 |
| 408092aa-afad-11e1-9877-5464f7aa6d24 |
  ^------^   ^^
  1      8   11-12

ご覧のとおり、最初の 8 文字と 11 番目と 12 番目の文字だけが異なります。UUID バージョン 1 がタイムスタンプとハードウェア MAC アドレスを使用して UUID を生成することを理解しています。ただし、これらの類似点 (および私の場合は MAC アドレスが変更されないという事実) のために、バージョン 1 の使用をためらっています。さらに、MAC アドレスが変更されない場合、ほとんどの UUID は役に立たず、スペースを浪費しています。

私のカスタム UUID 関数

実験として、PHP でカスタム UUID ジェネレーターを作成しました。

public static function GenerateUUID()
{
    return
    substr(sha1(Account::GetUsername() . Account::GetUserID()), 18, 8) . "-" .
    substr(md5(time()), rand() % 28, 4) . "-" . 
    substr(md5(date("Y")), rand() % 28, 4) . "-" . 
    substr(sha1(rand()), 20, 4) . "-" . 
    substr(sha1(rand() % PHP_INT_MAX), 17, 12);
}

結果のサンプル:

| uuid                                 |
----------------------------------------
| 574d18c2-5080-bac9-5597-45435f363ea1 |
| 574d18c2-30d4-8b5b-4ffd-001744d3d287 |

ここで、最初の 8 文字は同じユーザーの場合は同じです。これは意図されていましたが、必要ありませんでした。

質問

MySQL クエリ内でバージョン 4 またはバージョン 5 の UUID を生成する推奨/推奨方法はありますか?

そうでない場合、仕様に準拠しないカスタム UUID を (上記のように) PHP 内で生成することは許容されますか?

制限

  • コマンドライン アクセスで共有ホスティング プランを使用していますが、既存の MySQL インストールを変更できません。
  • サードパーティのパッケージ/ライブラリは避けたいと思います。

ノート

  • MAC アドレスを含む GUID を必要とするマージ、同期、またはその他の操作は実行していません。それはここでは問題ではありません。
4

2 に答える 2

11

「UUIDのほとんどが役に立たず、スペースを浪費している」というあなたの懸念は、データ型のサイズに固有のものです。理論上の制限である 16 バイトが許す限り、データベース内に多くのエントリを持つことはできません。

実際、UUID をテーブル ID として使用する場合、V1 UUID は V4 よりも適しています。これは、衝突を防ぐために MAC アドレスとタイムスタンプを使用するためです。V4 にはそのようなメカニズムはありませんが、実際にはクラッシュについてあまり心配する必要はありません :) UUID を予測できないようにする必要がある場合は、V1 の代わりに V4 UUID を使用する必要があります。

また、たとえば 4x4 バイトのランダム値を作成することは、16 バイトのランダム値を作成することと同じではない場合があることに注意してください。いつものように、暗号とランダム性: 独自の UUID::V4 ルーチンを実装することはお勧めしません。

マシンにインストールされている場合は、php-uuidパッケージを利用できます。

サンプル コード (アプリケーションでそのまま使用できます) は次の場所にあります: http://rommelsantor.com/clog/2012/02/23/generate-uuid-in-php/

次のように使用します。

$uuid = uuid_create(1);

ウェブサーバーにパッケージをインストールできるユーザーは、次のような必要なパッケージをインストールできます: (ubuntu の場合はこちら)

apt-get install php5-dev uuid-dev
pecl install uuid
于 2012-06-14T20:33:43.480 に答える
4

「類似部品」があることを評価するのは、実際にはかなり良い考えです。MAC アドレスを活用して、「どのサーバーがこの UUID を生成したか」を特定できるようになります...これは、遠隔地間でデータを移行するときに非常に役立ちます。このように、「これは私のテスト データです」と「これは私の本番データです」を実行することもできます。

PHP には、多数の UUID 生成ライブラリがあります。

PECL/PEAR の 1 つを次に示します (使用したことはありません)。

http://pecl.php.net/package/uuid

CakePHP フレームワークから:

http://api.cakephp.org/class/string#method-Stringuuid (ケーキ 2.x) http://api13.cakephp.org/class/string#method-Stringuuid (ケーキ 1.3)

最後のジェネレータ オプション:

バージョン管理フラグと関連オプションを持つ Linux コマンドラインuuidプログラムを使用し、それを使用してデータベースにフィードすることを検討してください。-vこれは非効率的ですが、少なくとも独自のジェネレーター関数を作成する必要はありません。

http://linux.die.net/man/1/uuid - man ページ

( uuidDebian 用パッケージ)

名前空間のバージョンでは、UUID に変換するために多くの「長い人名」を生成することに気付きました。それらと矛盾しない限り、それはとても甘いかもしれません。たとえば、ユーザーが電子メール アドレスで登録している場合...その電子メール アドレスの v5 uuid を取得する...いつでもその人を見つけることができます! 毎回同じ UUID を吐き出すようで、UUID は bob@bob.com と example.com のメンバーとしての一意の関係を表します。

uuid -v5 ns:URL "http://example.com/member/bob@bob.com/"

解説:

また、UUID、それらを保存しているように見える方法は、CHAR(36) ですか? 比較演算子が作動すると後悔するかもしれません。

Postgres は UUID を 128 ビット値として扱います (そしておそらく最適化されたバイナリ操作を行います) が、MYSQL の CHAR(36) ソリューションは 36 バイト = 288 ビット ANSI または 576 ビット UTF8 プラスまたはマイナスのビット/バイトを office として扱います。 - keep (そしておそらく、はるかに遅いマルチバイト文字ごとのマルチバイト文字文字列ルーチンを実行します)。

私は実際、MySQL と UUID の問題について多くのことを検討しました...そして私の結論は、16 進数表現をストレージ用のバイナリ表現に変換するストアド関数を作成する必要があるというものでした。すべての「選択」ステートメントは、16 進表現への変換を必要とします...そして、そのいずれかがどれほど効率的であるかを誰が知っていますか...最後に、Postgres に切り替えるだけです。XD

Postgres に切り替えたい場合は、既存のサーバーが運用サーバーである場合は、そのサーバーへのインストールに細心の注意を払ってください。のように...実際に移行を行う前に、クローンを作成して移行プロセスをテストします。「このパッケージをインストールすると、他の重要なパッケージが多数削除される」ため、どうにかしてシステムを強制終了できました(インストーラーがこれらの決定をどのように行ったかはわかりません)。

または、DB を操作するために最終的に多額のお金を支払う準備ができている場合は、GUID に相当する Microsoft SQL を使用してください...

UUID と MySQL を実行することは、現時点では悪い考えになりがちです。

于 2012-06-06T16:37:45.700 に答える