すべてのプロダクト
Search
ドキュメントセンター

Lindorm:動的カラム

最終更新日:Jan 14, 2025

LindormTable は動的カラムをサポートしています。この機能を使用すると、テーブルの作成時に明示的に指定されていないカラムにデータを動的に書き込んだり、クエリを実行したりできます。Lindorm このトピックでは、Lindorm SQL を使用して動的カラムを有効にする方法と、動的カラムにデータを書き込んだり、動的カラムのデータをクエリする方法について説明します。

背景情報

従来のリレーショナルデータベーステーブルのスキーマは事前に定義する必要があります。カラムを追加する場合は、テーブルの属性を変更する必要があります。大きなテーブルの属性を変更する操作には、長い時間がかかります。事前に定義されたスキーマは、ビジネス設計には不便な場合があります。LindormTable は動的カラム機能を提供します。管理するカラムを事前に定義する必要はありません。 Lindorm SQL を使用して、動的カラムからデータを読み取ったり、動的カラムにデータを書き込んだりできます。

注意事項

動的カラム機能を使用する前に、次の項目に注意してください。

  • LindormTable のバージョンが 2.2.19 以降であることを確認してください。詳細については、「Lindorm インスタンスのマイナーエンジンバージョンのアップグレード」をご参照ください。Lindorm

  • LindormTable の動的カラムのデータは VARBINARY 型です。動的カラムのデータをクエリしたり、動的カラムにデータを書き込むときは、動的カラムのデータ型をバイト配列に変換する必要があります。

  • Java 用 HBase API を使用してテーブルを作成したり、テーブルにデータを書き込む場合は、Lindorm SQL を使用して、テーブルの動的カラムからデータをクエリしたり、動的カラムにデータを書き込んだりできます。

動的カラムの有効化

重要

動的カラムは、テーブルに対して有効化された後は無効化できません。

次のいずれかの方法を使用して、動的カラムを有効にできます。

  • テーブルを作成するときに WITH 句を使用して、動的カラムを有効にします。

    CREATE TABLE t_dynamic (p1 INT, c1 INT, c2 VARCHAR, PRIMARY KEY(p1)) WITH (DYNAMIC_COLUMNS='true');
  • 既存のテーブルの属性を変更して、動的カラムを有効にします。

    ALTER TABLE t_dynamic SET 'DYNAMIC_COLUMNS' = 'true';

    結果の確認

    次のステートメントを実行して、テーブルに対して動的カラムが有効になっているかどうかを確認できます。

    SHOW TABLE VARIABLES FROM t_dynamic LIKE 'DYNAMIC_COLUMNS';
    説明

    テーブルに対して動的カラムが有効になったら、テーブルの属性を変更して、テーブルのスキーマに新しいカラムを追加できます。たとえば、次のステートメントを実行して、INT データ型の c3 カラムをテーブルのスキーマに追加できます。

    ALTER TABLE t_dynamic ADD COLUMN c3 int;

    テーブルのスキーマに c3 カラムを追加する前に、c3 という名前の動的カラムにデータを書き込むと、c3 に書き込まれたデータの型が VARBINARY であるため、c3 に INT データを挿入したり、c3 の INT データをクエリするときに例外が返されます。スキーマに追加する c3 カラムのデータ型が VARBINARY の場合は、この例外は返されません。したがって、動的カラムが有効になっているテーブルのスキーマを変更するときは、データ型に注意してください。事前に定義されたカラムの名前を、既存の動的カラムの名前に設定しないでください。

動的カラムへのデータの書き込み

SQL ステートメントを使用して動的カラムに直接データを書き込む

テーブルにデータを書き込むために使用される構文は、テーブルに対して動的カラムが有効化された後も変更されません。テーブルに対して動的カラムが有効になったら、テーブルスキーマで定義されていないカラムにデータを書き込むことができます。ただし、動的カラムのデータの型は VARBINARY のみで、バイト配列を示します。Lindorm-cli で SQL ステートメントを実行して、動的カラムにデータを書き込むことができます。UPSERT ステートメントを使用して動的カラムに書き込む値は、16 進文字(0 ~ 9 および A ~ F)で表されるバイナリ文字列である 16 進文字列(16 進文字列)に変換する必要があります。

説明

バイトは、0 ~ 255 の 10 進数、または 0x00 ~ 0xFF の 2 つの 16 進数で表すことができます。バイト配列を 16 進文字列に変換する方法の詳細については、「付録:バイト配列を 16 進文字列に変換する」をご参照ください。

