本文へ移動
cccskills
無料GitHub で公開日本語紹介

mysql-patterns

MySQLとMariaDBのテーブル設計や遅いSQLを見直し、インデックス、更新処理、接続管理、複製の遅延を点検して、修正案と検証手順をまとめるスキル。

原文原文の説明を見る

MySQL and MariaDB schema, query, indexing, transaction, replication, and connection-pool patterns for production backends. Use when designing MySQL or MariaDB schemas and indexes, or when a query, transaction, or replica lags.

インストール方法を見る

こんなときに便利

  • テーブルとインデックスの設計
  • 遅いSQLやデッドロックの調査
  • 大規模な本番テーブルの変更レビュー
  • 接続管理や複製の遅延を点検したいとき

日本語での紹介

できること

MySQLとMariaDBの設計や運用上の問題を点検し、具体的なSQL・コードの修正案と検証手順をまとめます。テーブルの型や制約、検索を助けるインデックス、複数の更新をひとまとまりで扱うトランザクションを確認します。接続の再利用設定や、読み取り用の複製データベースの遅延も対象です。

こんなときに便利

検索が遅い、更新処理が互いに待ち続ける、接続数が足りないといった問題の調査に向いています。大きな本番テーブルを変更する前のレビューや、大量データのページ分割、JSON列、全文検索の設計にも使えます。性能だけでなく、権限や通信の保護も確認します。

使い方の例

「このSQLとインデックスを見直して」「本番テーブルの変更案を確認して、検証とロールバックの基準を整理して」「接続プールの設定と複製の遅延を調べて」と依頼します。レビューでは、前提となるエンジンとバージョン、優先度の高い問題、修正案を整理します。

注意点

MySQLとMariaDBでは構文や機能が異なるため、適用前に製品とバージョンを確認します。EXPLAIN ANALYZEは実際にクエリを実行します。設定例の数値は共通の推奨値ではなく、負荷やハードウェア、復旧方針に合わせた検討が必要です。

この紹介文は、公開されている SKILL.md をもとに AI(Claude Haiku)が作成しました。正確な仕様は下の原文を確認してください。

含まれるファイル(1)

  • SKILL.md11.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

MySQL Patterns

Use this skill when working on MySQL or MariaDB schema design, migrations, slow-query investigation, queue-style transactions, connection pools, or production database configuration. Prefer exact version checks before applying a feature-specific pattern because MySQL and MariaDB have diverged in several SQL details.

Activation

  • Designing MySQL or MariaDB tables, indexes, and constraints
  • Reviewing migrations before they run on large production tables
  • Debugging slow queries, lock waits, deadlocks, or connection exhaustion
  • Adding keyset pagination, upserts, full-text search, JSON columns, or queues
  • Configuring application connection pools, read replicas, TLS, or slow logs

Version Check

Start by identifying the engine and version:

SELECT VERSION();
SHOW VARIABLES LIKE 'version_comment';

Keep MySQL and MariaDB guidance separate when syntax differs:

  • MySQL documents row aliases as the replacement for VALUES(col) in ON DUPLICATE KEY UPDATE; VALUES(col) is deprecated there.
  • MariaDB documents VALUES(col) as the supported way to reference inserted values in ON DUPLICATE KEY UPDATE; use it for cross-engine compatibility.
  • SKIP LOCKED is appropriate for queue-like work only. It skips locked rows and can return an inconsistent view, so do not use it for general accounting or integrity-sensitive reads.

Schema Defaults

