TiDBでベクトル検索
はじめに
ChatGPTのような生成AIの登場により、**ベクトル検索(Vector Search)**という技術が注目されています。これは、文章、画像などを数値のベクトル(数字の配列)に変換し、その「意味の近さ」や「特徴の類似度」に基づいてデータを検索する技術です。
きっかけは、TiDBユーザグループ ミートアップ #5に参加し、そこでTiDBのベクトル検索の紹介があり、どんなものかと試してみたことです。
これまでベクトル検索には専門のデータベースが必要でしたが、TiDBでもついにネイティブサポートが追加されました。この記事では、TiDBを使ってベクトル検索を行う基本的な手順を、実際に筆者が遭遇した多くのエラーとその最終的な解決策までを含めて、チュートリアルとして解説します。
前提条件
TiDBでインデックス作成の記事で使用したTiDBのプロジェクトを使用します。
最終的なゴール
- VECTOR型のカラムを持つテーブルを作成する。
- ベクトルデータを挿入する。
- VEC_COSINE_DISTANCE関数を使い、類似ベクトルを検索する。
環境準備:【最重要】バージョンと起動設定
TiDBのベクトル検索は比較的新しい機能のため、ローカル環境(tiup playground
)で試すには特定のバージョンと起動設定が必須です。ここが最初にして最大のハマりどころです。
- 必要なTiDBバージョン: v8.4.0以降
- 必要な起動オプション: サーバーの実験的機能を有効にする設定ファイル
ステップ1: TiDB用の設定ファイルを作成する
まず、viなどのエディタで以下の内容のファイルを作成します。このファイルは、「ベクトル検索機能を有効にする」という設定を意味します。
[experimental]
enable-vector-search = true
ステップ2: 正しいバージョンと設定でTiDBを起動する
作成したコンテナにアクセスしtiup playground
コマンドに、バージョンと先ほど作成した設定ファイルを指定して起動します。
# 既存のplaygroundがあれば一度クリーンアップ
tiup playground clean
# v8.4.0 と設定ファイルを指定して起動
tiup playground v8.4.0 --db.config ./tidb-config.toml
チュートリアル:類似文章を検索する
1. テーブルの作成
ベクトルデータを保存するためのテーブルを作成します。新しいデータ型VECTORがポイントです。VECTOR<FLOAT>(次元数)のように、要素の型と次元数を指定します。
CREATE DATABASE IF NOT EXISTS vector_db;
USE vector_db;
CREATE TABLE vector_table (
id INT,
title VARCHAR(255),
embedding VECTOR<FLOAT>(4),
PRIMARY KEY (id)
);
(実際のAIモデルでは、次元数は1536次元など、より大きくなります)
2. ベクトルデータの挿入
事前にAIモデルで文章をベクトル化したという想定で、データを挿入します。ベクトルデータは角括弧[]で囲んだ文字列として渡します。
INSERT INTO vector_table (id, title, embedding) VALUES
(1, '今日の天気は晴れです', '[0.1, 0.3, 0.5, 0.7]'),
(2, '昨日の天気は雨でした', '[0.2, 0.4, 0.6, 0.8]'),
(3, '美味しいレストランを紹介します', '[0.8, 0.6, 0.4, 0.2]'),
(4, 'おすすめのカフェ情報', '[0.7, 0.5, 0.3, 0.1]');
3. ベクトル検索の実行
いよいよ検索です。「人気の飲食店」という文章をベクトル化したものが[0.75, 0.55, 0.35, 0.15]
だとします。このベクトルとデータベース内の各ベクトルのコサイン類似度を計算し、最も近いもの(距離が小さいもの)を探します。
SELECT
id,
title,
-- VEC_COSINE_DISTANCE関数で検索ベクトルとの距離を計算
VEC_COSINE_DISTANCE(embedding, '[0.75, 0.55, 0.35, 0.15]') AS distance
FROM
vector_table
-- ORDER BY句で距離が近い順に並び替え
ORDER BY
distance ASC
LIMIT 3;
実行結果
「人気の飲食店」というクエリに対し、意味的に近い「美味しいレストラン」や「おすすめのカフェ」が上位にランク付けされて返ってきます。
id | title | distance |
---|---|---|
3 | 美味しいレストランを紹介します | 0.0008254166479818581 |
4 | おすすめのカフェ情報 | 0.0011794464930089399 |
2 | 昨日の天気は雨でした | 0.3641616533856764 |
🩺 ハマりどころと解決策(エラー別逆引き辞典)
ここからは、この手順の途中で筆者が実際に遭遇した多くのエラーと、その最終的な解決策を表にまとめます。
エラー内容 | 主な原因 | 解決策 |
---|---|---|
ERROR 1064: ... near "VECTOR..." |
TiDBのバージョンが古いか、ベクトル機能が有効になっていない。VECTOR 型をサーバーが認識できない。 |
v8.4.0 以降を使い、--db.config オプションで設定ファイルを読み込ませて起動する。 |
ERROR 1193: Unknown system variable 'tidb_enable_vector_search' |
古いバージョンの設定変数を実行している。 | このSET コマンドは不要。--db.config を使った起動方法に切り替える。 |
ERROR 1064: ... near "VECTOR)" |
VECTOR 型の定義で、次元数と要素の型を省略している。 |
VECTOR<FLOAT>(1536) のように、必ず次元数と型を指定する。 |
ERROR 1105: vector has X dimensions, does not fit VECTOR(Y) |
挿入するベクトルの次元数(X)と、テーブル定義の次元数(Y)が一致していない。 |
INSERT 文の[] 内の数値の個数が、テーブル定義の次元数と完全に一致しているか確認する。 |
ERROR 8027: Information schema is out of date |
ローカル環境でのリソース不足により、クラスタが不安定になっている。 | 1分ほど待ってから再実行する。頻発する場合はDockerのCPU/メモリ割り当てを増やすか、環境を再起動する。 |
まとめ
TiDBのベクトル検索機能を使えば、専門のベクトルデータベースを別途用意することなく、使い慣れたSQLで高度な類似検索機能をアプリケーションに組み込むことができます。
ローカルで試すにはv8.4.0以降と設定ファイルが必要というハマりどころはありますが、一度環境を構築すれば、VECTORデータ型とVEC_..._DISTANCE関数を覚えるだけで、TiDBが強力なAIバックエンドに進化します。ぜひ、未来の検索技術を体感してみてください!
Discussion