Mysql 主キー UUID と自動増分主キーの違いと利点と欠点

Mysql 主キー UUID と自動増分主キーの違いと利点と欠点

導入

私はしばらくの間、postgresql データベースを使用していました。クラウドに移行した後、自動増分主キーから uuid に変更しました。uuid はグローバルに一意であり、非常に便利だと感じています。

最近 MySQL を使用したところ、すべての MySQL 主キーが自動増分主キーであることがわかりました。慎重に比較した結果、MySQL が自動増分主キーを選択する理由と、その違いがわかりました。

MySQL 5.0 より前では、複数のマスター レプリケーション環境がある場合、自動インクリメント プライマリ キーは重複する可能性があるため使用できません。バージョン 5.0 以降では、自動インクリメント オフセットを構成することで問題全体が解決されます。

どのような状況でuuidを使用するのか

1. 重複を回避し、拡張性を容易にします。これが、クラウド サービスを構築するときに UUID を選択する主な理由です。

2. 倉庫に入る前にIDを知ることができます

3. 比較的安全。uuid から単純に情報を取得することはできません。ただし、自己増分されている場合は、情報を公開するのは簡単です。顧客 ID が 123456 の場合、123456 の顧客 ID があることは簡単に推測できます。

UUIDの何が問題なのか

1. UUIDは16バイトで、int(4バイト)やbigint(8バイト)よりも多くのストレージスペースを占有します。

2. サイズと乱雑さにより、パフォーマンスの問題が発生する可能性があります

MySQL の UUID 原則

MySQL の InnoDB ストレージ エンジンがストレージを処理する方法は、クラスター化インデックスを使用することです。

クラスター化インデックスとは、データベース テーブル行内のデータの物理的な順序が、キー値の論理的な (インデックス) 順序と同じである場合です。テーブルの物理的な順序は 1 つのケースのみに限られるため、テーブルにはクラスター化インデックスを 1 つだけ持つことができます。

1. uuidを主キーとして使用する理由

(1)実際、InnoDBストレージエンジンでは、自己増分IDを主キーとして使用した場合のパフォーマンスが最高に達しています。保存速度、読み取り速度ともに最速で、占有する保存スペースも最小です。

(2)しかし、実際のプロジェクトでは問題に遭遇します。履歴データテーブルの主キーIDは、データテーブルのIDと重複します。自動増分IDを主キーとする2つのテーブルをマージすると、必ずIDの競合が発生します。ただし、それぞれのIDが他のテーブルにも関連付けられている場合、操作が非常に難しくなります。

(3)UUIDを使用する場合、生成されるIDはテーブルに依存しないだけでなく、データベースにも依存しません。これは将来のデータ操作にとって非常に有益であり、一度限りのソリューションであると言えます。

2. UUIDのメリットとデメリット

デメリット: 1. 挿入速度に影響し、ハードディスクの使用率が低下する

2. UUID のサイズの比較は数値の比較よりもはるかに遅く、クエリの速度に影響します。

3. UUID は多くのスペースを占有します。作成するインデックスの数が増えるほど、影響は深刻になります。

利点: データを分割して統合して保存すると、グローバルな一意性が実現されます。

3. 最善の解決策

(1)InnoDBエンジンテーブルはB+ツリーに基づくインデックス構成テーブルです。

(2)B+ツリー:B+ツリーは、ディスクやその他の直接アクセス補助装置用に設計されたバランス検索ツリーです。B+ツリーでは、すべてのレコードノードがキー値の順序で同じ層のリーフノードに格納され、リーフノードポインタが接続されています。

(3)InnoDBプライマリインデックス:リーフノードには完全なデータレコードが含まれています。このタイプのインデックスはクラスター化インデックスと呼ばれます。 InnoDB インデックスは、非常に高速な主キー検索パフォーマンスを提供します。ただし、セカンダリ インデックスには主キー列も含まれるため、主キーが大きく定義されている場合は、他のインデックスも大きくなります。テーブルに多数のインデックスを定義する場合は、主キーをできるだけ小さく定義するようにしてください。 InnoDBはインデックスを圧縮しない

(4)このクラスター化インデックスの実装方法により、主キーによる検索は非常に効率的になりますが、補助インデックス検索では、最初に補助インデックスを検索して主キーを取得し、次に主キーを使用して主インデックスを検索してレコードを取得するという2つのインデックス検索が必要になります。

上記に基づいて、次のようになります。

(1)InnoDBテーブルのデータ書き込み順序がB+ツリーインデックスのリーフノード順序と一致している場合、アクセス効率は最も高くなります。ストレージとクエリのパフォーマンスのために、自己増分 ID を主キーとして使用する必要があります。

(2)InnoDBのプライマリインデックスの場合、データはプライマリキーに従ってソートされます。UUIDの乱れにより、InnoDBは大きなIOプレッシャーを生成します。このとき、UUIDを物理プライマリキーとして使用するのは適切ではありません。論理プライマリキーとして使用できます。物理プライマリキーは、引き続き自動インクリメントIDを使用します。グローバルな一意性を確保するには、uuid を他のテーブルを関連付けるインデックスとして、または外部キーとして使用する必要があります。

