ホームページ  >  記事  >  バックエンド開発  >  Greenplum によるテーブルの作成 -- 分散キー_PHP チュートリアル

Greenplum によるテーブルの作成 -- 分散キー_PHP チュートリアル

PHP中文网
PHP中文网オリジナル
2016-07-12 09:00:041665ブラウズ

Greenplum はテーブルを作成します - 分散キー

Greenplum は、テーブルを作成するときに分散キーを指定する必要があります (テーブルを作成するには CREATEDBA 権限が必要です)。その目的は、データを均等に分散することです。各セグメント。分散キーの選択は非常に重要です。間違ったキーを選択すると、データが一意でなくなり、さらに深刻な場合、SQL パフォーマンスが大幅に低下します。


Greenplum には 2 つの分散戦略があります:

1.

Greenplum はデフォルトでハッシュ分散戦略を使用します。この戦略では、分散キー (略して DK) として 1 つ以上の列を選択できます。分散キーはハッシュ アルゴリズムを使用して、データが対応するセグメントに格納されていることを確認します。同じ分散キー値は同じセグメントにハッシュされます。データが各セグメントに均等に分散されないように、テーブルに一意のキーまたは主キーを設定することが最善です。 Grammar、によって配布されました。

主キーまたは一意キーがない場合、デフォルトで最初の列が分散キーとして選択されます。主キーを追加します



2.

データはランダムにセグメントに分割され、同じレコードが異なるセグメントに保存される場合があります。ランダム分散によりデータが均一であることが保証されますが、Greenplum にはノード間でデータを制約する一意のキーがないため、データが一意であることは保証できません。一意性とパフォーマンスの考慮事項に基づいて、ハッシュ分散を使用することをお勧めします。パフォーマンスの部分については、別のドキュメントで詳しく紹介します。文法、ランダムに配布。

1. ハッシュ分散キー

分散列または分散タイプを指定せずにテーブルを作成します。 ハッシュ分散テーブルはデフォルトで作成され、最初の列 ID フィールドが分​​散キーとして使用されます。

testDB=# create table t_hash(id int,name varchar(50)) distributed by (id);
CREATE TABLE
testDB=# 
 
testDB=# \d t_hash
           Table "public.t_hash"
 Column |         Type          | Modifiers 
--------+-----------------------+-----------
 id     | integer               | 
 name   | character varying(50) | 
Distributed by: (id)

主キーを追加すると、主キーは ID 列ではなく分散キーにアップグレードされます。

testDB=# alter table t_hash add primary key (name);
NOTICE:  updating distribution policy to match new primary key
NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "t_hash_pkey" for table "t_hash"
 
ALTER TABLE
testDB=# \d t_hash
           Table "public.t_hash"
 Column |         Type          | Modifiers 
--------+-----------------------+-----------
 id     | integer               | 
 name   | character varying(50) | not null
Indexes:
    "t_hash_pkey" PRIMARY KEY, btree (name)
Distributed by: (name)

ハッシュ分散テーブルが主キーまたは一意のキー値の一意性を実現できることを確認します

testDB=# insert into t_hash values(1,'szlsd1');
INSERT 0 1
testDB=#
testDB=# insert into t_hash values(2,'szlsd1');
ERROR:  duplicate key violates unique constraint "t_hash_pkey"(seg2 gp-s3:40000 pid=3855)

さらに、主キー列には引き続き一意のキーを作成できます

testDB=# create unique index u_id on t_hash(name);
CREATE INDEX
testDB=#
testDB=#
testDB=# \d t_hash
           Table "public.t_hash"
 Column |         Type          | Modifiers
--------+-----------------------+-----------
 id     | integer               |
 name   | character varying(50) | not null
Indexes:
    "t_hash_pkey" PRIMARY KEY, btree (name)
    "u_id" UNIQUE, btree (name)
Distributed by: (name)

ただし、非主キー列は一意のインデックスを単独で作成することはできません。作成したい場合は、複数の分散キー列を含める必要があります

testDB=#  create unique index uk_id on t_hash(id);
ERROR:  UNIQUE index must contain all columns in the distribution key of relation "t_hash"
testDB=#  create unique index uk_id on t_hash(id,name);
CREATE INDEX
testDB=# \d t_hash
           Table "public.t_hash"
 Column |         Type          | Modifiers
