💬

【データベース】Scaling Databasesについて

2024/12/22に公開

Scaling Databases

より多くのデータとユーザーを効率的に処理できるようにデータベースを調整するプロセスです。
これは、既存のハードウェアをアップグレードするか、サーバーを追加することで実現されます。
これにより、データベースが成長しても堅牢な資産であり続けることが保証されます。

垂直スケーリング(Vertical Scaling)

サーバーのハードウェア能力を上げることでデータベースのパフォーマンスを向上させる方法です。
具体例としては、現状より高速なCPU、より多くのRAM、より大きなストレージをサーバーに追加することです。
垂直スケーリングの利点は、比較的に簡単に実装できますが、物理的なハードウェアの限界によってスケーリングにも限界があります。

水平スケーリング(Horizontal Scaling)

複数のサーバーにデータベースを分散させることによってパフォーマンスを向上させる方法です。
これには、データのシャーディングやレプリケーションが含まれます。
水平スケーリングの利点は、理論上はスケーリングの限界がほとんどないことですが、実装が複雑になる可能性があります。

Database Indexes

データベース管理システムにおけるデータ検索操作の速度を向上させるデータ構造です。
特定の列または列のセットに基づいて情報を簡単に検索する方法を提供します。

具体例として、インデックスは本でいう索引にあたります。
自分が知りたい項目を索引で探し、何ページかを確認してそのページを開けばそのページに辿り着けるような感じです。

データベースにおいて最も一般的に使用されているインデックスは、B-treeインデックスです。
B-treeインデックスの詳しいことについては、下記の記事を参考にすると良いと思います。
https://qiita.com/kiyodori/items/f66a545a47dc59dd8839

カーディナリティ(Cardinality)

ある列において異なるユニークな値の数のことです。

では具体例を見ていきましょう。

まず、性別を考えます。性別は男と女で2種類です。
よって、カーディナリティは2です。
出身都道府県の場合は47あるので、カーディナリティは47になります。

性別と出身都道府県を比較すると、出身都道府県の方がカーディナリティが高いと言えます。

カーディナリティが高い列ほど、データの重複が少なく、データの検索で該当のデータを絞りやすくなります。

設計指針

大きなテーブルに対して作成する
カーディナリティが高い列に作成する
WHERE句の選択条件、または、結合条件に使用される列に作成

大きなテーブルに対して作成

データ量が少ない場合は、インデックスを使わずにフルスキャンする方が高速です。
データ量が1万レコード以上くらいであれば、インデックスを使用してデータの検索を高速化する必要があります。

カーディナリティが高い列に作成

絞り込み率が 5% 以下の場合は、有効であると言われています。
つまり、カーディナリティが 20 以上の場合は、インデックスが有効に働く可能性が高いということになります。

WHERE句の選択条件、または、結合条件に使用される列に作成

下記の記事を参考にすれば良いと思います。
https://zenn.dev/yuki_tu/articles/c0a11385a33e0c#カーディナリティ

インデックスが使用できる検索方法

インデックスが使用できる検索方法は以下の3つです。

完全一致

SELECT * FROM users WHERE name = '東';

前方一致

SELECT * FROM users WHERE name = '東%';

範囲検索

SELECT * FROM users WHERE age BETWEEN 20 AND 30;

インデックスの作成方法

SQLでインデックスを作成するには、CREATE INDEXを使用します。

CREATE INDEX インデックス名 ON テーブル名(カラム名);

下記は、usersテーブルのname列に対してインデックスを作成します。

CREATE INDEX idx_users_name ON users (name);

インデックスを作成することによって、nameを使った検索の処理が高速化します。

SELECT * FROM users WHERE name = '東';

インデックスの種類

ユニークインデックス

重複を許さないインデックスを作成します。

CREATE UNIQUE INDEX インデックス名 ON テーブル名 (カラム名);

このクエリは、email列にユニーク制約を持つインデックスを作成します。

CREATE UNIQUE INDEX idx_users_email ON users (email);

複合インデックス

複数の列に基づいてインデックスを作成します。
条件の複合クエリを高速化するのに役立ちます。

CREATE INDEX インデックス名 ON テーブル名 (カラム名1, カラム名2);

このクエリは、customer_idとorder_dateの組み合わせに基づいてインデックスを作成します。

CREATE INDEX idx_orders_customer_date ON orders (customer_id, order_date);

フルテキストインデックス

大量のテキスト検索を効率化するインデックスです。

CREATE FULLTEXT INDEX インデックス名 ON テーブル名 (カラム名);
CREATE FULLTEXT INDEX idx_posts_content ON posts (content);

インデックスの削除方法

DROP INDEX インデックス名 ON テーブル名;

DROP INDEX idx_users_name ON users;

Discussion