次の例は、動的カラムにデータを書き込む方法を示しています。

  • 次のステートメントを実行して、t_dynamic テーブルの c3 カラムにデータを書き込みます。 c3 カラムは動的カラムです。書き込み操作は成功します。

    UPSERT INTO t_dynamic (p1, c2, c3) VALUES (1, '1', '41');
  • 次のステートメントを実行して、t_dynamic テーブルの c4 カラムにデータを書き込みます。 c4 カラムは動的カラムです。書き込み操作は成功します。

    UPSERT INTO t_dynamic (p1, c4) VALUES (2, 'ef0011');
  • Lindorm SQL 2.6.8 以降のバージョンでは、次のステートメントに示す方法を使用して 16 進文字列を指定し、通常の文字列と 16 進文字列の混同を避けることができます。

    UPSERT INTO t_dynamic(p1, c4) VALUES (3, x'ef0011');

    前のステートメントでは、動的カラム c4 に書き込まれるデータは、それぞれ長さが 1 バイトの次の 3 つの 16 進文字列ですが、長さが 6 バイトの文字列 ef0011 ではありません。0xEF0x00、および 0x11

    説明

    Lindorm SQL のバージョンの表示方法の詳細については、「SQL バージョン」をご参照ください。

  • 次のステートメントを実行して、t_dynamic テーブルの c5 カラムにデータを書き込みます。 c5 カラムは動的カラムです。動的カラム c5 に書き込まれる値は f で、これは偶数長の 16 進文字列ではないため、書き込み操作は失敗します。値 f0f に変更する必要があります。

    UPSERT INTO t_dynamic (p1, c5) VALUES (4, 'f');
  • 次のステートメントを実行して、t_dynamic テーブルの c6 カラムにデータを書き込みます。 c6 カラムは動的カラムです。 c6 に書き込まれる値は gf で、これは 16 進文字列ではないため、操作は失敗し、エラーが返されます。

    UPSERT INTO t_dynamic (p1, c6) VALUES (5, x'gf');

SQL ステートメントのパラメーターを指定して動的カラムにデータを書き込む(推奨)

アプリケーションの SQL ステートメントでバイト配列をパラメーターとして指定することにより、バイト配列を動的カラムに書き込むことをお勧めします。文字列または数値を動的カラムに書き込む場合は、文字列または数値をバイト配列にエンコードしてから、バイト配列をパラメーターとして指定して動的カラムに書き込む必要があります。

次の Java コードは、データをパラメーターとして指定することにより、t_dynamic テーブルの動的カラムにデータを書き込む方法の例を示しています。

Connection conn = DriverManager.getConnection(lindorm-jdbc-url);
String createTable = "CREATE TABLE testTable (p1 VARCHAR, c1 INT, PRIMARY KEY(p1)) 'DYNAMIC_COLUMNS' = 'true'";
Statement statement = conn.createStatement();
statement.execute(createTable);

// p1、c1、c2 の 3 つのカラムをテーブルに挿入します。 p1 カラムと c1 カラムはテーブルスキーマで定義されています。 c2 カラムは定義されておらず、動的カラムとしてテーブルに挿入されます。
String sqlUpsert = "upsert into " + tableName + "(p1, c1, c2) values(?, ?, ?)";
try (PreparedStatement stmt = conn.prepareStatement(sqlUpsert)) {
    stmt.setString(1, "pk");
    stmt.setInt(2, 4);
    stmt.setBytes(3, new byte[] {0,1});
    int updated = stmt.executeUpdate();
    Assert.assertEquals(1, updated);
}
重要

JDBC の PreparedStatement#setString() メソッドと同様に、16 進文字列をパラメーターとして入力してデータを書き込むことができます。ただし、特に MySQL を使用して Lindorm と対話する場合は、この方法でデータを書き込まないことをお勧めします。 MySQL では、クライアントから入力された STRING 型のパラメーターはバイト配列としてサーバーに送信され、データのあいまいさが生じる可能性があります。したがって、この方法でデータを書き込まないことをお勧めします。

動的カラムのデータのクエリ