--------+-----------------------+-----------
 id     | integer               |
 name   | character varying(50) | not null
Indexes:
    "t_hash_pkey" PRIMARY KEY, btree (name)
    "uk_id" UNIQUE, btree (id, name)
Distributed by: (name)

主キーを削除した後、元のハッシュ分散キーは変更されません。

testDB=# alter table t_hash drop constraint t_hash_pkey;
ALTER TABLE
testDB=# \d t_hash
           Table "public.t_hash"
 Column |         Type          | Modifiers
--------+-----------------------+-----------
 id     | integer               |
 name   | character varying(50) | not null
Distributed by: (name)

分散キーが主キーでも一意キーでもない場合、セグメント内に分散キーの同じ値が含まれていることを確認してみましょう。

次の実験では、名前列が分散キーであり、同じ名前の値を挿入すると、7 つのレコードがすべてセグメント ノード 2 に分類されることがわかります。

testDB=#  insert into t_hash values(1,'szlsd');
INSERT 0 1
testDB=#  insert into t_hash values(2,'szlsd');
INSERT 0 1
testDB=#  insert into t_hash values(3,'szlsd');
INSERT 0 1
testDB=#  insert into t_hash values(4,'szlsd');
INSERT 0 1
testDB=#  insert into t_hash values(5,'szlsd');
INSERT 0 1
testDB=#  insert into t_hash values(6,'szlsd');
INSERT 0 1
testDB=#
testDB=#
testDB=# select gp_segment_id,count(*) from t_hash group by gp_segment_id; 
 gp_segment_id | count
---------------+-------
             2 |     7
(1 row)

2. ランダム分散キー

ランダム分散テーブルを作成するには、distributed Random キーワードを追加する必要があります。どの列を分散キーとして使用するかは不明です。

testDB=# create table t_random(id int ,name varchar(100)) distributed randomly;
CREATE TABLE
testDB=#
testDB=#
testDB=# \d t_random
           Table "public.t_random"
 Column |          Type          | Modifiers
--------+------------------------+-----------
 id     | integer                |
 name   | character varying(100) |
Distributed randomly

主キー/一意キーの一意性を検証すると、ランダム分布表では主キーと一意キーを作成できないことがわかります

testDB=# alter table t_random add primary key (id,name);
ERROR:  PRIMARY KEY and DISTRIBUTED RANDOMLY are incompatible
testDB=#
testDB=# create unique index uk_r_id on t_random(id);
ERROR:  UNIQUE and DISTRIBUTED RANDOMLY are incompatible
testDB=#

データの一意性が確保できないことが実験からわかります。また、ポーリング挿入ではなく、ランダムに分散したテーブルにデータを挿入します。実験ではセグメントが3つありますが、1番に3レコード、2番に2レコードを挿入し、その後にデータを挿入しています。セグメント番号0。ランダムに分散されたテーブルがどのようにして均一なデータ分散を実現するのかは不明です。この実験では、ランダム分布表の同じ値が異なるセグメントに分布するという結論も検証されました。

testDB=# insert into t_random values(1,'szlsd3');
INSERT 0 1
testDB=# select gp_segment_id,count(*) from t_random group by gp_segment_id;
 gp_segment_id | count
---------------+-------
             1 |     1
(1 row)
 
testDB=#
testDB=# insert into t_random values(1,'szlsd3');
INSERT 0 1
testDB=# select gp_segment_id,count(*) from t_random group by gp_segment_id;
 gp_segment_id | count
---------------+-------
             2 |     1
             1 |     1
(2 rows)
 
testDB=# insert into t_random values(1,'szlsd3');
INSERT 0 1
testDB=# select gp_segment_id,count(*) from t_random group by gp_segment_id;
 gp_segment_id | count
---------------+-------
             2 |     1
             1 |     2
(2 rows)
 
testDB=# insert into t_random values(1,'szlsd3');
INSERT 0 1
testDB=# select gp_segment_id,count(*) from t_random group by gp_segment_id;
 gp_segment_id | count
---------------+-------
             2 |     2
             1 |     2
(2 rows)
 
testDB=# insert into t_random values(1,'szlsd3');
INSERT 0 1
testDB=# select gp_segment_id,count(*) from t_random group by gp_segment_id;
 gp_segment_id | count
