コンテンツにスキップ

RDBMS@DB系ミドルウェア

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. RDBMS (関係DB管理システム) の仕組み

RDBMSの種類

RDBMS RDB
MariaDB MariaDBのDB
MySQL MySQLのDB
PostgreSQL PostgreSQLのDB


アーキテクチャ

RDBMSは、リレーショナルエンジン、DBエンジン (ストレージエンジン) 、から構成される。

DB管理システムの仕組み


02. RDBMS

リレーショナルエンジン

記入中...


DBエンジン (ストレージエンジン)

▼ DBエンジンとは

『ストレージエンジン』ともいう。

RDBMSがDBに対してデータのCRUDの処理を行うために必要なソフトウェアのこと。

▼ DBエンジンの種類

RDMS (例:MySQL、PostgreSQLなど) によって、対応するDBエンジンが異なる。

  • InnoDB
  • Memory
  • CSV


RDB (関係DB)

▼ RDBとは

データ同士がテーブル状に関係を持つデータ格納形式で構成されるのこと。

NoSQLとは異なり、データはストレージに保管する。

▼ テーブル

行列からなるデータのセットのこと。

▼ カラム

テーブルの列データのこと。

▼ レコード

テーブルの行データのこと。


オンディスクDB

RDBは、ストレージにデータを保存する。

ストレージ (例:HDD、SSD) 上にデータを保管するDBを、メモリ上に保管することと比較して、オンディスクDBという。


DBパーティション

▼ DBパーティションとは

DBのテーブルを分割して管理する。

性能の向上のために、DBパーティションを作成する。

分割しても、DBMSクライアントからは単一のテーブルとして扱える。

▼ 水平パーティション (シャーディング)

『シャーディング』ともいう。

テーブルをレコード方向に分割して管理する。

▼ 垂直パーティンション

テーブルをカラム方向に分割して管理する


DBインデックス

▼ DBインデックスとは

テーブルから特定のカラムのみを抜き出し、検索しやすいように並び替え、名前を付けて保管しておいたもの。

性能の向上のために、DBインデックを作成しておく。

DBインデックスとして保管したカラムから特定のレコードを直接的に取得できる。

そのため、SQLの実行時間がカラム数に依存しなくなる。

DBインデックスを使用しない場合、SQLの実行時に全てカラムを取得するため、実行時間がテーブルのカラム数に依存してしまう。

▼ クラスターDBインデックス(自動作成)

プライマリーキーあるいはユニークキーのカラムを基準にして、テーブルのカラムを並び替えたDBインデックスのこと。

DBエンジンが自動で作成してくれる。

CREATE INDEX foo_index
    ON foo_table (id)

▼ セカンダリーDBインデックス(手動作成が必要)

プライマリーキーあるいはユニークキーではないカラムを基準にして、テーブルのカラムを並び替えたDBインデックスのこと。

CREATE INDEX foo_index
    ON foo_table (foo_column)

▼ 複合DBインデックス

複数のカラムを基準にして、テーブルを並び替えたDBインデックスのこと。

対象としたカラムごとに異なる値のレコード数が計測され、この数が少ない (一意の値の多い) カラムが検出される。

そして、カラムのレコードの昇順で並び替えられ、DBインデックスとして保管される。

CREATE INDEX foo_index
    ON foo_table (foo_column, bar_column, ...)

*例*

以下のようなfooテーブルがあり、nameカラムとaddressカラムを基準に並び替えたfoo_indexという複合DBインデックス名を作成する。

CREATE INDEX foo_index
    ON foo_table (name, address)
id name address old
1 Suzuki Tokyo 24
2 Yamada Osaka 18
3 Takahashi Nagoya 18
4 Honda Tokyo 16
5 Endou Tokyo 24

各カラムで値の異なるレコード数が計測され、nameカラムはaddressカラムよりも一意のレコードが多いため、nameカラムの昇順 (アルファベット順) に並び替えられ、DBインデックスとして保管される。

id name address old
5 Endou Tokyo 24
4 Honda Tokyo 18
1 Suzuki Tokyo 24
3 Takahashi Nagoya 18
2 Yamada Osaka 18

▼ DBインデックスのカラム変更

DBインデックスのカラム変更によって、DBインデックスの削除と追加が起こる。

次のようにDBインデックスの追加と削除を別にすれば、負荷を少しでも抑えられる。

実行例

これはSQLを使用した例である。

  1. 新しいDBインデックスを追加するリリース <--- ここで中程度の負荷
CREATE INDEX idx_user_org_name_updated ON User (organization_id, user_name, updated_at DESC, status);
CREATE INDEX idx_user_updated_org ON User (updated_at DESC, organization_id, status);
  1. 一日くらい新旧のDBインデックスを共存させる

  2. 古いDBインデックスを削除するリリース <--- ここで小程度の負荷

DROP INDEX idx_user_org_name_created ON User;
DROP INDEX idx_user_created_org ON User;

実行例

これはORMを使用した例である。

ORMを使用する場合、より簡単にカラムを変更できる。

model User {
    user_id         String   @id @default(cuid()) @db.VarChar(127)
    organization_id String   @db.VarChar(127)
    user_name       String   @db.VarChar(127)
    email           String   @db.VarChar(255)
    status          String   @db.VarChar(31)
    created_at      DateTime @default(now()) @db.DateTime(3)
    updated_at      DateTime @updatedAt @db.DateTime(3)

    // 古いインデックス(created_atを使用) <--- 共存させた後に削除する
    @@index([organization_id, user_name, created_at(sort: Desc), status])
    @@index([created_at(sort: Desc), organization_id, status])

    // 新しいインデックス(updated_atを使用)
    @@index([organization_id, user_name, updated_at(sort: Desc), status])
    @@index([updated_at(sort: Desc), organization_id, status])
}


04. RDBMSクライアント

クエリ

▼ クエリとは

RDBMSの種類に応じたクエリが必要になる。

▼ クエリパッケージ

クエリの実装の抽象度に応じて、パッケージがある。

クエリパッケージ 説明
生のクエリ RDB固有のクエリのこと。
クエリビルダー RDB固有のクエリを実装しやすくしたパッケージのこと。
ORM アプリケーション側にDBテーブルに対応したモデルを定義し、これを使用してRDBに固有のクエリを送信するパッケージのこと。


DB接続

▼ DB接続とは

アプリからRDBMSへのクエリ送信時の通信のこと。

TCP/IPプロトコルを使用する。

▼ DBセッション

ログインに成功したDB接続のこと。

セッションを確立できると、クエリを送信できるようになる。

一つのセッション中に一つのトランザクション (複数のクエリからなる) を実行することになる。

▼ 接続プロキシ

アプリケーションとDBの間に、接続プールプロキシ (例:ProxySQL、PgBouncerなど) を配置する。

これにより、アプリケーションサーバーの接続プールの処理を接続プロキシに委譲する。

注意点として、プリペアードステートメントでは既存の接続を再利用する必要があるが、接続プロキシでは別の接続を使用してしまうことがある。

そのため、接続プロキシの採用時には、プリペアードステートメントを使用できない。

▼ 接続プール

アプリからDBへのクエリ送信時に新しく作成した接続を、非アクティブ状態として保持しておき、以降のクエリ送信時に再利用する。

一定回数再利用されたり、一定期間使用されていない接続は削除される。

db_connection-pool

▼ 接続プールに対する待機キュー

もし接続プール上の接続が全て使用されてしまった場合、いずれかの接続が解放されるまで待機する必要がある。

この時に、送信されたリクエストは待機キューで解放を待つ。


05. 性能指標

秒当たりの平均トランザクション数 (TPS:Transaction Per Second)