メインコンテンツまでスキップ

スキーマ変更

ユーザーはAlter table操作を通じてDorisテーブルのスキーマを変更できます。スキーマ変更は主にカラム変更とインデックス変更を含みます。この記事では主にカラム関連のスキーマ変更を紹介します。インデックス関連の変更については、table Indexを参照して、インデックスを変更するさまざまな方法を理解してください。

原理紹介

Dorisは2種類のスキーマ変更操作をサポートしています:軽量スキーマ変更と重量スキーマ変更です。違いは主に実行プロセスの複雑さ、実行速度、リソース消費にあります。

機能軽量スキーマ変更重量スキーマ変更
実行速度秒(ほぼリアルタイム)分、時間、日(テーブル内のデータ量に依存;データが大きいほど、実行が遅くなる)
データ再書き込みが必要なしあり、データファイルの再書き込みを含む
システムパフォーマンスへの影響最小システムパフォーマンスに影響する可能性があり、特にデータ変換中
リソース消費高、データを再編成するための計算リソースを消費し、プロセスに関与するテーブルデータが占有するストレージ容量が倍増する。
操作タイプ値カラムの追加・削除、カラム名変更、VARCHAR長の変更カラムデータ型の変更、プライマリキーの変更、カラム順序の変更など

軽量スキーマ変更

軽量スキーマ変更とは、データの再書き込みを伴わない単純なスキーマ変更操作を指します。これらの操作は通常メタデータレベルで実行され、データファイルへの物理的な変更を伴わずにテーブルのメタデータを変更するだけです。軽量スキーマ変更操作は通常数秒で完了し、システムパフォーマンスに大きな影響を与えません。軽量スキーマ変更には以下が含まれます:

  • 値カラムの追加または削除
  • カラムの名前変更
  • VARCHARカラムの長さの変更(UNIQUEおよびDUPテーブルキーカラムを除く)

重量スキーマ変更

重量スキーマ変更はデータファイルの再書き込みまたは変換を伴い、これらの操作は比較的複雑で、通常DorisのBackend(BE)の支援を必要として実際のデータ変更または再編成を実行します。重量スキーマ変更操作は通常テーブルのデータ構造に深い変更を伴い、ストレージの物理レイアウトに影響する可能性があります。軽量スキーマ変更をサポートしないすべての操作は重量スキーマ変更に該当します:

  • カラムのデータ型の変更
  • カラムの順序の変更

重量操作はデータ変換のためのタスクをバックグラウンドで開始します。バックグラウンドタスクはテーブルの各tabletを変換し、元のデータをtablet単位で新しいデータファイルに再書き込みします。データ変換プロセス中に「ダブルライト」現象が発生する可能性があり、新しいデータが新しいtabletと古いtabletの両方に同時に書き込まれます。データ変換が完了すると、古いtabletは削除され、新しいtabletがそれを置き換えます。

ジョブ管理

ジョブの表示

ユーザーはSHOW ALTER TABLE COLUMNコマンドを通じてスキーマ変更ジョブの進捗を表示できます。このコマンドにより、ユーザーは現在実行中または完了したスキーマ変更ジョブを確認できます。スキーマ変更ジョブがマテリアライズドビューを含む場合、このコマンドは複数行を表示し、各行がマテリアライズドビューに対応します。例は以下の通りです:

mysql > SHOW ALTER TABLE COLUMN\G;
*************************** 1. row ***************************
JobId: 20021
TableName: tbl1
CreateTime: 2019-08-05 23:03:13
FinishTime: 2019-08-05 23:03:42
IndexName: tbl1
IndexId: 20022
OriginIndexId: 20017
SchemaVersion: 2:792557838
TransactionId: 10023
State: FINISHED
Msg:
Progress: NULL
Timeout: 86400
1 row in set (0.00 sec)

ジョブのキャンセル

ジョブステータスがFINISHEDまたはCANCELLEDでない場合、以下のコマンドを使用してスキーマ変更ジョブをキャンセルできます:

CANCEL ALTER TABLE COLUMN FROM tbl_name;

使用例

列名の変更

ALTER TABLE [database.]table RENAME COLUMN old_column_name new_column_name;

具体的な構文については、ALTER TABLE RENAMEを参照してください。

