サブライブラリ、サブテーブルとは何ですか?
データベース シャーディングとテーブル シャーディングは、大規模なデータのストレージとクエリを処理するために使用されるデータベース アーキテクチャ設計方法です。単一データベースのストレージ容量やクエリ パフォーマンスでは需要を満たせない場合、データを複数のデータベース サーバーに分散することでシステムのスケーラビリティとパフォーマンスを向上させることができます。
データベースのシャーディングとテーブルのシャーディングには、通常、データベースのシャーディングとテーブルのシャーディングの 2 つのステップが含まれます。
分館図書館
データベースシャーディングとは、単一のデータベースを一定のルールに従って複数のデータベースに分割し、各データベースにデータの一部を格納できるようにすることを指します。これにより、単一データベース内のデータ量が削減され、クエリ効率が向上します。一般的な倉庫保管方法には、縦型倉庫と横型倉庫があります。
垂直サブデータベースとは、機能モジュールまたは業務領域に応じてデータを複数のデータベースに分割することを指します。たとえば、注文データ、ユーザー データ、製品データを異なるデータベースに保存できます。
水平サブデータベースとは、時間や地理的位置などのデータ特性に従ってデータを複数のデータベースに分割することを指します。たとえば、注文データを月ごとに異なるデータベースに保存できます。
サブテーブル
テーブルパーティショニングとは、1つのテーブルを一定の規則に従って複数のテーブルに分割することを指し、各テーブルにはデータの一部を格納できます。これにより、単一テーブル内のデータ量が削減され、クエリ効率が向上します。一般的なテーブルの分割方法には、テーブルの垂直分割とテーブルの水平分割があります。
テーブルの垂直分割とは、機能モジュールまたは業務領域に応じてテーブルを複数の部分に分割することを指します。たとえば、注文テーブルは、注文ステータスに基づいてセクションに分割できます。
水平テーブル パーティショニングとは、時間や地理的位置などのデータ特性に従ってテーブルを複数の部分に分割することを指します。たとえば、注文テーブルを月ごとに異なるテーブルに保存できます。
PostgreSQL 11 以降、テーブル パーティションには次の 3 種類があります。
1.レンジパーティション
範囲パーティショニングでは、特定の列の値に基づいてテーブルを 1 つ以上のセグメントに分割します。各パーティションのエンドポイント値は、pg_partition_range システム テーブルに保存されます。範囲パーティショニングは、日付列に基づいて日次、月次、年次などのパーティションを自動的に作成するなど、タイムスタンプに基づいた自動パーティショニングをサポートします。
2. リストパーティション
リストパーティショニングでは、特定のカラムの値に従ってテーブルを配列に格納し、各パーティションの値は pg_partition_list システムテーブルに格納されます。リストのパーティション化のサポートは比較的柔軟であり、パーティション値をカスタマイズしたり、パーティション化に事前定義されたリストを使用したりできます。
3. ハッシュ パーティション
ハッシュ パーティションは、特定の列の値に従ってテーブルに対してハッシュ演算を実行し、その結果を異なるパーティションにマッピングします。ハッシュ パーティショニングでは、MD5、SHA1 などの任意のハッシュ関数を使用できます。ハッシュ パーティショニングの利点は、データを均等に分散し、特定のパーティションに過剰なデータを格納することを回避し、クエリの効率を向上できることです。
例
1. メインテーブルを作成する
まず、すべてのサブテーブルの共通フィールドとインデックスを保存するメインテーブルを作成する必要があります。この例では、列 ID、名前、年齢、住所を持つ Customers という名前のテーブルを作成します。
testdb=# CREATE TABLE customers (
id SERIAL PRIMARY KEY,
name VARCHAR(50) NOT NULL,
age INT NOT NULL,
address VARCHAR(100) NOT NULL
);
2. サブテーブルの作成
次に、複数のサブテーブルを作成する必要があります。各サブテーブルには、メイン テーブルのすべてのフィールドと追加の特定のフィールドが含まれます。この例では、age パーティションテーブルを作成します。
user=# create table customers_10 () inherits (customers);
CREATE TABLE
user=# create table customers_20 () inherits (customers);
CREATE TABLE
user=# create table customers_30 () inherits (customers);
CREATE TABLE
user=#
user=# \d
List of relations
Schema | Name | Type | Owner
--------+-----------------------+----------+-------
public | customers | table | user
public | customers_10 | table | user
public | customers_20 | table | user
public | customers_30 | table | user
3. テーブル分割ルールを定義する
PostgreSQLが提供するパーティショニングルール(パーティショニング)機能を使用して、データを異なるパーティションに分散する方法を定義します。この例では、AGE 列をシャーディング ルールとして使用し、データを customer_age シャーディング テーブルに分散します。
まず関数を作成し、年齢 (0, 10)、[10, 20)、[20, ...] を 3 つの異なるテーブルにそれぞれ挿入します。
次に、この関数を顧客に挿入する前に、この関数の実行を開始するトリガーを作成します。
このようにして、customers テーブルにデータを挿入するときに
user=# create or replace function customers_partition_trigger()
returns trigger as $$
begin
if NEW.age < 10 then
insert into customers_10 values (NEW.*);
elseif NEW.age < 20 then
insert into customers_20 values (NEW.*);
else insert into customers_30 values (NEW.*);
end if;
return null;
end;
$$
language plpgsql;
CREATE FUNCTION
user=# create trigger insert_customers_partition_trigger
user-# before insert on customers
user-# for each row execute procedure customers_partition_trigger();
CREATE TRIGGER
4. テーブルにデータを挿入します。ここでのデータは引き続き親テーブルに表示されますが、実際には、親テーブルはパーティション テーブル構造全体の表示としてのみ使用され、実際に挿入されたレコードは子テーブルに保存されます。 。
user=# INSERT INTO customers VALUES (1, 'Alice', 25, 'New York');
INSERT 0 0
user=# INSERT INTO customers VALUES (2, 'Bob', 35, 'San Francisco');
INSERT 0 0
user=# INSERT INTO customers VALUES (3, 'Charlie', 18, 'Chicago');
INSERT 0 0
user=# INSERT INTO customers VALUES (3, 'Charlie', 18, 'Chicago');
INSERT 0 0
user=# select * from customers;
id | name | age | address
----+---------+-----+---------------
3 | Charlie | 18 | Chicago
3 | Charlie | 18 | Chicago
1 | Alice | 25 | New York
2 | Bob | 35 | San Francisco
(4 rows)
user=# select * from customers_10;
id | name | age | address
----+------+-----+---------
(0 rows)
user=# select * from customers_20;
id | name | age | address
----+---------+-----+---------
3 | Charlie | 18 | Chicago
3 | Charlie | 18 | Chicago
(2 rows)
user=# select * from customers_30;
id | name | age | address
----+-------+-----+---------------
1 | Alice | 25 | New York
2 | Bob | 35 | San Francisco
(2 rows)
5. テーブルのパーティション分割制約を設定して、クエリの効率を向上させます。メインテーブルがクエリされると、すべてのサブテーブルがクエリのために直接スキャンされますが、制約が追加されると、プランナは条件に基づいて対応するサブパーティションをクエリできるようになり、クエリが存在する場合にクエリを高速化できます。たくさんのデータ。
user=# alter table customers_10
user-# add constraint customers_10_check_age_key
user-# check (age < 10);
ALTER TABLE
user=# alter table customers_20
user-# add constraint customers_20_check_age_key
user-# check (age < 20);
ALTER TABLE
user=# alter table customers_30
user-# add constraint customers_30_check_age_key
user-# check (age < 30);
ALTER TABLE
長所と短所
サブデータベースとサブテーブルには特定の利点と欠点があります。以下でそれらを確認してみましょう。
アドバンテージ
- システムの拡張性の向上: データを複数のデータベース サーバーに分散して保存することで、システムの拡張性が向上し、ストレージ容量と処理能力の拡張が容易になります。
- システム パフォーマンスの向上: データを分散して複数のデータベース サーバーに保存することで、システム パフォーマンスを向上させ、単一データベースへの負荷を軽減できます。
- データの冗長性を減らす: データを複数のデータベース サーバーに分散して保存することで、データの冗長性を減らし、データ損失のリスクを軽減できます。
欠点がある
- 複雑さ: データベースとテーブルのシャーディングにはデータの分割とメンテナンスが必要であり、システムの複雑さとメンテナンスのコストが増加します。
- データの一貫性: データベースとテーブルのシャーディングによりデータの不整合が生じる可能性があり、データの一貫性を確保するために追加のメカニズムが必要になります。
- トランザクション処理: サブデータベースとサブテーブルはトランザクション処理に影響を与える可能性があり、データベース間のトランザクション処理をサポートするには追加のメカニズムが必要になります。