---------------+-------
             2 |     2
             1 |     3
(2 rows)
 
testDB=# insert into t_random values(1,'szlsd3');
INSERT 0 1
testDB=# select gp_segment_id,count(*) from t_random group by gp_segment_id;
 gp_segment_id | count
---------------+-------
             2 |     2
             1 |     3
             0 |     1
(3 rows)

3. CTAS は元のテーブルの分散キーを継承します

Greenplum には 2 つの CTAS 構文がありますが、どちらの構文であっても、デフォルトでは元のテーブルの分散キーが継承されます。ただし、主キー、一意キー、APPENDONLY、COMPRESSTYPE (圧縮) など、テーブルの一部の特殊な属性は継承されません。

testDB=# \d t_hash;
           Table "public.t_hash"
 Column |         Type          | Modifiers
--------+-----------------------+-----------
 id     | integer               |
 name   | character varying(50) | not null
Indexes:
    "t_hash_pkey" PRIMARY KEY, btree (name)
    "uk_id" UNIQUE, btree (id, name)
Distributed by: (name)
 
testDB=#
testDB=#
testDB=# create table t_hash_1 as select * from t_hash;
NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'name' as the Greenplum 
Database data distribution key for this table.
HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the 
optimal data distribution key to minimize skew.
SELECT 0
testDB=# \d t_hash_1
          Table "public.t_hash_1"
 Column |         Type          | Modifiers
--------+-----------------------+-----------
 id     | integer               |
 name   | character varying(50) |
Distributed by: (name)
 
testDB=#
testDB=# create table t_hash_2 (like t_hash);
NOTICE:  Table doesn't have 'distributed by' clause, defaulting to distribution columns from LIKE table
CREATE TABLE
testDB=# \d t_hash_2
          Table "public.t_hash_2"
 Column |         Type          | Modifiers
--------+-----------------------+-----------
 id     | integer               |
 name   | character varying(50) | not null
Distributed by: (name)

CTAS が分散キーを変更するテーブルを作成する場合は、distributed by を追加するだけです。

testDB=# create table t_hash_3 as select * from t_hash distributed by (id);
SELECT 0
testDB=#
testDB=# \d t_hash_3
          Table "public.t_hash_3"
 Column |         Type          | Modifiers
--------+-----------------------+-----------
 id     | integer               |
 name   | character varying(50) |
Distributed by: (id)
 
testDB=#
testDB=#
testDB=# create table t_hash_4 (like t_hash) distributed by (id);
CREATE TABLE
testDB=#
testDB=# \d t_hash4
Did not find any relation named "t_hash4".
testDB=# \d t_hash_4
          Table "public.t_hash_4"
 Column |         Type          | Modifiers
--------+-----------------------+-----------
 id     | integer               |
 name   | character varying(50) | not null
Distributed by: (id)

CTAS を使用する場合は、ランダムに分散されたキーに特別な注意を払う必要があり、ランダムに分散されたキーを追加する必要があります。そうしないと、元のテーブルにはハッシュ分散キーが含まれ、新しい CTAS テーブルにはランダムに分散されたキーが含まれます。

testDB=# \d t_random
           Table "public.t_random"
 Column |          Type          | Modifiers
--------+------------------------+-----------
 id     | integer                |
 name   | character varying(100) |
Distributed randomly
 
testDB=#
testDB=# \d t_random_1
          Table "public.t_random_1"
 Column |          Type          | Modifiers
--------+------------------------+-----------
 id     | integer                |
 name   | character varying(100) |
Distributed by: (id)
testDB=# create table t_random_2 as select * from t_random distributed randomly;
SELECT 7
testDB=#
testDB=# \d t_random_2
          Table "public.t_random_2"
 Column |          Type          | Modifiers
--------+------------------------+-----------
 id     | integer                |
 name   | character varying(100) |
Distributed randomly

参考:

「Greenplum エンタープライズ アプリケーションの実践」

「Greenplum 4.2.2 管理者ガイド」

上記は、Greenplum 作成テーブル - 配布キー_PHP チュートリアルの内容です。その他の関連コンテンツについては、注意してください。 PHP 中国語 Web サイト (www.php.cn)!


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。