MySQL の面接の質問と回答

1.MySQLとは何ですか

リレーショナル データベースはデータをハードディスクに直接保存します。(Redis) に代わって、対応する NoSQL 非リレーショナル データベース

2. MyISAMInnoDBの違い

バージョン 5.5 の前後での 2 つのデフォルトのデータベース エンジンの違いは次のとおりです。

a. 行レベルのロック (テーブル内のデータの特定の行をロックして、他のトランザクションがデータを変更または削除できないように、粒度が高く同時処理効率が高い) をサポートするかどうか: MyISAM (テーブル レベルのロック) および InnoDB (行-レベル ロックとテーブルレベルロック) ロック、デフォルトは行レベル ロック)

b. トランザクションとクラッシュ後の安全なリカバリをサポートしているかどうか: MyISAM はパフォーマンスを重視しており、各クエリ操作はアトミックですが、トランザクションはサポートしていません。InnoDB はトランザクションサポート トランザクション、外部キー、その他の機能を提供します 。

c. 外部キー ( 1 つのテーブル内の別のテーブルを関連付けるために使用されるフィールドまたは属性)をサポートするかどうか: MyISAM (サポートされません) InnoDB (サポートされます)

d. MVCC (同時実行制御メカニズム) をサポートするかどうか: InnoDB によってのみサポートされます。

3. インデックスとは何ですか? 共通インデックスとは何ですか? 

以下は、データベースにインデックスを作成する方法を紹介する簡単な例です。

一般的なインデックスで使用されるデータ構造の分類:

a.BTree インデックス:

Mysql の BTree インデックスは主に B ツリー内の B+ ツリーを使用しますが、バージョン 5.5 の前後ではエンジンごとに格納方法が異なります。

MyISAM: B+Tree リーフ ノードのデータフィールドには、データ レコードのアドレスが格納されます。インデックスを検索するときは、まず B+Tree 検索アルゴリズムに従ってインデックスを検索し、指定されたKey が存在する場合は、そのデータフィールドの値を取り出しデータフィールドの値をアドレスとして使用して、対応するデータを読み取ります。記録

InnoDB:そのデータ ファイル自体がインデックス ファイルです。MyISAM と比較すると、インデックス ファイルとデータ ファイルが分離されており、テーブル データ ファイル自体はB+Tree によって編成されたインデックス構造であり、ツリーのリーフ ノードデータフィールドには完全なデータ レコードが格納されます。このインデックスのキーはデータ テーブルの主キーであるため、InnoDBテーブル データ ファイル自体が主インデックスになります。これを「クラスター化インデックス (またはクラスター化インデックス)」と呼びます残りのインデックスは補助インデックスとして使用され、補助インデックスのデータフィールドにはアドレスの代わりに、対応するレコードの主キーの値が格納される点も MyISAM とは異なります。

主インデックスに基づいて検索する場合は、キーが 配置されているノード         を直接見つけてデータを取得できますが、補助インデックスに基づいて検索する場合は、最初に主キーの値を取得してから、主キーを検索する必要があります。 索引。したがって、テーブルを設計するときは、長すぎるフィールドを主キーとして使用したり、単調でないフィールドを主キー としてこれにより、主インデックスが頻繁に分割されます。

b. ハッシュインデックス:

ハッシュ インデックスの場合、基礎となるデータ構造はハッシュ テーブルです。したがって、ほとんどの要件が単一レコード クエリに関するものである場合は、クエリ パフォーマンスが最も速いハッシュ インデックスを選択できます。その他のほとんどのシナリオでは、ハッシュ インデックスを選択することをお勧めします。 BTree インデックスを選択します
同時トランザクションはどのような問題を引き起こしますか?
1. ダーティリード:
トランザクションがデータにアクセスしてデータを変更しており、この時点ではこの変更がデータベースに送信されていない場合、他のトランザクションもデータにアクセスしてそのデータを使用する場合、データはまだコミットされていないため、他のトランザクションによって読み取られたデータは「ダーティ」であると考えられ、その後の操作は当然間違っています
2. 失われた変更:
これは、トランザクションがデータを読み取ると、他のトランザクションもそのデータにアクセスすることを意味するため、最初のトランザクションがデータを変更し、他のトランザクションがデータを変更すると、以前の変更結果は失われます
3. 反復不可能な読み取り:
これは、トランザクションが同じデータを複数回読み取ることを意味します。トランザクションが終了しないと、他のトランザクションもデータにアクセスします。その後、最初のトランザクションによるデータの 2 回の読み取り中に、2 番目のトランザクションの変更により 2 番目のトランザクションが発生する可能性があります。トランザクションの 2 回のアクセスで読み取られるデータが異なるため、 「反復不能読み取り」が発生します。
4. ファントムの読み取り:
これは、トランザクションが数行のデータを読み取り、他のトランザクションがこのデータを読み取り、変更して挿入することを検討することを意味します。その後のプロセスでは、あたかも錯覚が起こったかのように、存在しないレコードがいくつか見つかることになります。いわゆる「 ファントムリード
トランザクションの分離レベルは何ですか? MySQL のデフォルトの分離レベルは何ですか?
1. 送信されたものを読む (役に立たず、あまり役に立たない):
最も低い分離レベル。コミットされていないデータ変更の読み取りを許可します。これにより、ダーティ読み取り、ファントム読み取り、または反復不能読み取りが発生する可能性があります。
2. コミットされていない読み取り (デフォルト レベル):
  同時トランザクションによってコミットされたデータを読み取ることができます。これによりダーティ リードを防ぐことができますが、ファントム リードや反復不可能な読み取りが発生する可能性があります。 
3. 反復可能な読み取り:
同じフィールドの複数の読み取りの結果は、データが独自のトランザクションによって変更されない限り一貫性があり、ダーティ リードや反復不可能な読み取りを防ぐことができますが、それでもファントム リードが発生する可能性があります。
4. シリアル化可能:
ACID 絶縁レベルに完全準拠した最高の絶縁レベル。すべてのトランザクションは 1 つずつ実行されるため、トランザクション間で干渉が発生する可能性はありません。つまり、このレベルではダーティ リード、反復不可能なリード、ファントム リードを防ぐことができます (シリアル化分離レベルでのすべての読み取りは、操作によって行われます) 。共有ロックを取得するとパフォーマンスが低下する可能性があるため、実際のアプリケーションでは状況に応じて適切な分離レベルを選択する必要があります )
ロックメカニズムと InnoDB ロックアルゴリズム
データベースでは、ロック メカニズムを使用してデータへの同時アクセス方法を制御し、トランザクションの正確さと一貫性を確保します。したがって、ロック メカニズムを実装するためにさまざまなロック アルゴリズムが使用されます。
InnoDB のロック アルゴリズムは、主に共有ロックと排他ロックの 2 つのカテゴリに分類されます。
共有ロック : 複数のトランザクションが同時に同じデータを読み取ることを許可しますが、書き込み操作は許可しません。
排他的ロック : 読み取りおよび書き込み操作を実行できるロックは 1 つだけであり、他のトランザクションは操作を実行できません。
InnoDB は 2 段階のロック プロトコルを採用しており、トランザクションの実行中に関連データに適切な共有ロックまたは排他ロックを自動的に追加します。実装されているロック アルゴリズムは次の 3 つです。
a. 行レベルのロック。トランザクション間の分離を確保するために、行の 1 つに共有ロックまたは排他的ロックを追加します。
b. ギャップロック、
c. インテンションロックを挿入します。

