記事ノートからの主な引用:
リレーショナル データベースと非リレーショナル データベースの違いについてどれくらい知っていますか?
- リレーショナル データベースの利点
- わかりやすい。リレーショナル モデルを使用してデータを整理するためです。
- データの整合性を保つことができます。
- データ更新のオーバーヘッドは比較的小さいです。
- 複雑なクエリ(where 句を含むクエリ)をサポートします。
- 非リレーショナル データベースの利点
- SQL層で解析する必要がなく、読み書き効率が高い。
- キーと値のペアに基づいて、データは非常にスケーラブルです。
- 写真や文書など、さまざまな種類のデータの保存をサポートできます。
非リレーショナル データベースとは何ですか?
非リレーショナル データベースは NOSQL とも呼ばれ、キーと値のペアの形式で保存されます。
読み書き性能が高く、拡張が容易で、Redis、Mongodb、HBaseなどのインメモリデータベースとドキュメントデータベースに分けられます。
非リレーショナル データベースの使用に適したシナリオ:
- ロギングシステム
- 地理位置情報ストレージ
- 膨大な量のデータ
- 高可用性
MySQL が SQL を実行する方法について話しましょう? 具体的な手順は何ですか?
サーバー層が SQL を順番に実行する手順は次のとおりです。
- クライアントのリクエスト ->
- コネクタ (ユーザー ID の検証、権限の付与) ->
- キャッシュのクエリ (キャッシュが存在する場合は直接戻り、キャッシュが存在しない場合は後続の操作を実行) ->
- アナライザー(字句解析(構文ツリーの構築)およびSQLの構文解析操作) ->
- プリプロセッサ ( SQL クエリ ステートメント内のテーブルまたはフィールドが存在するかどうかを確認します。シンボルをテーブル上のすべての列に展開します。) -
select *
>*
- オプティマイザー(主にSQLの最適化を実行するための最適な実行計画方法を選択します) ->
- Executor (実行時に、最初にユーザーに実行権限があるかどうかを確認し、その後、このエンジンが提供するインターフェイスを使用します) ->
- エンジン層に移動してデータの戻り値を取得します (クエリのキャッシュが有効になっている場合、クエリの結果はキャッシュされます)
MySQLの内部構造を理解していますか?一般的にはどの 2 つの部分に分けることができますか?
これは、サーバー層とストレージ エンジン層の 2 つの部分に分けることができます。そのうちの 1 つは次のとおりです。
サーバー層には、コネクタ、クエリ キャッシュ、パーサー、プリプロセッサ、オプティマイザ、エグゼキュータなどが含まれており、 MySQL のコア サービス機能のほとんどと、すべての組み込み関数 (日付、時刻、数学関数、暗号化関数など) をカバーします。 ).ストアド プロシージャ、トリガー、ビューなど、すべてのクロスストレージ エンジン機能がこのレイヤーに実装されます。
ストレージ エンジン層は、データの保存と取得を担当します。そのアーキテクチャ モデルはプラグインであり、InnoDB、MyISAM、Memory などの複数のストレージ エンジンをサポートします。現在最も一般的に使用されているストレージ エンジンは InnoDB で、MySQL 5.5.5 以降、デフォルトのストレージ エンジンとなっています。
MySQLの最適化についてご存知ですか? パフォーマンスの最適化が達成できる側面について教えてください。
- 検索フィールドのインデックスを作成する
- Select * の使用を避け、クエリが必要なフィールドをリストします。
- 縦分割テーブル
- 適切なストレージ エンジンを選択する
ビューについて聞いたことがありますか? カーソルはどうでしょうか?
ビューは、SQL ステートメントの結果セットに基づく視覚的なテーブルです。
カーソルは、ユーザーが SQL ステートメントの実行結果を格納するためにシステムによって開かれるデータ バッファーです。各カーソル領域には名前があり、ユーザーは SQL ステートメントを使用してカーソルからレコードを 1 つずつ取得し、それらをメイン変数に割り当てて、メイン言語でさらに処理することができます。
ビューの役割は何ですか? 変更できますか?
ビューは仮想テーブルです。データを含むテーブルとは異なり、ビューには使用時にデータを動的に取得するクエリのみが含まれ、列やデータは含まれません。ビューを使用すると、複雑な SQL 操作を簡素化し、特定の詳細を非表示にし、データを保護できます。ビューを作成すると、テーブルと同じように使用できます。
ビューにインデックスを付けることも、トリガーやデフォルト値を関連付けることもできません。ビュー自体に order by がある場合、ビュー上の order by が再度上書きされます。
ビューの作成: ビュー xxx を xxxx として作成します
結合サブクエリのグループ化集計関数を使用しない Distinct Union などの一部のビューは更新できます。ビューを更新するとベース テーブルが更新されます。ただし、ビューは主に取得を簡素化し、データを保護するために使用され、データを保護するものではありません。更新に使用され、ほとんどのビューは更新できません。
MySQL の一般的なストレージ エンジンである InnoDB と MyISAM の違いは何ですか? 該当するシナリオは何ですか?
1) トランザクション: MyISAM はサポートしていませんが、InnoDB はサポートしています 2) ロック レベル: MyISAM テーブル レベル ロック、InnoDB 行レベル ロックおよび外部キー制約 3) MyISAM はテーブル内の総行数を保存しますが、InnoDB はサポートしません行の合計数を格納する; 4) MyISAM は非クラスター化インデックスを使用し、B+ ツリーはデータ ファイルへのストア ポインターを残します。InnoDB のプライマリ キー インデックスはクラスター化インデックスを使用し、B+ ツリーはストア データを残します; 5) バックアップ: InnoDB はオンライン ホット バックアップをサポートしており、一貫したビューを取得するために、すべてのテーブルへの書き込みを停止する必要はありません。MyISAM はサポートしていません。
適用可能なシナリオ: MyISAM は次の場合に適しています: 挿入がまれで、クエリが非常に頻繁に実行され、多数の SELECT が実行される場合は、MyISAM の方が良い選択肢であり、トランザクションがない。InnoDB は次のような場合に適しています: 信頼性要件が比較的高い、またはトランザクションが必要である; テーブルの更新とクエリが非常に頻繁であり、大量の INSERT または UPDATE
データベース構造の最適化についてどのような方法を知っていますか?
- パラダイムの最適化: 冗長性の排除 (スペースの節約など)
- アンチパラダイム最適化: 適切な冗長性の追加 (結合の削減) など
- データの範囲を制限する: データの範囲を制限する条件のないクエリ ステートメントは必ず禁止してください。たとえば、ユーザーが注文履歴をクエリする場合、1 か月以内に管理できます。
- 読み取り/書き込み分離: 古典的なデータベース分割スキーム。マスター データベースは書き込みを担当し、スレーブ データベースは読み取りを担当します。
- 分割テーブル: パーティションはデータを物理的に分離し、異なるパーティション内のデータを異なるディスク上のデータ ファイルに保存できます。このようにして、このテーブルをクエリするとき、テーブル全体をスキャンするのではなく、テーブル パーティションをスキャンするだけで済み、クエリ時間が大幅に短縮されます。また、異なるディスク上のパーティションにより、このテーブルのデータ送信も異なるディスクに分散されます。ディスク I/O、慎重に構成されたパーティションにより、ディスク I/O のデータ転送競合が均等に分散されます。この方法は、大量のデータを含む timetable に使用できます。テーブル パーティションは月ごとに自動的に作成できます。
データベースをデータベースとテーブルに分割する必要があるのはなぜですか? それらをすべて 1 つのライブラリまたは 1 つのテーブルに配置することはできませんか?
データベースとテーブルをシャーディングする目的は、データベース上の単一データベースと単一テーブルの負担を軽減し、クエリのパフォーマンスを向上させ、クエリ時間を短縮することです。
テーブルを分割することにより、データベース上の 1 つのテーブルの負担が軽減されると同時に、異なるテーブルのデータ量が削減されるため、クエリのパフォーマンスが向上します。さらに、テーブルロックの問題も大幅に軽減できます。テーブル分割戦略は、垂直分割と水平分割として要約できます。 水平テーブル分割: モジュラー テーブル分割はランダム テーブル分割に属し、時間ディメンション テーブル分割は連続テーブル分割に属します。垂直分割の設計方法、私の提案:使用頻度の低いフィールドを別の拡張テーブルに分割します。大きなテキストを含むフィールドを別の拡張テーブルに個別に分割し、頻繁に変更されないフィールドを同じテーブルに配置します。1 つのテーブルで、頻繁に変更されるフィールドを別のテーブルに配置します。多数のユーザーがいるシナリオでは、モジュラスを取得してテーブルを分割することを検討できます。データは比較的均一になり、ホット スポットや同時アクセスのボトルネックは発生しにくくなります。
データベース内でテーブルを分割すると、単一テーブル内のデータが大きすぎる問題が解決されるだけですが、単一テーブル内のデータが異なる物理マシンに分散されるわけではないため、MySQL サーバーの負荷は軽減されません。同じ物理マシン上のリソースの競合や、CPU、メモリ、ディスク IO、ネットワーク帯域幅などのボトルネック。
シャーディングとシャーディングによって引き起こされる分散ジレンマと対策 データの移行と拡張の問題 - 一般的なアプローチは、最初にプログラムを通じてデータを読み取り、次に指定されたシャーディング戦略に従ってデータを各シャーディング テーブルに書き込むことです。ページネーションとソートの問題 - データはソートされて別のサブテーブルに返される必要があり、別のサブテーブルから返された結果セットは要約されて再度ソートされ、最終的にユーザーに返されます。
データベースの最適化で最も一般的な方法の 1 つは、データ テーブルを分割することです。データ テーブルの分割について何を知っていますか?
分割は実際には垂直分割と水平分割に分けられます。
ケース: 単純なショッピング システムには一時的に次のテーブルが含まれます。
1. 製品表(データ量10w、安定)
2. 注文テーブル(データ量:200万件、増加傾向)
3. ユーザーテーブル(データ量:100万、増加傾向)
MySQL を例に水平分割と垂直分割を説明します。MySQL が許容できる規模は、数百万から数千万の静的データの範囲です。
縦に分割
問題の解決: テーブル間の IO 競合
問題は解決していない: 単一テーブル内のデータ量の増加によるプレッシャー
解決策: 製品テーブルとユーザー テーブルを 1 つのサーバーに配置し、注文テーブルを別のサーバーに配置します。
水平に分割
問題の解決: 単一テーブル内のデータ量の増大によるプレッシャー
問題は解決されません: テーブル間の IO 競合
解決策:ユーザー テーブル は性別ごとに男性ユーザー テーブルと女性ユーザー テーブルに分割され、注文テーブルは 完了と完了ごとに完了注文と未完了注文に分割され、製品テーブルと 未完了注文はサーバー上に配置され、完成した注文テーブルは、男性ユーザーのテーブルを 1 つのサーバーに置き、女性ユーザーのテーブルを別のサーバーに置きます (女性は買い物が大好きです (笑))。
シナリオの質問: あなたの会社がデータ ストレージに MySQL データベースを選択し、1 日あたり 50,000 アイテム以上増加し、3 年間の運用と保守が予想される場合、どのような最適化方法がありますか?
- 適切に設計されたデータベース構造により、部分的なデータの冗長性が可能になり、結合クエリが回避されて効率が向上します。
- 適切なテーブル フィールドのデータ型とストレージ エンジンを選択し、インデックスを適切に追加します。
- MySQL データベースのマスターとスレーブの読み取りと書き込みの分離。
- 通常のテーブルを見つけて1 つのテーブル内のデータ量を減らし、クエリ速度を向上させます。
- Memcached、Apc などのキャッシュ メカニズムを追加します。
- 頻繁に変更されないページの場合は、静的ページが生成されます。
- 効率的な SQL を作成します。たとえば、SELECT * FROM TABLE は SELECT field_1, field_2, field_3 FROM TABLE に変更されます。
データベース内の主キー、スーパーキー、候補キー、外部キーとは何ですか? (素晴らしい)
-
スーパー キー:関係内のタプルを一意に識別できる属性のセットは、リレーショナル スキーマのスーパー キーと呼ばれます。
-
候補キー:冗長な属性を含まないスーパーキーは候補キーと呼ばれます。つまり、候補キーの属性を削除すると、キーではなくなります。
-
主キー:タプル識別子としてユーザーが選択した候補キーを主キーといいます。
-
外部キー:リレーショナル スキーマ R の属性 K が別のスキーマの主キーである場合、kはスキーマ R の外部キーと呼ばれます。
例:
学生証 | 名前 | 性別 | 年 | 部門 | 選考科目 |
---|---|---|---|---|---|
20020612 | リー・フイ | 男 | 20 | コンピューター | ソフトウェア開発 |
20060613 | 張明 | 男 | 18 | コンピューター | ソフトウェア開発 |
20060614 | 王暁宇 | 女性 | 19 | 物理 | 力学 |
20060615 | 李書華 | 女性 | 17 | 生物学 | 動物学 |
20060616 | 趙静 | 男 | 21 | 化学薬品 | 食品化学 |
20060617 | 趙静 | 女性 | 20 | 生物学 | 植物学 |
- スーパーキー: この例から、学生 ID が学生エンティティを識別する一意の識別子であることがわかります。このタプルのスーパーキーは学生番号です。さらに、(
学号
、性别
)、 (学号
、年龄
)などの他の属性と組み合わせることもできます。 - 候補キー: 例によれば、学生番号はタプルを一意に識別できる一意の識別子であるため、学生番号が候補キーになります。実際には、候補キーはスーパー キーのサブセットです。たとえば、(学生番号) 、年齢)はスーパーキーですが、候補キーではありません。追加のプロパティがあるためです。
- 主キー: 簡単に言うと、例のタプルの候補キーは学生番号ですが、タプルの一意の識別子として選択すると、学生番号が主キーになります。
- 外部キーは主キーに相対的です。たとえば、学生レコードでは、主キーは学生番号であり、成績証明書テーブルにも学生番号フィールドがあります。したがって、学生番号は、成績証明書テーブルと学生テーブルの主キー。
主キーは候補キーのサブセットであり、候補キーはスーパーキーのサブセットであり、外部キーの決定は主キーに対して相対的に行われます。
データベースの 3 つのパラダイムの詳細な紹介
第一正規形
どのリレーショナル データベースでも、第 1 正規形 (1NF) はリレーショナル モデルの基本要件です。第 1 正規形 (1NF) を満たさないデータベースはリレーショナル データベースではありません。いわゆる第一正規形 (1NF) は、データベース テーブルの各列が分割できない基本データ項目であることを意味します。同じ列に複数の値を含めることはできません。つまり、エンティティ内の属性が複数の値を持つことはできません。または属性が重複しています。
繰り返し属性が表示される場合は、新しいエンティティを定義する必要がある場合があります。新しいエンティティは繰り返し属性で構成されます。新しいエンティティと元のエンティティの間には 1 対多の関係があります。第 1 正規形 (1NF) では、テーブルの各行には 1 つのインスタンスのみに関する情報が含まれます。
つまり、第一正規形は重複のない列です。
第 2 正規形
第 2 正規形 (2NF) は、第 1 正規形 (1NF) に基づいて確立されます。つまり、第 2 正規形 (2NF) を満たすためには、まず第 1 正規形 (1NF) を満たす必要があります。第 2 正規形 (2NF) では、データベース テーブル内の各インスタンスまたは行が一意に区別できる必要があります。
差別化を実現するには、通常、各インスタンスの一意の ID を格納する列をテーブルに追加する必要があります。この一意の属性列は、主キー、主キー、主キーと呼ばれます。第 2 正規形 (2NF) では、エンティティの属性が主キーに完全に依存することが要求されます。
いわゆる完全な依存とは、主キーの一部にのみ依存する属性が存在できないことを意味します。それが存在する場合は、この属性と主キーのこの部分を分離して新しいエンティティを形成する必要があります。新しいエンティティと元のエンティティは 1 対多の関係です。差別化を実現するには、通常、各インスタンスの一意の ID を格納する列をテーブルに追加する必要があります。
つまり、主キーが存在し、主キー以外のフィールドは主キーに依存します。
第 3 正規形
第 3 正規形 (3NF) を満たすには、まず第 2 正規形 (2NF) を満たす必要があります。つまり、第 3 正規形 (3NF) では、データベース テーブルには、他のテーブルに既に含まれている非主キー情報が含まれていないことが必要です。
例えば、部門情報テーブルがあり、各部門には、部門番号(dept_id)、部門名、部門プロフィール等の情報が含まれる。従業員情報テーブルに部門番号がリストされた後は、部門名、部門プロフィール、およびその他の部門関連情報を従業員情報テーブルに追加することはできません。部門情報テーブルが存在しない場合は、第 3 正規形 (3NF) に従って構築する必要があります。そうしないと、データの冗長性が高くなります。
つまり、主キー以外のフィールドは相互に依存できません。
1NF: アトミック性。フィールドを細分化することはできません。細分化しないと、リレーショナル データベースではありません。
2NF: 独自性。表では 1 つのことだけを説明します。
3NF: 各列は主キーと直接の関係があり、推移的な依存関係はありません。
データベースの耐久性はどのように確保されているのでしょうか?
主に Innodb のREDO ログを使用します。前述したように、ログを書き換えると、MySQL はまずディスク上のデータをメモリにロードし、メモリ内のデータを変更してからディスクに書き戻します。このとき突然マシンがクラッシュしてしまうと、メモリ内のデータが失われてしまいます。この問題をどうやって解決すればいいでしょうか?これは簡単で、トランザクションがコミットされる前にデータをディスクに直接書き込むだけです。これを行うことの何が問題ですか?
- ページ内の 1 バイトだけを変更するには、ページ全体をディスクにフラッシュする必要があり、リソースの無駄になります。結局のところ、ページのサイズは 16 kb であり、ページを少し変更しただけで 16 kb のコンテンツがディスクにフラッシュされることになりますが、これは合理的とは思えません。
- 結局のところ、トランザクション内の SQL には複数のデータ ページの変更が含まれる可能性があり、これらのデータ ページは隣接していない可能性があります。つまり、ランダム IO に属している可能性があります。明らかに、ランダム IO の動作は遅くなります。
そこで、上記の問題を解決するために、REDO ログを使用することにしました。データが変更されると、その操作はメモリ内で実行されるだけでなく、REDO ログにも記録されます。トランザクションがコミットされると、REDO ログはフラッシュされます ( REDO ログの一部はメモリ内に、一部はディスク上にあります)。データベースが停止して再起動されると、REDO ログの内容がデータベースに復元され、UNDO ログとbinlogの内容に基づいてデータがロールバックまたは送信されます。
REDO ログを使用する利点は何ですか?
実際、REDO ログのフラッシュはデータ ページのフラッシュよりも効率的であるという利点があり、具体的なパフォーマンスは次のとおりです。
- REDO ログはサイズが小さく、結局どのページが変更されたかを記録するだけであるため、REDO ログのサイズは小さく、高速に更新できます。
- REDO ログは最後に追加され、シーケンシャル IO に属します。効率はランダム IO よりも明らかに高速です。
データベースの同時実行性が高いという問題がよく発生しますが、何か良い解決策はありますか?
- Web サービス フレームワークにキャッシュを追加します。サーバーとデータベース層の間にキャッシュ層を追加して、頻繁にアクセスされるデータをキャッシュに保存し、データベースの読み取り負荷を軽減します。
- データベースのインデックスを増やしてクエリ速度を向上させます。(ただし、インデックスが多すぎると速度が低下し、データベースへの書き込みによってインデックスが更新されるため、これも速度が低下します)
- マスターとスレーブの読み取りと書き込みは分離されているため、マスター サーバーが書き込みを担当し、スレーブ サーバーが読み取りを担当します。
- データベースを分割してデータベース テーブルをできるだけ小さくし、クエリ速度を向上させます。
- 分散アーキテクチャを使用してコンピューティングの圧力を分散します。
MySQL でデータベースとテーブルをパーティション分割した後、各テーブルの ID が一意であることを確認するにはどうすればよいですか?
スノーフレーク アルゴリズムを使用して分散 ID を生成すると、異なるプロセスの主キーが重複しないことと、同じプロセスの主キーの順序性を確保できる 整数が生成されます 。64 bit
スノーフレークアルゴリズム
同じ処理において、まず時間ビットで重複がないことを保証し、時間が同じであればシーケンスビットでそれを保証します。同時に、時間ビットが単調増加するため、各サーバーが一般的に時間同期している場合、生成された主キーは分散環境で一般的に順序付けられていると見なすことができ、インデックス フィールドの挿入効率が保証されます。
ただし、スノーフレーク アルゴリズムには時間に大きく依存するため、マシンの時間がダイヤルバックされると、重複した ID が生成される可能性があるという欠点があります。Meituanが提供するタイムスタンプに依存しない分散IDソリューション Leafを利用できます。