4. UUID を主キーとして使用する必要がある場合は、次の提案を参考にしてください。

マスタースレーブまたは MS モードの場合、MySQL 組み込みの uuid 関数を使用して一意のプライマリ キーを生成しないことをお勧めします。これは、マスター テーブルによって生成された uuid がスレーブ テーブルに関連付けられている場合、データベースにアクセスして uuid を見つける必要があり、データベースとのやり取りが 1 回多く必要になるためです。この時間差の間に、マスター テーブルがデータを生成する可能性が高く、関連付けられた uuid にエラーが発生しやすくなります。どうしても uuid を使いたい場合は、Java で生成して DB に直接保存することができます。このとき、マスターとスレーブの uuid は同じになります。

補足:MySQLのuuid()主キーは重複しています

1. mysqlのuuid()主キーが重複している

MySQLはNavicatクライアントを使用し、次のSQLを実行すると

t_user u から、id、u.user_id として replace(uuid(), '-', '') を選択します。

生成された uuid が重複していることが判明しました。

調査の結果、Navicat の問題であることが判明しました。SQL ステートメントを次のように調整する必要がありました。

t_user u から replace(convert(uuid() using utf8mb4), '-', ''), u.user_id を選択します。

結果は次のとおりです。

2. 他の解決策を使用する:

uuid に対して再度 md5 を実行します。

t_user u から id、u.user_id として md5(uuid()) を選択します。

上記は私の個人的な経験です。参考になれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。間違いや不備な点がありましたら、遠慮なくご指摘ください。

以下もご興味があるかもしれません:
  • MySQL の主キーがクエリを高速化するために数値を使用するか UUID を使用するかについての簡単な分析
  • 乱数、文字列、日付、検証コード、UUIDを生成するMySQLメソッド
  • MySQL が uuid または snowflake id を主キーとして使用することを推奨しない理由の詳細な分析
  • Mysql でサーバーの UUID を変更する方法
  • Mysql で UUID を保存するときに水平線を削除する方法
  • なぜMySQLはテーブルの主キーを分析および設計する際にUUIDを使用しないのですか?

<<:  Linux DockerでSpringbootプロジェクトを実行するための詳細な手順

>>:  HTML チュートリアル: よく使われる HTML タグのコレクション (6)

推薦する

JavaScript 配列重複排除ソリューション

目次方法1: set: データ型ではなくデータ構造であり、メンバーは一意である方法2: オブジェクト...

Linux/CentOS サーバー セキュリティ構成の一般ガイド

Linux はオープン システムです。インターネット上には、既成のプログラムやツールが多数存在します...

MySQLフィルタリングレプリケーションのアイデアの詳細な説明

目次mysql フィルター レプリケーションメインデータベースに実装ライブラリから実装いくつかの質問...

Nginxのアクセスボリューム制御の詳細な説明

目的リクエスト アクセス ボリュームを制御するための Nginx ngx_http_limit_co...

JavaScript によるデータ視覚化: ECharts マップの作成

目次概要予防1. 使用方法2. 実装手順予備実装コード効果: Geo共通設定上記の構成を追加した後の...

CSS3 変換によって子要素の固定位置を絶対位置に変更する方法

この記事では、CSS3 の transform を使用して子要素の固定配置を絶対配置に変更する方法を...

HTML+CSS+JavaScript でガールフレンド版のスクラッチ カードを作成します (一度見ればすぐに覚えられます)

誰もがスクラッチ チケットで遊んだことがあると思います。子供の頃、ポケットにお金が入るとすぐに友達に...

PrometheusとGrafanaを使用したMySQLサーバーのパフォーマンス監視の詳細な説明

概要Prometheus は、HTTP プロトコルを介してリモート マシンからデータを収集し、ローカ...

HTML チェックボックスとラジオボタンスタイルの美化の簡単な例

HTML チェックボックスとラジオボタンスタイルの美化の簡単な例チェックボックス: XML/HTML...

CentOS7にMySQL 8.0.26をインストールする手順

1. まず、お使いのマシンに応じて、MySQL 公式サイトから対応するデータベースをダウンロードしま...

CSS はモバイル デバイスで水平スクロール ナビゲーション バーを実装します (PC デバイスにも適用可能)

関数の起源最近、水平スクロール バーを必要とする H5 に取り組んでいました。いくつかのドキュメント...

VueはTodoListの例をカプセル化し、ブラウザのローカルキャッシュのアプリケーションを実装します。

この記事では主に、Vue で TodoList をカプセル化するケースと、ブラウザのローカル キャッ...

CentOS 6.2 に MySQL 5.7.28 をインストールするチュートリアル (mysql ノート)

1. 環境整備1.MySQLインストールパス: /usr/local 2. CentOS 6.2 ...