CREATE TABLE orders (
    id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    account_id BIGINT UNSIGNED NOT NULL,
    status VARCHAR(32) NOT NULL,
    total DECIMAL(15, 2) NOT NULL,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    deleted_at DATETIME NULL,
    PRIMARY KEY (id),
    KEY idx_orders_account_status_created (account_id, status, created_at),
    KEY idx_orders_active (account_id, deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Default choices:

Use CasePreferAvoid
Surrogate primary keysBIGINT UNSIGNED AUTO_INCREMENTINT for tables that can grow beyond 2B rows
UUID lookup keysBINARY(16) with conversion helpersVARCHAR(36) primary keys on hot tables
Money and exact quantitiesDECIMAL(p, s)FLOAT or DOUBLE
User-facing textutf8mb4 tables and indexesMySQL utf8 / utf8mb3 defaults
Application timestampsDATETIME with UTC managed by the appAssuming DATETIME stores time zone metadata
Soft deletesdeleted_at DATETIME NULL plus scoped indexesFiltering soft-deleted rows without an index
Extensible status valueslookup table or constrained VARCHARENUM when values change often

Indexing

Composite index order usually follows equality predicates first, then range or sort columns:

CREATE INDEX idx_orders_account_status_created
    ON orders (account_id, status, created_at);

SELECT id, total
FROM orders
WHERE account_id = ?
  AND status = 'pending'
  AND created_at >= ?
ORDER BY created_at DESC
LIMIT 50;

Use EXPLAIN before adding or changing an index:

EXPLAIN
SELECT id, total
FROM orders
WHERE account_id = 123 AND status = 'pending'
ORDER BY created_at DESC
LIMIT 50;

Signals to investigate:

FieldRisk Signal
typeALL on a large table
keyNULL when a selective predicate exists
rowsVery high row estimate for an interactive path
ExtraUsing temporary, Using filesort, or broad Using where

Avoid adding indexes blindly. Each index increases write cost, migration time, backup size, and buffer-pool pressure.

Query Patterns

Upsert

Cross-engine-compatible form:

INSERT INTO user_settings (user_id, setting_key, setting_value)
VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE
    setting_value = VALUES(setting_value),
    updated_at = CURRENT_TIMESTAMP;

MySQL row-alias form:

INSERT INTO user_settings (user_id, setting_key, setting_value)
VALUES (?, ?, ?) AS new
ON DUPLICATE KEY UPDATE
    setting_value = new.setting_value,
    updated_at = CURRENT_TIMESTAMP;

Use the row-alias form only after confirming the target is MySQL. Use VALUES(col) for MariaDB or mixed MySQL/MariaDB fleets.

Keyset Pagination

SELECT id, name, created_at
FROM products
WHERE (created_at, id) < (?, ?)
ORDER BY created_at DESC, id DESC
LIMIT 50;

Back it with an index that matches the cursor:

CREATE INDEX idx_products_created_id ON products (created_at, id);

Do not use deep OFFSET pagination on large tables; it makes the server scan and discard rows before returning the page.

JSON Fields

Use JSON columns for extension data, not for fields that need heavy relational filtering or constraints.

CREATE TABLE events (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    payload JSON NOT NULL,
    event_type VARCHAR(64)
        GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(payload, '$.type'))) STORED,
    KEY idx_events_type (event_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

For frequently queried JSON paths, expose a generated column and index that column. Keep foreign keys, ownership, tenancy, and lifecycle fields relational.

Full-Text Search

ALTER TABLE articles ADD FULLTEXT KEY ft_articles_title_body (title, body);

SELECT id, title, MATCH(title, body) AGAINST (? IN NATURAL LANGUAGE MODE) AS score
FROM articles
WHERE MATCH(title, body) AGAINST (? IN NATURAL LANGUAGE MODE)
ORDER BY score DESC
LIMIT 20;

Use external search when you need typo tolerance, complex ranking, cross-table facets, or language-specific analysis beyond built-in full-text behavior.

Transactions

Keep transactions short and lock rows in a consistent order:

START TRANSACTION;

SELECT id, balance
FROM accounts
WHERE id IN (?, ?)
ORDER BY id
FOR UPDATE;

UPDATE accounts SET balance = balance - ? WHERE id = ?;
UPDATE accounts SET balance = balance + ? WHERE id = ?;

COMMIT;

Deadlock and lock-wait checklist:

  • Lock rows in a deterministic order across code paths.
  • Do external API calls before opening the transaction, not inside it.
  • Add indexes for predicates used in UPDATE, DELETE, and locking reads.
  • On deadlock, roll back and retry the whole transaction with a bounded retry budget.
  • Capture SHOW ENGINE INNODB STATUS\G soon after a deadlock; it is overwritten by later events.

Queue-style worker claim:

START TRANSACTION;

SELECT id
FROM jobs
WHERE status = 'pending'
ORDER BY created_at
LIMIT 1
FOR UPDATE SKIP LOCKED;

UPDATE jobs
SET status = 'processing', started_at = CURRENT_TIMESTAMP
WHERE id = ?;

COMMIT;

Use SKIP LOCKED only for queue-like workloads where skipping a locked row is acceptable. It is not a replacement for normal transactional consistency.

Connection Pools

SQLAlchemy example:

from sqlalchemy import create_engine

engine = create_engine(
    "mysql+mysqlconnector://app:secret@db.internal/app",
    pool_size=10,
    max_overflow=5,
    pool_timeout=30,
    pool_recycle=240,
    pool_pre_ping=True,
    connect_args={"connect_timeout": 5},
)

Node.js mysql2 example:

import mysql from 'mysql2/promise';

const pool = mysql.createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0,
  enableKeepAlive: true,
  keepAliveInitialDelay: 30000,
});