カラムの追加

  • 集約モデルがvalue列を追加する場合、agg_typeを指定する必要があります。

  • 非集約モデル(DUPLICATE KEYなど)がkey列を追加する場合、KEYキーワードを指定する必要があります。

非集約テーブルへのカラムの追加

  1. テーブル作成文
CREATE TABLE IF NOT EXISTS example_db.my_table(
col1 int,
col2 int,
col3 int,
col4 int,
col5 int
) DUPLICATE KEY(col1, col2, col3)
DISTRIBUTED BY RANDOM BUCKETS 10;
  1. example_db.my_tablecol1の後にキー列key_colを追加する
ALTER TABLE example_db.my_table ADD COLUMN key_col INT KEY DEFAULT "0" AFTER col1;
  1. example_db.my_tablecol4の後に値列value_colを追加する
ALTER TABLE example_db.my_table ADD COLUMN value_col INT DEFAULT "0" AFTER col4;

集約テーブルへの列の追加

  1. テーブル作成文
CREATE TABLE IF NOT EXISTS example_db.my_table(
col1 int,
col2 int,
col3 int,
col4 int SUM,
col5 varchar(32) REPLACE DEFAULT "abc"
) AGGREGATE KEY(col1, col2, col3)
DISTRIBUTED BY HASH(col1) BUCKETS 10;
  1. example_db.my_tablecol1の後にキー列key_colを追加する
ALTER TABLE example_db.my_table ADD COLUMN key_col INT DEFAULT "0" AFTER col1;
  1. example_db.my_tablecol4の後にSUM集計タイプの値列value_colを追加する
ALTER TABLE example_db.my_table ADD COLUMN value_col INT SUM DEFAULT "0" AFTER col4;

複数列の追加

  • 集約モデルが値列を追加する場合、agg_typeを指定する必要があります。

  • 集約モデルがキー列を追加する場合、KEYキーワードを指定する必要があります。

集約テーブルへの複数列の追加

  1. テーブル作成文
CREATE TABLE IF NOT EXISTS example_db.my_table(
col1 int,
col2 int,
col3 int,
col4 int SUM,
col5 varchar(32) REPLACE DEFAULT "abc"
) AGGREGATE KEY(col1, col2, col3)
DISTRIBUTED BY HASH(col1) BUCKETS 10;
  1. example_db.my_table(集約モデル)に複数のカラムを追加する
ALTER TABLE example_db.my_table
ADD COLUMN (c1 INT DEFAULT "1", c2 FLOAT SUM DEFAULT "0");

Delete Column

  • パーティションカラムは削除できません。

  • UNIQUE keyカラムは削除できません。

example_db.my_tableからカラムを削除するには

  1. テーブル作成文
CREATE TABLE IF NOT EXISTS example_db.my_table(
col1 int,
col2 int,
col3 int,
col4 int SUM,
col5 varchar(32) REPLACE DEFAULT "abc"
) AGGREGATE KEY(col1, col2, col3)
DISTRIBUTED BY HASH(col1) BUCKETS 10;
  1. example_db.my_tableからcol4列を削除する
ALTER TABLE example_db.my_table DROP COLUMN col4;

カラムタイプと位置の変更

  • 集約モデルが値カラムを変更する場合は、agg_typeを指定する必要があります。

  • 非集約タイプがキーカラムを変更する場合は、KEYキーワードを指定する必要があります。

  • カラムのタイプのみ変更可能で、カラムのその他の属性は同じままにする必要があります。

  • パーティションカラムとバケットカラムは変更できません。

  • 現在、以下のタイプ変換がサポートされています(ユーザーは精度損失に注意する必要があります):

    • TINYINT/SMALLINT/INT/BIGINT/LARGEINT/FLOAT/DOUBLEタイプは、より大きな数値タイプに変換できます。

    • TINTINT/SMALLINT/INT/BIGINT/LARGEINT/FLOAT/DOUBLE/DECIMALはVARCHARに変換できます。

    • VARCHARは最大長の変更をサポートします。

    • VARCHAR/CHARはTINTINT/SMALLINT/INT/BIGINT/LARGEINT/FLOAT/DOUBLEに変換できます。

    • VARCHAR/CHARはDATE(現在6つの形式をサポート:"%Y-%m-%d"、"%y-%m-%d"、"%Y%m%d"、"%y%m%d"、"%Y/%m/%d"、"%y/%m/%d")に変換できます。

    • DATETIMEはDATE(年月日情報のみ保持、例:2019-12-09 21:47:05 <--> 2019-12-09)に変換できます。

    • DATEはDATETIME(時分秒は自動的にゼロに設定、例:2019-12-09 <--> 2019-12-09 00:00:00)に変換できます。

    • FLOATはDOUBLEに変換できます。

    • INTはDATE(INTタイプのデータが無効な場合、変換は失敗し、元のデータは変更されません)に変換できます。

    • DATEとDATETIME以外のすべてのタイプはSTRINGに変換できますが、STRINGは他のタイプには変換できません。

  1. テーブル作成文