銀行口座システムがあり、複数のユーザーが同時に口座照会、送金、入金を実行できると仮定します。このシナリオにおける下流レベルのロック、ギャップ ロック、および挿入意図ロックのメタファーは次のとおりです。

  • 行レベルのロック:各アカウントが独立したキャビネットに配置されるのと同じように、各ユーザーは操作する必要がある特定のキャビネットのみをロックでき、ユーザーが操作を完了して解放するまで他のユーザーはそのキャビネットを変更または削除できません。押し入れ。

  • ギャップ ロック:各アカウント間に空のロッカーがあるのと同様、ユーザーがアカウントのロッカーをロックすると、たとえそれらのロッカー アカウントに実際のロッカーがなかったとしても、他のユーザーはアカウントの前後にある空のロッカーをロックすることはできません。同様に、ギャップ ロックでは、トランザクションがデータ行の範囲をロックすると、これらのデータ行が実際には存在しない場合でも、他のトランザクションはこの範囲に新しいデータ行を挿入できません。銀行口座システムの場合、これは、ユーザーが口座に対して送金または入金操作を実行している場合、他のユーザーは、たとえその口座に関する情報を照会したい場合でも、その口座の前後に操作を挿入できないことを意味します。

  • インテントロックの挿入:銀行が送金リクエストを処理するときにトランザクションの意図を記録するのと同じように、トランザクションによって特定の支店の口座が変更される可能性があることを意味します。他のトランザクションは既存のデータの読み取りと変更を続行できますが、アカウントの前後に新しい操作を挿入することはできません。また、トランザクションがコミットまたはロールバックされるまで、インテント ロックは常に存在します。この種類のロックは、トランザクションによるデータへのアクセス シーケンスの調整に役立つため、デッドロックの問題を回避するために使用できます。銀行口座システムのシナリオでは、ユーザーが口座に入金または送金しようとする場合、口座を変更することを示す挿入インテント ロックを要求します。他のユーザーは引き続きクエリと操作を行うことができますが、ユーザーが操作を完了してインテント ロックを解放するまで、アカウントの前後に操作を挿入することはできません。

大規模なテーブルの最適化
1. まず第一に、それは限られたデータ範囲のクエリにすぎません
2. 次に、データベースの読み取りと書き込みを分離し、メイン ライブラリが書き込みを担当し、スレーブ ライブラリが読み取りを担当します。
3. 垂直パーティションは、テーブルの列の分割に従って、多くの列を含むテーブルを複数のテーブルに分割します。
4. 水平パーティショニングでは、データ テーブルの構造は変更されずに維持され、いくつかの戦略を使用してデータ フラグメントを格納するため、各データが異なるテーブルまたはライブラリに分散され、それによって分散の目的が達成されます。水平パーティショニングは非常に大規模なデータをサポートできます。データ量
サブデータベースサブテーブルの後のID主キーを処理するにはどうすればよいですか?
1. 複数のテーブルに分割した後、各テーブルが 1 から累積されるため、いくつかの問題が発生するため、サポートするにはグローバルに一意の ID が必要です。
2. ID 主キーの処理方法は一般に次のとおりです: a. データベースの自己インクリメント ID; b. Redis を使用して ID を生成します
MySQL での SQL ステートメントの実行方法
1. 字句アナライザー: SQL 文字列をキーワード、テーブル名、列名などの個々のトークン (トークン) に分割します。
2. 文法アナライザ: SQL 文字列が文法規則に従って文法構造に適合しているかどうかをチェックし、解析木を生成します。
3. オプティマイザー: クエリを最適化し、最適な実行プランを選択します。オプティマイザーは、さまざまな最適化戦略 (インデックスの使用、テーブルの接続順序、WHERE 条件の書き換えなど) を検討します。
4. エグゼキュータ: オプティマイザによって生成された実行プランに従ってクエリ ステートメントを実行します。エグゼキュータは、各行のクエリに一致するデータを読み取り、処理して結果を返します。
5. 結果セットを返す: エグゼキュータは結果セットをクライアントに返します。

おすすめ

転載: blog.csdn.net/weixin_64625868/article/details/130997585