const [rows] = await pool.execute(
  'SELECT id, total FROM orders WHERE account_id = ? LIMIT 50',
  [accountId],
);

Keep application pool recycling below the server wait_timeout. If the server uses wait_timeout = 300, a pool_recycle around 240 seconds is coherent; pool_pre_ping still helps recover from network and failover events.

Diagnostics

Useful first-pass commands:

SHOW FULL PROCESSLIST;
SHOW ENGINE INNODB STATUS\G;
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';

Enable the slow log in a controlled environment:

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SET GLOBAL log_queries_not_using_indexes = 'ON';

Use EXPLAIN ANALYZE only when it is safe to execute the query. It runs the statement and can be expensive on production-sized data.

Replication

Read replicas can lag. Do not route read-your-own-write paths, checkout flows, permission checks, or idempotency-key reads to a replica immediately after a write.

-- MySQL legacy terminology, still common in existing fleets
SHOW SLAVE STATUS\G;

-- Newer terminology where supported
SHOW REPLICA STATUS\G;

Check the engine/version before standardizing on one command. Monitor replica SQL thread health, IO thread health, and lag, not just whether the TCP connection is alive.

Security

CREATE USER 'app'@'%' IDENTIFIED BY 'use-a-secret-manager';
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'app'@'%';

ALTER USER 'app'@'%' REQUIRE SSL;

SELECT user, host
FROM mysql.user
WHERE user = '';

DROP USER IF EXISTS ''@'localhost';
DROP USER IF EXISTS ''@'%';

Security review points:

  • Do not grant ALL PRIVILEGES or *.* to application users.
  • Require TLS for application users when traffic crosses hosts or networks.
  • Store credentials in the platform secret manager, not in examples, scripts, or repository files.
  • Separate migration/admin users from runtime application users.
  • Audit public network exposure and bind addresses before tuning performance.

Configuration

Example starting point for a dedicated database host:

[mysqld]
innodb_buffer_pool_size = 4G
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1

max_connections = 300
thread_cache_size = 50

wait_timeout = 300
interactive_timeout = 300
innodb_lock_wait_timeout = 10

slow_query_log = ON
long_query_time = 1
log_queries_not_using_indexes = ON

log_bin = mysql-bin
binlog_format = ROW
binlog_expire_logs_seconds = 604800

Treat configuration values as a prompt for review, not a universal preset. Size memory, connections, log retention, and durability settings from workload, hardware, backup policy, and recovery objectives.

Anti-Patterns

