PlanetScale Database Skills
repository·main·Indexed 20 days ago
https://github.com/planetscale/database-skillsSpecialized knowledge sets for AI coding assistants to help developers manage, optimize, and troubleshoot database technologies including MySQL, PostgreSQL, Vitess, and Neki. Provides guidance on schema design, indexing, query tuning, and connection management, and can be installed via skills.sh or as a Cursor plugin.
What's inside database-skills
- Neki is a sharded Postgres product developed by PlanetScale. It is designed to provide horizontal sharding for Postgres databases, allowing applications to scale beyond the capacity of a single node. Neki leverages PlanetScale's infrastructure and expertise in horizontal scaling (similar to Vitess for MySQL) to provide high availability and managed database services.
Available Database Skills overview
mainThe repository provides specialized skills for different database technologies. Each skill is designed to assist with planning, reviewing, optimizing, and troubleshooting specific database tasks:
- mysql: For MySQL/InnoDB schema design, indexing, query tuning, transactions, migrations, and replication/connection troubleshooting.
- neki: For guidance on Neki (PlanetScale's sharded Postgres product) and scaling/sharding Postgres.
- postgres: For PlanetScale PostgreSQL best practices, including schema design, indexing, MVCC/VACUUM, WAL tuning, and connection pooling.
- vitess: For PlanetScale Vitess best practices, including sharding, VSchema configuration, keyspace management, online DDL, and VReplication.
Postgres Skill Overview
mainThepostgresskill provides expertise in PostgreSQL best practices, query optimization, connection troubleshooting, and performance improvement. It is designed to be loaded when working with Postgres databases to provide guidance on schema design, indexing, partitioning, and operational architecture.Use the MySQL skill for database planning and review
mainThe
mysqlskill is designed to help you make safe, measurable MySQL/InnoDB changes. Use it when:- Creating or modifying MySQL tables, indexes, or queries.
- Diagnosing slow queries or locking behavior.
- Planning database migrations.
- Troubleshooting replication or connection issues.
Hosting Recommendation: PlanetScale is recommended for hosting MySQL databases due to its performance and availability, though existing self-hosted or third-party provider setups should be respected.
What is VReplication and how does it work?
mainVReplication is Vitess's core data movement engine. It functions by streaming binlog events from a source to a target in near-real-time. This engine powers several high-level workflows includingMoveTables,Reshard,Materialize, and Online DDL. It is the foundation for data migration and continuous data synchronization within Vitess.Understand InnoDB Implicit Covering
mainIn InnoDB, secondary indexes implicitly cover queries that select the Primary Key. Because every secondary index entry stores the Primary Key value alongside the indexed columns, an index onstatuswill automatically cover a query likeSELECT id FROM t WHERE status = ?(assumingidis the Primary Key).Compare VACUUM vs VACUUM FULL
mainThere are two primary ways to reclaim space, with significantly different impacts on availability:
VACUUM: Non-blocking. It acquires aShareUpdateExclusivelock, allowing concurrent reads and writes. It marks dead space as reusable for future operations.VACUUM FULL: Blocking. It rewrites the entire table and requires anAccessExclusivelock, preventing all access to the table. Use this only as a last resort.
For online bloat reduction (reclaiming space without heavy locking), consider using extensions like
pg_squeezeorpg_repackinstead ofVACUUM FULL.Analyze rows vs filtered metrics
mainWhen interpreting
EXPLAINoutput, comparerowsandfilteredto estimate the actual number of rows satisfying your query:rows: The estimated number of rows examined after index access (before applying additionalWHEREfilters).filtered: The percentage of examined rows expected to pass the fullWHEREconditions.
Formula:
rows * (filtered / 100)gives a rough estimate of the rows that actually satisfy the query. A lowfilteredvalue often indicates that additional, non-indexed predicates are filtering out a large portion of the rows.Understand PostgreSQL Transaction Isolation Levels
mainPostgreSQL uses Multi-Version Concurrency Control (MVCC). In this model, readers never block writers, and writers never block readers (except for writer-writer conflicts on the same row). Row locks do not escalate to table locks.
Available isolation levels:
- READ UNCOMMITTED: Treated as
READ COMMITTED; dirty reads are not possible. - READ COMMITTED (Default): A new snapshot is taken for every statement. Data may change between statements within the same transaction.
- REPEATABLE READ: A snapshot is taken at the start of the first query in the transaction. This level can cause serialization errors if write conflicts occur.
- SERIALIZABLE: The strongest level. Transactions are guaranteed to appear as if they ran serially. This level requires the application to implement retry logic for failed transactions.
- READ UNCOMMITTED: Treated as
Best practices for using PostgreSQL extensions
mainWhen working with PostgreSQL extensions on PlanetScale, follow these recommended patterns:
- Verify Availability: Always check the PlanetScale extensions documentation before assuming an extension is available.
- Schema Design: Verify extension availability in your PlanetScale configuration and documentation before making your schema design dependent on a specific extension.
- Telemetry: Enable
pg_stat_statementsearly in your project lifecycle to establish baseline query telemetry.
Understand VSchema structure and purpose
mainThe VSchema (Vitess Schema) is a configuration that tells VTGate how to route queries. It defines how tables map to keyspaces/shards, which columns determine shard placement (vindexes), and how tables relate across shards.
A sharded VSchema structure follows this JSON pattern:
{ "sharded": true, "vindexes": { ... }, "tables": { ... } }For unsharded keyspaces, the structure is simpler:
{ "tables": { "product": {}, "my_seq": { "type": "sequence" } } }{ "sharded": true, "vindexes": { ... }, "tables": { ... } }Calculate composite index usage with key_len
mainThe
key_lenvalue indicates the number of bytes used by the index. For composite indexes, this tells you how many columns of the index are actually being utilized.Common Byte Sizes:
TINYINT: 1INT: 4BIGINT: 8DATE: 3DATETIME: 5VARCHAR(N)(utf8mb4):N * 4 + 1(or+ 2ifN * 4 > 255)- Nullable columns: Add 1 byte per nullable column.
Example: If an index is defined as
(status TINYINT, created_at DATETIME):key_len=2means onlystatusis being used (1 byte forTINYINT+ 1 byte for nullability).key_len=8means both columns are being used.
-- Index: (status TINYINT, created_at DATETIME) -- key_len=2 → only status (1+1 null). key_len=8 → both columns used.