CREATE TABLE IF NOT EXISTS example_db.my_table(
col0 int,
col1 int DEFAULT "1",
col2 int,
col3 varchar(32),
col4 int SUM,
col5 varchar(32) REPLACE DEFAULT "abc"
) AGGREGATE KEY(col0, col1, col2, col3)
DISTRIBUTED BY HASH(col0) BUCKETS 10;
  1. キー列 col1 の型を BIGINT に変更し、列 col2 の後に移動する
ALTER TABLE example_db.my_table 
MODIFY COLUMN col1 BIGINT KEY DEFAULT "1" AFTER col2;

注意:キー列または値列を変更する場合、完全な列情報を宣言する必要があります。

  1. ベーステーブルのval1列の最大長を変更します。元のval1は (val1 VARCHAR(32) REPLACE DEFAULT "abc") でした
ALTER TABLE example_db.my_table 
MODIFY COLUMN col5 VARCHAR(64) REPLACE DEFAULT "abc";

注意: カラムのタイプのみ変更可能です。カラムの他の属性は同じままでなければなりません。

  1. キーカラム内のフィールドの長さを変更する
ALTER TABLE example_db.my_table
MODIFY COLUMN col3 varchar(50) KEY NULL comment 'to 50';

並び替え

  • すべての列を一覧表示する必要があります。
  • 値列はキー列の後に配置する必要があります。
  1. Create table文
CREATE TABLE IF NOT EXISTS example_db.my_table(
k1 int DEFAULT "1",
k2 int,
k3 varchar(32),
k4 date,
v1 int SUM,
v2 int MAX,
) AGGREGATE KEY(k1, k2, k3, k4)
DISTRIBUTED BY HASH(k1) BUCKETS 10;
  1. example_db.my_table内の列を並び替える
ALTER TABLE example_db.my_table
ORDER BY (k3,k1,k2,k4,v2,v1);

制限事項

  • テーブルは同時に1つのスキーマ変更ジョブのみ実行できます。

  • パーティション列とバケット列は変更できません。

  • 集約テーブルがREPLACE方式を使用して集約された値列を持つ場合、キー列は削除できません。

  • ユニークテーブルはキー列を削除できません。

  • SUMまたはREPLACEの集約タイプを持つ値列を追加する場合、その列のデフォルト値は履歴データに対して意味を持ちません。

  • 履歴データは詳細情報を失っているため、デフォルト値は実際には集約された値を反映することができません。

  • 列タイプを変更する場合、タイプ以外のすべてのフィールドは元の列の情報で補完する必要があります。

  • 新しい列タイプを除き、集約方式、Nullable属性、およびデフォルト値は元の情報に従って補完する必要があることに注意してください。

  • 集約タイプ、Nullable属性、およびデフォルト値の変更はサポートされていません。

関連設定

FE設定

  • alter_table_timeout_second: ジョブのデフォルトタイムアウト、86400秒。

BE設定

  • alter_tablet_worker_count: BE側で履歴データ変換を実行するために使用されるスレッド数。デフォルトは3。スキーマ変更ジョブを高速化したい場合は、このパラメータを適切に増加させてBEを再起動できます。ただし、変換スレッドが多すぎるとIO圧迫が増加し、他の操作に影響を与える可能性があります。

  • alter_index_worker_count: BE側で履歴データのインデックス構築を実行するために使用されるスレッド数(注:現在は転置インデックスのみサポート)。デフォルトは3。インデックス変更ジョブを高速化したい場合は、このパラメータを適切に増加させてBEを再起動できます。ただし、スレッドが多すぎるとIO圧迫が増加し、他の操作に影響を与える可能性があります。