Anti-PatternRiskBetter Pattern
SELECT * in hot pathsOver-fetching and brittle clientsSelect explicit columns
Deep OFFSET paginationLinear scans and slow pagesKeyset pagination
No index on foreign-key joinsSlow joins and lock-heavy deletesIndex FK columns intentionally
Long transactionsLock waits and large undo historyCommit small units of work
Direct DML against mysql.userGrant-table corruption riskUse CREATE USER, ALTER USER, DROP USER
Application user with admin grantsHigh blast radiusLeast-privilege runtime user
Pool recycle above wait_timeoutStale pooled connectionsRecycle below timeout and pre-ping
Replica reads after writesStale user-facing statePin read-after-write flows to primary

Output Expectations

When this skill is used for review, return:

  1. Engine/version assumptions.
  2. Highest-risk correctness, lock, security, and migration issues.
  3. Exact SQL or code changes for the safe path.
  4. Validation plan: EXPLAIN, migration dry run, lock/deadlock check, and rollback criteria.
  5. Any MySQL/MariaDB syntax differences that affect the recommendation.

Related

  • Skill: postgres-patterns - PostgreSQL-specific schema and query patterns
  • Skill: database-migrations - migration planning and rollout safety
  • Skill: backend-patterns - API and service-layer patterns
  • Skill: security-review - secret handling, auth, and least privilege
  • Agent: database-reviewer - broader database review workflow

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

accessibility

無料日本語概要

Web・iOS・Androidの画面を、読み上げやキーボード操作に対応させ、ラベル、配色、操作対象の大きさなどをWCAG 2.2に沿って設計・点検するスキル。

  • アイコンボタンの説明を付けたいとき
  • キーボード操作とモーダルの点検
  • コントラストや操作対象の大きさの確認
affaan-m/ECC27.8万2026年10月12日 更新

agent-architecture-audit

無料日本語概要

AIエージェントの不調を、指示・記憶・ツール実行・画面表示など12の層から調べるスキル。コードやログを根拠に原因を整理し、重要度順の指摘と修正案をまとめます。

  • アプリ内だけで起きる不調を調べたいとき
  • 過去の会話が混ざる原因を調査
  • ツールの未実行や実行の誤報を確認
affaan-m/ECC27.8万2026年10月12日 更新

agent-eval

無料日本語概要

実際の開発課題で複数のコーディングエージェントを比較するスキル。成功率、取得可能なAPI費用、所要時間、繰り返し実行の安定性を測り、選定や更新後の評価に使えます。

  • 実際の開発課題でエージェントを比較
  • 新しいツールやモデルの導入前評価
  • エージェント更新後の性能確認
affaan-m/ECC27.8万2026年10月12日 更新

agent-harness-construction

無料日本語概要

AIエージェントが使うツールの種類や入出力、エラーからの復帰手順を設計・見直します。文脈の情報量も整理し、作業完了率や再試行回数で改善を評価します。

  • エージェントのツールや入力形式の設計
  • ツールの結果と次の行動を明確にしたいとき
  • 安全な再試行と停止条件を定めたいとき
affaan-m/ECC27.8万2026年10月12日 更新

agent-introspection-debugging

無料日本語概要

AIエージェントの失敗や同じ操作の繰り返しを記録し、原因の切り分け、小さな復旧操作、結果の報告まで進める手順を示して、根拠のある再試行につなげるスキル。

  • 同じツール操作を繰り返す原因の調査
  • 会話の肥大化による品質低下の調査
  • ファイルパスや環境の食い違いの確認
affaan-m/ECC27.8万2026年10月12日 更新

agent-introspection-debugging

無料日本語概要

AIエージェントが失敗や同じ操作を繰り返す原因を、エラーと実行状況から整理します。小さな復旧操作を試し、結果と根拠を引き継げる報告にまとめるスキルです。

  • エージェントの連続失敗を診断したいとき
  • 同じツール操作のループ調査
  • 情報の蓄積による出力劣化の点検
affaan-m/ECC27.8万2026年10月5日 更新

affaan-m のスキルをすべて見る

このスキルの問題を報告する