ディープコピーを実行する
ディープコピーでは、テーブルを自動的にソートする一括挿入を利用してテーブルを再作成し、データを入力します。テーブルにソートされていない大規模なリージョンがある場合、ディープコピーの方がバキューム処理より高速です。ディープコピーオペレーション中の同時更新は、追跡可能な場合にのみ行うことをお勧めします。プロセスが完了したら、差分更新を新しいテーブルに移動します。VACUUM オペレーションは同時更新を自動でサポートします。
4 つの方法の 1 つを選択し、元のテーブルのコピーを作成できます:
-
元のテーブル DDL を使用します。
CREATE TABLE DDL が利用できる場合、これが最も速く推奨の方法になります。新しいテーブルを作成する場合は、プライマリキーと外部キーを含むすべてのテーブルと列の属性を指定できます。SHOW TABLE 関数を使用すると、元の DDL を検索できます。
-
CREATE TABLE LIKE を使用します。
元の DDL が利用できない場合、CREATE TABLE LIKE を使用して元のテーブルを再作成できます。新しいテーブルは親テーブルのエンコーディング、分散キー、ソートキー、非 null の属性を継承します。新しいテーブルは親テーブルのプライマリキーと外部キーの属性を継承しませんが、ALTER TABLE を使ってそれらを追加できます。
-
一時テーブルを作成し、元のテーブルの全データを削除します。
親テーブルのプライマリキーおよび外部キーの属性を保持する必要がある場合。親テーブルに依存関係がある場合は、CREATE TABLE... を使用できます。AS (CTAS) を使って一時テーブルを作成します。次に、元のテーブルの全データを削除してから、一時テーブルのデータを入力します。
一時テーブルを使用すると、永続テーブルを使用する場合と比較して著しくパフォーマンスが向上しますが、データを失うリスクがあります。一時テーブルは、作成したセッションの終了時に自動的に削除されます。TRUNCATE を使うと、トランザクションブロック内にある場合でも、即座にコミットされます。TRUNCATE が成功しても後続の INSERT が完了する前にシャットダウンした場合、データが失われます。データ損失を許容できない場合は、永続テーブルを使用します。
テーブルのコピーを作成した後、新しいテーブルへのアクセスを許可する必要がある場合があります。GRANT を使用してアクセス権限を定義できます。テーブルのすべてのアクセス権限を表示および付与するには、次のいずれかに該当する必要があります。
-
スーパーユーザー。
-
コピーするテーブルの所有者。
-
テーブルの権限を確認するための ACCESS SYSTEM TABLE 権限と、関連するすべての権限の付与権限を持つユーザー。
さらに、ディープコピーが格納されているスキーマの使用権限を付与する必要がある場合があります。ディープコピーのスキーマが元のテーブルのスキーマと異なり、また public
スキーマでもない場合は、使用権限を付与する必要があります。使用権限を表示および付与するには、次のいずれかに該当する必要があります。
-
スーパーユーザー。
-
ディープコピーのスキーマに対する USAGE 権限を付与できるユーザー。
元のテーブル DDL を使用してディープコピーを実行するには、次のように実行します。
-
(オプション)
v_generate_tbl_ddl
というスクリプトを実行してテーブル DDL を再作成します。 -
元の CREATE TABLE DDL を使い、テーブルのコピーを作成します。
-
INSERT INTO … SELECT ステートメントを使い、元のテーブルのデータをコピーに入力します。
-
古いテーブルに付与されている権限を確認してください。これらの権限は、SVV_RELATION_PRIVILEGES システムビューで確認できます。
-
必要に応じて、古いテーブルの権限を新しいテーブルに付与します。
-
元のテーブルで権限を持つすべてのグループとユーザーに使用権限を付与します。ディープコピーテーブルが
public
スキーマ内にある場合、または元のテーブルと同じスキーマにある場合は、この手順は必要ありません。 -
元のテーブルを削除 (Drop) します。
-
ALTER TABLE ステートメントを使用し、コピーの名前を元のテーブル名に変更します。
次の例では、sample_copy という名前の SAMPLE の複製を利用し、SAMPLE テーブルにディープコピーを実行します。
--Create a copy of the original table in the sample_namespace namespace using the original CREATE TABLE DDL. create table
sample_namespace
.sample_copy ( … ); --Populate the copy with data from the original table in the public namespace. insert into sample_namespace.sample_copy (select * frompublic
.sample); --Check SVV_RELATION_PRIVILEGES for the original table's privileges. select * from svv_relation_privileges where namespace_name = 'public' and relation_name = 'sample' order by identity_type, identity_id, privilege_type; --Grant the original table's privileges to the copy table. grant DELETE on table sample_namespace.sample_copy to groupgroup1
; grant INSERT, UPDATE on table sample_namespace.sample_copy to groupgroup2
; grant SELECT on table sample_namespace.sample_copy touser1
; grant INSERT, SELECT, UPDATE on table sample_namespace.sample_copy touser2
; --Grant usage permission to every group and user that has privileges in the original table. grant USAGE on schema sample_namespace to group group1, group group2, user1, user2; --Drop the original table. drop table public.sample; --Rename the copy table to match the original table's name. alter table sample_namespace.sample_copy rename to sample;
CREATE TABLE LIKE を使用してディープコピーを実行するには、次のように実行します。
-
CREATE TABLE LIKE を使用して新しいテーブルを作成します。
-
INSERT INTO … SELECT ステートメントを使用し、現在のテーブルから新しいテーブルに行をコピーします。
-
古いテーブルに付与されている権限を確認してください。これらの権限は、SVV_RELATION_PRIVILEGES システムビューで確認できます。
-
必要に応じて、古いテーブルの権限を新しいテーブルに付与します。
-
元のテーブルで権限を持つすべてのグループとユーザーに使用権限を付与します。ディープコピーテーブルが
public
スキーマ内にある場合、または元のテーブルと同じスキーマにある場合は、この手順は必要ありません。 -
現在のテーブルを削除 (Drop) します。
-
ALTER TABLE ステートメントを使用し、新しいテーブルの名前を元のテーブル名に変更します。
次の例では、CREATE TABLE LIKE を使用して SAMPLE テーブルにディープコピーを実行します。
--Create a copy of the original table in the sample_namespace namespace using CREATE TABLE LIKE. create table
sameple_namespace
.sample_copy (likepublic
.sample); --Populate the copy with data from the original table. insert into sample_namespace.sample_copy (select * from public.sample); --Check SVV_RELATION_PRIVILEGES for the original table's privileges. select * from svv_relation_privileges where namespace_name = 'public' and relation_name = 'sample' order by identity_type, identity_id, privilege_type; --Grant the original table's privileges to the copy table. grant DELETE on table sample_namespace.sample_copy to groupgroup1
; grant INSERT, UPDATE on table sample_namespace.sample_copy to groupgroup2
; grant SELECT on table sample_namespace.sample_copy touser1
; grant INSERT, SELECT, UPDATE on table sample_namespace.sample_copy touser2
; --Grant usage permission to every group and user that has privileges in the original table. grant USAGE on schema sample_namespace to group group1, group group2, user1, user2; --Drop the original table. drop table public.sample; --Rename the copy table to match the original table's name. alter table sample_namespace.sample_copy rename to sample;
一時テーブルを作成し、元のテーブルの全データを削除する方法でディープコピーを実行するには、次のように実行します。
-
CREATE TABLE AS を使用し、元のテーブルの行を使用して一時テーブルを作成します。
-
現在のテーブルの全データを削除します。
-
INSERT INTO … SELECT ステートメントを使用し、一時テーブルから元のテーブルに行をコピーします。
-
一時テーブルを削除 (Drop) します。
次の例では、一時テーブルを作成し、元のテーブルの全データを削除することによって、SALES テーブルにディープコピーが実行されます。元のテーブルはそのまま残っているため、コピーテーブルにアクセス権限を付与する必要はありません。
--Create a temp table copy using CREATE TABLE AS. create temp table salestemp as select * from sales; --Truncate the original table. truncate sales; --Copy the rows from the temporary table to the original table. insert into sales (select * from salestemp); --Drop the temporary table. drop table salestemp;