Rocky Linux 9にPostgreSQL 16＋pgvectorをインストールする

# What's？

PostgreSQL 16にpgvectorをインストールしてみよう、ということで。

# pgvector

pgvectorは、ベクトル検索ができるPostgreSQLのextensionです。

https://github.com/pgvector/pgvector

PostgreSQL 13以上で使えるようです。

- 正確なkNN、ANN
- 単精度浮動小数点、半精度浮動小数点、バイナリ、 疎ベクトルをサポート
- ユークリッド距離、内積、コサイン距離、マンハッタン距離、ハミング距離、ジャッカード距離
- 各言語向けのクライアントがある

現時点でのバージョンは0.8.0です。

今回はインストールして簡単に動かして終了しようと思うのですが、インストール方法もたくさんあってよいですね。

[pgvector / Additional Installation Methods](https://github.com/pgvector/pgvector/tree/v0.8.0?tab=readme-ov-file#additional-installation-methods)

クライアントの一覧はこちら。

[pgvector / Languages](https://github.com/pgvector/pgvector/tree/v0.8.0?tab=readme-ov-file#languages)

ローカルでよく使われそうなものは、DockerHubのイメージかなと思います。

https://hub.docker.com/r/pgvector/pgvector

各種バージョンのPostgreSQLとの組み合わせでタグがあります。

OSのパッケージマネージャーでインストールする場合は、PostgreSQLの提供するリポジトリからpgvectorもインストールできるようなので、今回はRocky Linux 9で試してみようと思います。

このパターンに当てはまるのは、aptとdnf（yum）ですね。

- [pgvector / APT](https://github.com/pgvector/pgvector/tree/v0.8.0?tab=readme-ov-file#apt)
- [pgvector / Yum](https://github.com/pgvector/pgvector/tree/v0.8.0?tab=readme-ov-file#yum)

# 環境

今回の環境はこちら。Rocky Linux 9です。

```shell
$ cat /etc/redhat-release
Rocky Linux release 9.5 (Blue Onyx)


$ uname -srvmpio
Linux 5.14.0-503.26.1.el9_5.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Feb 19 16:28:19 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
```

# PostgreSQL 16＋pgvectorをインストールする

まずは、こちらに習ってRocky Linux 9にPostgreSQL 16をインストールします。

https://www.postgresql.org/download/linux/redhat/

PostgreSQLのインストールまで。

```shell
$ sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
$ sudo dnf -qy module disable postgresql
$ sudo dnf install -y postgresql16-server
```

PostgreSQL 16.8がインストールされました。

```shell
$ psql --version
psql (PostgreSQL) 16.8
```

データベースクラスタの作成。

```shell
$ sudo PGSETUP_INITDB_OPTIONS='--encoding=UTF-8 --no-locale' postgresql-16-setup initdb
```

ロケールの確認。

```shell
$ sudo grep lc_ /var/lib/pgsql/16/data/postgresql.conf
lc_messages = C                         # locale for system error message
lc_monetary = C                         # locale for monetary formatting
lc_numeric = C                          # locale for number formatting
lc_time = C                             # locale for time formatting
```

では、pgvectorをインストールしてみます。

パッケージの検索。

```shell
$ dnf search pgvector
メタデータの期限切れの最終確認: 0:00:10 前の 2025年02月24日 21時37分00秒 に実施しました。
========================================================================= 名前 & 概要 一致: pgvector ==========================================================================
pgvector_12-llvmjit.x86_64 : Just-in-time compilation support for pgvector
pgvector_13-llvmjit.x86_64 : Just-in-time compilation support for pgvector
pgvector_14-llvmjit.x86_64 : Just-in-time compilation support for pgvector
pgvector_15-llvmjit.x86_64 : Just-in-time compilation support for pgvector
pgvector_16-llvmjit.x86_64 : Just-in-time compilation support for pgvector
pgvector_17-llvmjit.x86_64 : Just-in-time compilation support for pgvector
============================================================================= 名前 一致: pgvector =============================================================================
pgvector_12.x86_64 : Open-source vector similarity search for Postgres
pgvector_13.x86_64 : Open-source vector similarity search for Postgres
pgvector_14.x86_64 : Open-source vector similarity search for Postgres
pgvector_15.x86_64 : Open-source vector similarity search for Postgres
pgvector_16.x86_64 : Open-source vector similarity search for Postgres
pgvector_17.x86_64 : Open-source vector similarity search for Postgres
```

確かにインストールできそうです。

パッケージの情報。

```shell
$ dnf info pgvector_16
メタデータの期限切れの最終確認: 0:01:09 前の 2025年02月24日 21時37分00秒 に実施しました。
利用可能なパッケージ
名前         : pgvector_16
バージョン   : 0.8.0
リリース     : 1PGDG.rhel9
Arch         : x86_64
サイズ       : 107 k
ソース       : pgvector_16-0.8.0-1PGDG.rhel9.src.rpm
リポジトリー : pgdg16
概要         : Open-source vector similarity search for Postgres
URL          : https://github.com/pgvector/pgvector/
ライセンス   : PostgreSQL
説明         : Open-source vector similarity search for Postgres. Supports L2 distance,
             : inner product, and cosine distance

```

インストール。

```shell
$ sudo dnf install pgvector_16
```

PostgreSQLを起動して使ってみます。

```shell
$ sudo systemctl enable postgresql-16
$ sudo systemctl start postgresql-16
```

接続。

```shell
$ sudo -u postgres psql
```

この時点ではpgvectorは認識していません。

```sql
postgres=# \dx
                    インストール済みの拡張一覧
  名前   | バージョン |  スキーマ  |             説明
---------+------------+------------+------------------------------
 plpgsql | 1.0        | pg_catalog | PL/pgSQL procedural language
(1 行)

```

ひとまず、データベースとユーザーを作成します。

```sql
postgres=# create user myuser password 'password';
CREATE ROLE
postgres=# create database example owner myuser;
CREATE DATABASE
```

データベースの切り替え。

```sql
postgres=# \c example
データベース"example"にユーザー"postgres"として接続しました。
```

ここからはpgvectorのGetting Startedに沿って進めます。

[pgvector / Getting Started](https://github.com/pgvector/pgvector/tree/v0.8.0?tab=readme-ov-file#getting-started)

pgvectorの導入。

```sql
example=# create extension vector;
CREATE EXTENSION
```

今度は認識されました。

```sql
example=# \dx
                                インストール済みの拡張一覧
  名前   | バージョン |  スキーマ  |                         説明
---------+------------+------------+------------------------------------------------------
 plpgsql | 1.0        | pg_catalog | PL/pgSQL procedural language
 vector  | 0.8.0      | public     | vector data type and ivfflat and hnsw access methods
(2 行)

```

作成したユーザーでログインしなおします。

```sql
$ sudo -u postgres psql -U myuser -h localhost example
ユーザー myuser のパスワード:
psql (16.8)
"help"でヘルプを表示します。

example=>
```

テーブルの作成。

```sql
example=> create table items (id bigserial primary key, embedding vector(3));
CREATE TABLE
```

データの登録。

```sql
example=> insert into items (embedding) values ('[1,2,3]'), ('[4,5,6]');
INSERT 0 2
```

マンハッタン距離で`order by`。

```sql
example=> select * from items order by embedding <-> '[3,1,2]' limit 5;
 id | embedding
----+-----------
  1 | [1,2,3]
  2 | [4,5,6]
(2 行)

```

ひとまず、導入というｋ