コンテンツにスキップ

7.2 テーブル構造とスキーマ

メッセージ全体を1つのカラムに格納すれば、収集をすぐに開始できます。 しかし、後から機器別のエラー件数を求めるために毎回原文を解析すると、クエリが複雑になります。 この節では、原文を保持しつつ、繰り返し検索・集計する値を別カラムに取り出す方法を説明します。

カラム構成

次は、セキュリティイベントを1件保存して確認する独立した実習です。

CREATE LOG TABLE ch7_schema (
    event_time DATETIME,
    event_id   VARCHAR(64),
    device     VARCHAR(32),
    severity   SHORT,
    src_ip     IPV4,
    dst_port   INTEGER,
    message    TEXT
);

INSERT INTO ch7_schema VALUES (
    TO_DATE('2026-01-01 10:00:00', 'YYYY-MM-DD HH24:MI:SS'),
    'evt-0001', 'FW-01', 3, '192.0.2.10', 65535,
    'connection blocked by policy'
);

SELECT event_id, device, severity, src_ip, dst_port, message
  FROM ch7_schema;

evt-0001の1行とポート65535が返されます。 ここでのevent_idは追跡用の値であり、重複入力を防ぐキー制約ではありません。

event_timeには、入力元が記録した発生時刻を保存します。 自動カラムの_arrival_timeをDDLで再宣言しないでください。 ネットワーク遅延や一括移行があると、2つの時刻が異なるのは自然なことです。

データ型の選択

選択する型確認事項
デバイス名・短いコード・イベントIDVARCHAR(n)LOGの宣言範囲は1~32,767バイトであり、文字数ではない
長い原文メッセージTEXT最大64MiB。原文自体のソート・グループ化は未サポート
エラーの重要度・小さなコードSHORTまたはINTEGER各コードの意味を収集側と検索側で統一
ポートINTEGERUSHORTの65535はNULLの予約値のため、ポート全範囲には不適切
累積バイト数LONG想定最大値とNULLの予約値を確認
アドレスIPV4またはIPV6アドレス形式と元の文字列の保存要否を区別

LOGでは、VARCHARとTEXTの両方でKEYWORDインデックスによる単語検索が可能です。 全文検索を行うという理由だけで、短いコードまでTEXTにする必要はありません。

文字列長には注意が必要です。VARCHAR(100)は韓国語100文字を意味しません。 UTF-8サンプルのバイト数を確認し、長さを超える値を実際の入力方法で送ってください。 長さ超過が切り詰めとエラーのどちらになるかは、使用するSDKやロードツールも含めて確認する必要があります。

ソート・集計用カラム

上のスキーマでは、deviceseverityを検索条件と集計基準に使用し、 messageを原文の読み取りや単語検索に使用します。 ORDER BY messageGROUP BY messageのようにTEXT自体を対象にするとエラーになります。 メッセージ全体をソートするより、デバイス、エラーコード、発生時刻から実際に必要な基準を決めてください。

KEYWORDインデックスは、形態素解析器や検索スコアに基づく検索エンジンと同じものではありません。 単語検索と原文の部分文字列検索の違いは、テキスト検索で確認できます。

スキーマ変更と入力マッピング

LOGはカラムの追加・削除・名前変更と、限定的な属性変更をサポートしています。 ただし、保存した行の値をUPDATEで変更できるわけではありません。 特にカラム順に送信するAppenderとCSVマッピングはDDL変更の影響を受けるため、変更時刻と入力プログラムの展開を併せて計画してください。

実習テーブルを削除してから、カラム変更の実習に進みます。

DROP TABLE ch7_schema;

どの値をカラムに取り出すべきか迷う場合は、実際に答える必要がある問いを書き出してください。 その問いをSQLで表現すると、必要なカラムも明確になります。

最終更新日