LoginSignup
11
6
お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

【初LT登壇】「sqlxからpgxへの移行を今はしない判断をするまで」の深堀りをしてみます!

Last updated at Posted at 2024-07-02

こんにちは。

株式会社HRBrainでバックエンドエンジニアをしているみつです!

この春に新卒として入社し、さまざまな経験を積む中で、「sqlライブラリの移行」というタスクに立ち向かう機会がありました。

2024.05.20にししとうLTでは、時間の都合上話せなかった詳細について、この記事で補足したいと思います:relaxed:

(ちなみに、ししとうLTは私にとって人生初のLT登壇でした:joy: 記事執筆時点では、社外LTに聞く側でしか参加したことがないので、もし誘っていただけたら嬉しいですw)

資料はこちら ▼

sqlxからpgxへの移行までの話

新規プロダクト開発を進める中で、「リリースまでにログを出したい!」というタスクがありました。

せっかくなのでやってみたい!と手を挙げ、チームで使用していたsqlxにloggerを持たせる方法を検討しました。

しかし、sqlxではloggerを持たせることができないという壁にぶつかりました。

加えて、同じ時期にデータベースの設計見直しが行われており、この機会にライブラリも見直す必要があるのではないかと考えるようになり、"ぷち沼"にハマっていくことになります。

出したかったログの種類:writing_hand:

出したいログの種類は、大きく3つでした。

  • アクセスログ(いつアクセスしたかなど)
  • アプリケーションログ(エラーのスタックトレースなど)
  • SQL操作ログ(Cloud SQLでどんなSQLが実行されたかなど)

色々なGoのSQLライブラリを検討:sunny:

まず、GoにはどんなSQLライブラリがあり、どのライブラリであればLoggerを持たせられるのかを検討しました。

標準パッケージであるdatabase/sqlから最近流行りのsqlc(?)まで、一言にSQLと言ってもさまざまな種類のライブラリがあることを知りました。

正直なところ、種類が多くて、それぞれが何に使われるものなのかよく分からなかったので、一つずつドキュメントを読んで知識を深めることにしました。笑

  • database/sql
  • pq
  • sqlx
  • pgx
  • sqlc

...etc.

pqについて

  • pqパッケージは、database/sqlパッケージ用の純粋なGo PostgreSQLドライバです。[DeepL訳]
  • ほとんどの場合、クライアントはこのパッケージを直接使う代わりに database/sqlパッケージを使うでしょう。[DeepL訳]

理解したのは、純粋なGoのPostgreSQLドライバとあるように、database/sqlと合わせて使うことで機能が拡張されるライブラリ。

database/sqlでPostgreSQLにある機能を使うためにこのドライバを使うことができます。

import (
	"database/sql"

	_ "github.com/lib/pq"
)

func main() {
	connStr := "user=pqgotest dbname=pqgotest sslmode=verify-full"
	db, err := sql.Open("postgres", connStr)
	if err != nil {
		log.Fatal(err)
	}

	age := 21
	rows, err := db.Query("SELECT name FROM users WHERE age = $1", age)
	
}

sqlxについて

  • sqlxは、Goの標準ライブラリ database/sql を拡張するためのライブラリである。[DeepL訳]

これもpq同様、database/sqlと合わせて使うことで拡張することが出来るライブラリのようです。(pqsqlx

package main

import (
    "database/sql"
    "fmt"
    "log"

    _ "github.com/lib/pq"
    "github.com/jmoiron/sqlx"
)

pgxについて

  • pgxはPostgreSQL用の純粋なGoドライバとツールキットです。[DeepL訳]
  • pgx ドライバは低レベルで高性能なインタフェースであり、LISTEN / NOTIFYCOPY といった PostgreSQL 固有の機能を提供します。また、標準の database/sql インタフェースのアダプタも含まれています。[DeepL訳]

最初にドキュメントを読んだ時は、pqsqlxより強そうという印象を受けました。

このライブラリは、とても便利でpgxをドライバとして使用することもできたり、database/sqlのアダプタも含まれているとあるのでその機能を担うことも出来たりします。

実装例でも、database/sqlのimportなしに使っています。

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/jackc/pgx/v5"
)