動的カラムのデータをクエリできるシナリオは、次のタイプに分類されます。

  • クエリするフィールドは、明示的に定義された動的カラムです。動的カラムが有効になっているテーブルのデータをクエリするために使用される構文は、動的カラムが有効になっていないテーブルのデータをクエリするために使用される構文と同じです。テーブルに対して動的カラムを有効にすると、テーブルスキーマで定義されていないカラムのデータをクエリできます。次の例では、c3 と c4 はテーブルの作成後に追加された動的カラムです。

    SELECT p1, c2, c3, c4 FROM t_dynamic WHERE p1 = 1;

    次の結果が返されます。

    +----+----+------+------+
    | p1 | c2 |  c3  |  c4  |
    +----+----+------+------+
    | 1  | 1  | 0x41 | null |
    +----+----+------+------+
  • テーブルに含まれる動的カラムを表示するには、SELECT * ステートメントを実行して、テーブル内のすべてのカラムをクエリできます。この場合、ステートメントの最後に LIMIT 句を追加して、返される結果セットのサイズを制限する必要があります。これにより、Lindorm SQL は結果セットのメタデータの整合性を確保できます。

    SELECT * FROM t_dynamic LIMIT 10;

    次の結果が返されます。

    +----+------+------+------+----------+
    | p1 |  c1  |  c2  |  c3  |    c4    |
    +----+------+------+------+----------+
    | 1  | null | 1    | 0x41 | null     |
    | 2  | null | null | null | 0xef0011 |
    | 3  | null | null | null | 0xef0011 |
    +----+------+------+------+----------+
    重要

    SELECT * ステートメントと LIMIT 句を指定して、動的カラムが有効になっているテーブルのデータをクエリする場合、LIMIT のデフォルトの最大値は 5,000 です。最大値を指定できます。クエリされた値が最大値を超えると、エラーが返されます。

  • 動的カラムは WHERE 条件で使用されます。

    クエリのパフォーマンスを確保するには、WHERE 条件にプライマリキーカラムまたはインデックスキーカラムを含める必要があります。 Lindorm-cli または SQL ステートメントを使用して動的カラムのデータをクエリする場合、WHERE 条件の動的カラムの値は 16 進文字列である必要があります。

    たとえば、テーブル t_dynamicc4 カラムが動的カラムの場合、次のステートメントを実行してクエリを正常に実行できます。

    SELECT p1, c4 FROM t_dynamic WHERE p1 = 3 AND c4 = x'ef0011';

    対照的に、次のクエリは、WHERE 条件の c4 カラムの値 1 が 16 進文字列ではないため、失敗します。

    SELECT p1, c1, c4 FROM t_dynamic WHERE p1 = 2 AND c4 = '1';

動的カラムのデータの表示

動的カラムのクエリ結果は、Lindorm への接続に使用するコマンドラインツールに基づいて異なる方法で表示されます。

Lindorm-cli

HexString

Lindorm-cli を使用して Lindorm に接続する場合、クエリ結果は 16 進文字列として表示されます。たとえば、次のステートメントを実行して、t_dynamic テーブルのデータをクエリします。

SELECT p1, c3, c4 FROM t_dynamic WHERE p1 = 1;

次の結果が返されます。

+----+------+------+------+----------+
| p1 |  c1  |  c2  |  c3  |    c4    |
+----+------+------+------+----------+
| 1  | null | 1    | 0x41 | null     |
| 2  | null | null | null | 0xef0011 |
| 3  | null | null | null | 0xef0011 |
+----+------+------+------+----------+

結果セットでは、動的カラム c3 の 1 行目の値は、文字 A を示す 16 進文字列 0x41 として表示されます。

String

動的カラムのクエリ結果を通常の文字列として返す場合は、Lindorm-cli で Lindorm に接続するために使用するコマンドの最後に -bytesOutputAsString パラメーターを追加する必要があります。次の例は、コマンドの形式を示しています。

./lindorm-cli -url <jdbc url> -username <ユーザー名> -password <パスワード> -bytesOutputAsString
説明

Lindorm-cli の接続パラメーターの詳細については、「手順 2:LindormTable に接続する」をご参照ください。

前の例と同じ SQL ステートメントを実行すると、次の結果が返されます。

+-----+-------+---------+
| p1  |   c3  |   c4    |
+-----+-------+---------+
|  1  | A     |  null   |
+-----+-------+---------+

MySQL コマンドラインツール

デフォルトでは、クエリされた動的カラムのデータは、MySQL コマンドラインツールで疑問符(?)として表示されます。

付録:バイト配列を 16 進文字列に変換する

次の Java コードは、バイト配列を 16 進文字列に変換する方法の例を示しています。

private static final char[] DIGITS = {
  '0', '1', '2', '3', '4', '5', '6', '7',
  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
  };

private static String toHexString(byte[] bytes) {
  char[] chars;
  int j = 0;
  chars = new char[bytes.length * 2];
  for (byte b : bytes) {
    chars[j++] = DIGITS[(b & 0xF0) >> 4];
    chars[j++] = DIGITS[b & 0x0F];
  }
  return new String(chars, 0, j);
}

public void testToHexString() {
  String s = "Hello, world";
  // 文字列の getBytes() メソッドを使用して、文字列に対応するバイト配列を取得できます。
  byte[] bytes = s.getBytes(Charset.forName("UTF-8"));
  String hexString = toHexString(bytes);
  System.out.println(hexString); // 出力は 48656c6c6f2c20776f726c64 です。
}