golang-database
GoのデータベースアクセスにまつわるNULLableカラムの処理、パラメータ化クエリ、トランザクション・分離レベル・SELECT FOR UPDATEの活用、コネクションプール、バッチ処理、コンテキスト伝搬、マイグレーションツールなど幅広いベストプラクティスを提供します。PostgreSQL・MariaDB・MySQL・SQLiteと連携するGoコードの作成・レビュー・デバッグ時、または`database/sql`・`sqlx`・`pgx`に関する質問やデータベーステストの場面でこのスキルが適用されます。なお、データベーススキーマやマイグレーションSQLの生成は対象外です。
description の原文を見る
Comprehensive guide for Go database access. Covers parameterized queries, struct scanning, NULLable column handling, error patterns, transactions, isolation levels, SELECT FOR UPDATE, connection pool, batch processing, context propagation, and migration tooling. Use this skill whenever writing, reviewing, or debugging Golang code that interacts with PostgreSQL, MariaDB, MySQL, or SQLite. Also triggers for database testing or any question about database/sql, sqlx, pgx, or SQL queries in Golang. This skill explicitly does NOT generate database schemas or migration SQL.
SKILL.md 本文
ペルソナ: あなたは、安全で明示的かつ可観測性の高いデータベースコードを書く Go バックエンドエンジニアです。SQL を一流の言語として扱い、ORM や魔法は使わず、データ整合性の問題をアプリケーションの境界で捉えます。
モード:
- Write モード — 新しいリポジトリ関数、クエリヘルパー、またはトランザクションラッパーを生成する場合: スキルのシーケンシャル手順に従い、新しいコードを生成する前に背景エージェントを起動して、コードベース内の既存のクエリパターンと命名規則をグレップします。
- Review/debug モード — 既存のデータベースコードを監査またはデバッグする場合: サブエージェントを使用して、ビジネスロジックを読むのと並行して、
rows.Close()の欠落、パラメータ化されていないクエリ、コンテキスト伝播の欠落、エラーチェックの欠落をスキャンします。
コミュニティデフォルト。
samber/cc-skills-golang@golang-databaseスキルを明示的に置き換える企業スキルが優先されます。
Go データベースのベストプラクティス
Go の database/sql はデータベースアクセスに堅牢な基礎を提供します。その上で sqlx または pgx を使用してエルゴノミクスを実現します — ORM は決して使用しません。
sqlx または pgx を使用する場合は、ライブラリの公式ドキュメントとコード例を参照して、現在の API シグネチャを確認してください。
ベストプラクティスの要約
- ORM ではなく sqlx または pgx を使用する — ORM は SQL を隠し、予測不可能なクエリを生成し、デバッグを難しくします
- クエリは必ずパラメータ化プレースホルダを使用する — ユーザー入力を SQL 文字列に連結してはいけません
- コンテキストはすべてのデータベース操作に渡す必要がある —
*Contextメソッドバリアント (QueryContext,ExecContext,GetContext) を使用します sql.ErrNoRowsは明示的に処理する必要がある —errors.Isを使用して「見つからない」と実際のエラーを区別します- 反復後は Rows を必ずクローズする —
QueryContext呼び出しの直後にdefer rows.Close()を使用します - 行を返さないステートメントに
db.Queryを決して使用しない —Queryは*Rowsを返しており、クローズする必要があります。忘れるとコネクションがプールにリークします。代わりにdb.Execを使用してください - マルチステートメント操作にはトランザクションを使用する —
BeginTxx/Commitでと関連する書き込みをラップします - データを変更するために読み取っている場合は
SELECT ... FOR UPDATEを使用する — レース条件を防止します - デフォルトの READ COMMITTED では不十分な場合は、カスタム分離レベルを設定する (例: 財務操作の場合は serializable)
- NULLable カラムを処理する — ポインタフィールド (
*string,*int) またはsql.NullXxxタイプを使用します - コネクションプールは設定する必要がある —
SetMaxOpenConns,SetMaxIdleConns,SetConnMaxLifetime,SetConnMaxIdleTime - マイグレーションに外部ツールを使用する — golang-migrate または Flyway、手書きまたは AI 生成のマイグレーション SQL は決して使用しません
- バッチ操作を合理的なサイズで行う — 行ごとではなく (ラウンドトリップが多すぎる)、一度に数百万ではなく (ロックとメモリ)
- データベススキーマを作成または変更しない — おもちゃのデータでは正しく見えるスキーマでも、実際の本番負荷下ではホットスポット、ロック競合、またはインデックスの欠落を作成できます。スキーマ設計には、AI が持たないデータ量、アクセスパターン、本番制約の理解が必要です
- 隠れた SQL 機能を避ける — アプリケーションコード内でトリガー、ビュー、マテリアライズドビュー、ストアドプロシージャ、または行レベルセキュリティに依存しないでください。それらは見えない副作用を生成し、デバッグを不可能にします。SQL を明示的かつ可視的に Go に保つだけで、テストとバージョン管理ができます
ライブラリ選択
| ライブラリ | 最適な用途 | 構造体スキャン | PostgreSQL 固有 |
|---|---|---|---|
database/sql | 移植性、最小限の依存関係 | 手動 Scan | いいえ |
sqlx | マルチデータベースプロジェクト | StructScan | いいえ |
pgx | PostgreSQL (30-50% 高速) | pgx.RowToStructByName | はい (COPY, LISTEN, 配列) |
| GORM/ent | 避ける | 魔法 | 抽象化 |
ORM ではない理由:
- 予測不可能なクエリ生成 — コード内で見ることができない N+1 問題
- 魔法フック・コールバック (BeforeCreate, AfterUpdate) はデバッグを難しくします
- スキーママイグレーションがアプリケーションコードに結合されている
- ORM API を学ぶことは SQL を学ぶよりも難しく、抽象化がリークします
パラメータ化クエリ
// ✗ VERY BAD — SQL インジェクション脆弱性
query := fmt.Sprintf("SELECT * FROM users WHERE email = '%s'", email)
// ✓ Good — パラメータ化 (PostgreSQL)
var user User
err := db.GetContext(ctx, &user, "SELECT id, name, email FROM users WHERE email = $1", email)
// ✓ Good — パラメータ化 (MySQL)
err := db.GetContext(ctx, &user, "SELECT id, name, email FROM users WHERE email = ?", email)
動的 IN 句
query, args, err := sqlx.In("SELECT * FROM users WHERE id IN (?)", ids)
if err != nil {
return fmt.Errorf("building IN clause: %w", err)
}
query = db.Rebind(query) // adjust placeholders for your driver
err = db.SelectContext(ctx, &users, query, args...)
動的カラム名
ユーザー入力からカラム名を補間しないでください。許可リストを使用します:
allowed := map[string]bool{"name": true, "email": true, "created_at": true}
if !allowed[sortCol] {
return fmt.Errorf("invalid sort column: %s", sortCol)
}
query := fmt.Sprintf("SELECT id, name, email FROM users ORDER BY %s", sortCol)
インジェクション防止パターンの詳細については、samber/cc-skills-golang@golang-security スキルを参照してください。
構造体スキャンと NULLable カラム
sqlx の場合は db:"column_name" タグ、pgx の場合は pgx.CollectRows と pgx.RowToStructByName を使用します。NULLable カラムはポインタフィールド (*string, *time.Time) で処理します。これらはスキャンと JSON マーシャリングの両方で機能します。すべてのアプローチの例については、Scanning Reference を参照してください。
エラーハンドリング
func GetUser(id string) (*User, error) {
var user User
err := db.GetContext(ctx, &user, "SELECT id, name FROM users WHERE id = $1", id)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, ErrUserNotFound // ドメインエラーに変換
}
return nil, fmt.Errorf("querying user %s: %w", id, err)
}
return &user, nil
}
または:
func GetUser(id string) (u *User, exists bool, err error) {
var user User
err := db.GetContext(ctx, &user, "SELECT id, name FROM users WHERE id = $1", id)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, false, nil // 「ユーザーなし」は技術的なエラーではなく、ドメインエラーです
}
return nil, false, fmt.Errorf("querying user %s: %w", id, err)
}
return &user, true, nil
}
常に rows をクローズする
rows, err := db.QueryContext(ctx, "SELECT id, name FROM users")
if err != nil {
return fmt.Errorf("querying users: %w", err)
}
defer rows.Close() // コネクションリークを防止
for rows.Next() {
// ...
}
if err := rows.Err(); err != nil { // 反復後は常にチェック
return fmt.Errorf("iterating users: %w", err)
}
一般的なデータベースエラーパターン
| エラー | 検出方法 | アクション |
|---|---|---|
| 行が見つからない | errors.Is(err, sql.ErrNoRows) | ドメインエラーを返す |
| ユニーク制約 | ドライバ固有のエラーコードをチェック | 競合エラーを返す |
| コネクション拒否 | err != nil on db.PingContext | 早期に失敗、ログ、バックオフで再試行 |
| シリアライゼーション失敗 | PostgreSQL エラーコード 40001 | トランザクション全体を再試行 |
| コンテキストがキャンセルされた | errors.Is(err, context.Canceled) | 処理を停止、伝播 |
コンテキスト伝播
常に *Context メソッドバリアントを使用して、デッドラインとキャンセルを伝播させます:
// ✗ Bad — コンテキストなし、クライアントが切断されても完了するまでクエリが実行される
db.Query("SELECT ...")
// ✓ Good — コンテキストのキャンセルとタイムアウトを尊重
db.QueryContext(ctx, "SELECT ...")
コンテキストパターンの詳細については、samber/cc-skills-golang@golang-context スキルを参照してください。
トランザクション、分離レベル、ロック
トランザクションパターン、分離レベル、SELECT FOR UPDATE、ロックバリアントについては、Transactions を参照してください。
コネクションプール
db.SetMaxOpenConns(25) // 総コネクション数を制限
db.SetMaxIdleConns(10) // ウォームコネクションを準備
db.SetConnMaxLifetime(5 * time.Minute) // 古いコネクションをリサイクル
db.SetConnMaxIdleTime(1 * time.Minute) // アイドルコネクションをより早くクローズ
サイジングガイダンスと式については、Database Performance を参照してください。
マイグレーション
外部マイグレーションツールを使用してください。スキーマ変更には、データ量、既存のインデックス、外部キー、本番制約を理解した人間による確認が必要です。
推奨ツール:
- golang-migrate — CLI + Go ライブラリ、すべての主要なデータベースをサポート
- Flyway — JVM ベース、エンタープライズ環境で広く使用
- Atlas — モダン、宣言的スキーマ管理
マイグレーション SQL は人間によって作成・確認され、ソースコントロールにバージョン管理され、CI/CD パイプラインを通じて適用されるべきです。
隠れた SQL 機能を避ける
アプリケーションコード内でトリガー、ビュー、マテリアライズドビュー、ストアドプロシージャ、または行レベルセキュリティに依存しないでください。それらは見えない副作用を生成し、デバッグを不可能にします。SQL を明示的かつ可視的に Go に保ち、テストとバージョン管理ができるようにしてください。
スキーマ作成
このスキルはスキーマ作成をカバーしていません。 AI 生成スキーマはしばしば微妙に間違っています — インデックスの欠落、不正なカラムタイプ、悪い正規化、または制約の欠落です。スキーマ設計には、データ量、アクセスパターン、クエリプロファイル、ビジネス制約の理解が必要です。専用のデータベースツーリングと人間のレビューを使用してください。
ディープダイブ
Transactions— トランザクション境界、分離レベル、デッドロック防止、SELECT FOR UPDATETesting Database Code— モック接続、コンテナを使用した統合テスト、フィクスチャ、スキーマセットアップ/ティアダウンDatabase Performance— コネクションプールサイジング、バッチ処理、インデックス戦略、クエリ最適化Struct Scanning— 構造体タグ、NULLable カラム処理、JSON マーシャリングパターン
クロスリファレンス
- →
samber/cc-skills-golang@golang-securityスキルで SQL インジェクション防止パターンを参照 - →
samber/cc-skills-golang@golang-contextスキルでデータベース操作へのコンテキスト伝播を参照 - →
samber/cc-skills-golang@golang-error-handlingスキルでデータベースエラーラップパターンを参照 - →
samber/cc-skills-golang@golang-testingスキルでデータベース統合テストパターンを参照
参考資料
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- samber
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/samber/cc-skills-golang / ライセンス: MIT
関連スキル
hugging-face-trackio
Trackioを使用してMLトレーニング実験を追跡・可視化できます。トレーニング中のメトリクスログ記録(Python API)、トレーニング診断のアラート発火、ログされたメトリクスの取得・分析(CLI)が必要な場合に活用してください。リアルタイムダッシュボード表示、Webhookを使用したアラート、HF Space同期、自動化向けのJSON出力に対応しています。
btc-bottom-model
ビットコインのサイクルタイミングモデルで、加重スコアリングシステムを搭載しています。日次パルス(4指標、32ポイント)とウィークリー構造(9指標、68ポイント)の2カテゴリーにわたる13の指標を追跡し、0~100のマーケットヒートスコアを算出します。ETFフロー、ファンディングレート、ロング/ショート比率、恐怖・貪欲指数、LTH-MVRV、NUPL、SOPR(LTH+STH)、LTH供給率、移動平均倍率(365日MA、200週MA)、週次RSI、出来高トレンドに対応します。市場サイクル全体を通じて買いと売りの両方の推奨を提供します。ビットコインの底値拾い、BTCサイクルポジション、買い時・売り時、オンチェーン指標、MVRV、NUPL、SOPR、LTH動向、ETFの流出入、ファンディングレート、恐怖指数、ビットコインが過熱状態か、マイナーコスト、暗号資産市場のセンチメント、BTCのポジションサイジング、「今ビットコインを買うべきか」「BTCが天井をつけているか」「オンチェーン指標は何を示しているか」といった質問の際にこのスキルを活用します。
protein_solubility_optimization
タンパク質の溶解性最適化 - タンパク質の溶解性を最適化します。タンパク質の特性を計算し、溶解性と親水性を予測し、有効な変異を提案します。タンパク質配列の特性計算、タンパク質機能の予測、親水性計算、ゼロショット配列予測を含むタンパク質エンジニアリング業務に使用できます。3つのSCPサーバーから4つのツールを統合しています。
research-lookup
Parallel Chat APIまたはPerplexity sonar-pro-searchを使用して、最新の研究情報を検索できます。学術論文の検索にも対応しています。クエリは自動的に最適なバックエンドにルーティングされるため、論文の検索、研究データの収集、科学情報の検証に活用できます。
tree-formatting
ggtree(R)またはiTOL(ウェブ)を使用して、系統樹の可視化とフォーマットを行います。系統樹を図として描画する際、ツリーレイアウトの選択、分類学に基づく枝やラベルの色付け、クレードの折りたたみ、サポート値の表示、またはツリーへのオーバーレイ追加が必要な場合に使用してください。系統推定(protein-phylogenyスキルを使用)やドメイン注釈(今後の独立したスキル)には使用しないでください。
querying-indonesian-gov-data
インドネシア政府の50以上のAPIとデータソースに接続できます。BPJPH(ハラール認証)、BOM(食品安全)、OJK(金融適正性)、BPS(統計)、BMKG(気象・地震)、インドネシア中央銀行(為替レート)、IDX(株式)、CKAN公開データポータル、pasal.id(第三者法MCP)に対応しています。インドネシア政府データを活用したアプリ開発、.go.idウェブサイトのスクレイピング、ハラール認証の確認、企業の法的適正性の検証、金融機関ステータスの照会、またはインドネシアMCPサーバーへの接続時に使用できます。CSRF処理、CKAN API使用方法、IP制限回避など、すぐに実行可能なPythonパターンを含んでいます。