func main() {
	// urlExample := "postgres://username:password@localhost:5432/database_name"
	conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))
	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
		os.Exit(1)
	}
	defer conn.Close(context.Background())

	var name string
	var weight int64
	err = conn.QueryRow(context.Background(), "select name, weight from widgets where id=$1", 42).Scan(&name, &weight)
	if err != nil {
		fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err)
		os.Exit(1)
	}

	fmt.Println(name, weight)
}

sqlcについて

  • 普通にORM
  • sqlcはSQLから完全に型安全なイディオムGoコードを生成します。[DeepL訳]

これは調べて見てすぐ分かったことですが、必須のライブラリではありません。

オブジェクト関係マッピング(ORM、Object-Relational Mapping)というSQLを直接触ること無く記述するためのライブラリでした。

他にも有名どころだと、GORMSQLBoilerなど様々なものが存在していてそれぞれにメリット・デメリットがあるようです。

ログの導入の前に大変なことが発覚

様々なライブラリを調査し、選定を終え、ログ導入の準備が整いつつあったのですが…

「ちょっと待てよ。DBの設計見直しが入ったということは、APIが全て置き換わるということなんじゃないか」という議論が持ち上がりました。

実際にその通りで、DB設計の見直しが行われているため、ライブラリ導入でミスをしても影響は少ない(=今が導入しやすいタイミングと言える)一方で、DBが変更され、APIスキーマも変更され、実装も大きく方向転換することになります。

つまり、今頑張って書き換えや置き換え作業を行っても、膨大な時間ロスが発生するのではないかという議論も生まれました。

Query Insightsの導入をしつつ、ライブラリ移行は見送りに

そもそも、

  • Cloud SQLを利用する中でどのようなSQLが実行されているのか
  • クエリのパフォーマンスが明らかに悪い時に確認したい

などが背景で始まったログ導入タスク。

Query Insightsで一時的に必要なものな情報を取れることが判明し、それらの設定することでログの対応はひとまず見送ることになりました。

Query Insightsについては別記事でも紹介してるのでぜひ見てください:relaxed:

まとめ

インターン時代は既存サービスのフロントエンドを主に実装していましたが、新卒からは新規プロダクトでのバックエンド開発を担当しています。

その中で、ライブラリの導入は、初期段階だからこそ経験できる、楽しい壁だと感じています!

今回のライブラリ移行を通して、以下のようなことを学びました。

  • Goでデータベースを操作する際は、database/sqlを使うのが基本であること

  • しかし、database/sqlはPostgreSQL以外のデータベース(MySQLなど)にも対応しているため、PostgreSQLの機能を利用する場合は、拡張ライブラリが必要になること:frowning2:

    • 例)↑ を埋めるのが、pgx, pq, sqlxだったりする
    • 例)↑ database/sql + PostgreSQL独自機能 = pgx
  • pqは、database/sqlをより使いやすく、PostgreSQL風に設計されたライブラリ

  • sqlxも、database/sqlをより使いやすくしたり、database/sqlではできない機能を提供するライブラリ

    • (ちなみに、機能的に重複しているため、sqlxpgxはあまり併用しないようです。)

現在は、ライブラリの入れ替えはほとんど行われていませんが、チームではアーキテクチャ周りの議論でいつも大盛りあがり(?)です!

また明日からも楽しくコーディングを続けていきたいと思います!:v:

PR

株式会社HRBrainでは、一緒に働く仲間を募集しています!

興味を持っていただいた方はぜひ弊社の採用ページをご確認ください!

HRBrain文化を一緒に作っていきましょう!

11
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6