Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
{"prerequisites":[{"skill":"backend","reason":"Database is typically used within backend context"}],"delegation_triggers":[{"trigger":"API for data access patterns","delegate_to":"backend","context":"Repository pattern, service layer design"},{"trigger":"Data validation at API level","delegate_to":"api-design","context":"Request validation, error responses"},{"trigger":"Database integration tests","delegate_to":"testing-strategies","context":"Test data setup, cleanup strategies"}],"receives_context_from":[{"skill":"backend","receives":["Expected query patterns","Transaction requirements","Caching strategy"]},{"skill":"api-design","receives":["Pagination requirements","Filtering capabilities"]}],"provides_context_to":[{"skill":"backend","provides":["Connection pool configuration","Query optimization hints","Index usage recommendations"]},{"skill":"testing-strategies","provides":["Test database setup scripts","Seed data patterns"]}]}
Database Development
Overview
Database design, query optimization, and data management patterns for relational and NoSQL databases.
PostgreSQL
Schema Design
-- Users table with proper constraintsCREATE TABLE users (
id UUID PRIMARY KEYDEFAULT gen_random_uuid(),
email VARCHAR(255) NOT NULLUNIQUE,
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(100),
role VARCHAR(20) DEFAULT'user'CHECK (role IN ('user', 'admin', 'moderator')),
status VARCHAR(20) DEFAULT'active'CHECK (status IN ('active', 'suspended', 'deleted')),
metadata JSONB DEFAULT'{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Posts with foreign keyCREATE TABLE posts (
id UUID PRIMARY KEYDEFAULT gen_random_uuid(),
title VARCHAR(255) NOT NULL,
slug VARCHAR(255) NOT NULLUNIQUE,
content TEXT,
excerpt (),
status () (status (, , )),
author_id UUID users(id) CASCADE,
published_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOW(),
updated_at TIMESTAMPTZ NOW()
);
tags (
id UUID gen_random_uuid(),
name () ,
slug ()
);
post_tags (
post_id UUID posts(id) CASCADE,
tag_id UUID tags(id) CASCADE,
(post_id, tag_id)
);
INDEX idx_posts_author posts(author_id);
INDEX idx_posts_status posts(status) status ;
INDEX idx_posts_published_at posts(published_at ) status ;
INDEX idx_users_email_lower users((email));
posts search_vector tsvector;
INDEX idx_posts_search posts GIN(search_vector);
REPLACE update_search_vector()
$$
NEW.search_vector :
setweight(to_tsvector(, (NEW.title, )), )
setweight(to_tsvector(, (NEW.excerpt, )), )
setweight(to_tsvector(, (NEW.content, )), );
;
;
$$ plpgsql;
posts_search_update
BEFORE posts
update_search_vector();
VARCHAR
500
VARCHAR
20
DEFAULT
'draft'
CHECK
IN
'draft'
'published'
'archived'
NOT NULL
REFERENCES
ON
DELETE
DEFAULT
DEFAULT
-- Many-to-many with junction table
CREATE TABLE
PRIMARY KEY
DEFAULT
VARCHAR
50
NOT NULL
UNIQUE
VARCHAR
50
NOT NULL
UNIQUE
CREATE TABLE
REFERENCES
ON
DELETE
REFERENCES
ON
DELETE
PRIMARY KEY
-- Indexes
CREATE
ON
CREATE
ON
WHERE
=
'published'
CREATE
ON
DESC
WHERE
=
'published'
CREATE
ON
LOWER
-- Full-text search
ALTER TABLE
ADD
COLUMN
CREATE
ON
USING
CREATE
OR
FUNCTION
RETURNS
TRIGGER
AS
BEGIN
=
'english'
COALESCE
''
'A'
||
'english'
COALESCE
''
'B'
||
'english'
COALESCE
''
'C'
RETURN
NEW
END
LANGUAGE
CREATE
TRIGGER
INSERT
OR
UPDATE
ON
FOR
EACH
ROW
EXECUTE
FUNCTION
Advanced Queries
-- Common Table Expressions (CTE)WITH post_stats AS (
SELECT
author_id,
COUNT(*) as post_count,
AVG(LENGTH(content)) as avg_length
FROM posts
WHERE status ='published'GROUPBY author_id
)
SELECT
u.name,
u.email,
ps.post_count,
ps.avg_length
FROM users u
JOIN post_stats ps ON u.id = ps.author_id
ORDERBY ps.post_count DESC
LIMIT 10;
-- Window functionsSELECT
p.title,
p.published_at,
u.name as author,
ROW_NUMBER() OVER (PARTITIONBY p.author_id ORDERBY p.published_at DESC) as author_rank,
COUNT(*) OVER (PARTITIONBY p.author_id) as author_total_posts,
p.published_at -LAG(p.published_at) OVER (PARTITIONBY p.author_id ORDERBY p.published_at) as days_since_last
FROM posts p
JOIN users u ON p.author_id = u.id
WHERE p.status ='published';
-- Recursive CTE (hierarchical data)WITHRECURSIVE category_tree AS (
-- Base caseSELECT id, name, parent_id, 0as depth, ARRAY[name] as path
FROM categories
WHERE parent_id ISNULLUNIONALL-- Recursive caseSELECT c.id, c.name, c.parent_id, ct.depth +1, ct.path || c.name
FROM categories c
JOIN category_tree ct ON c.parent_id = ct.id
)
SELECT*FROM category_tree ORDERBY path;
-- JSONB queriesSELECT
id,
metadata->>'theme'as theme,
metadata->'preferences'->>'notifications'as notifications
FROM users
WHERE metadata @>'{"verified": true}'AND metadata->'preferences' ? 'dark_mode';
-- Update JSONBUPDATE users
SET metadata = jsonb_set(
metadata,
'{lastLogin}',
to_jsonb(NOW())
)
WHERE id = $1;
Performance Optimization
-- Analyze query plan
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT p.*, u.name as author_name
FROM posts p
JOIN users u ON p.author_id = u.id
WHERE p.status ='published'ORDERBY p.published_at DESC
LIMIT 20;
-- Partial index for common queriesCREATE INDEX idx_active_users ON users(email) WHERE status ='active';
-- Covering index (index-only scan)CREATE INDEX idx_posts_list ON posts(status, published_at DESC)
INCLUDE (title, slug, excerpt, author_id);
-- BRIN index for time-series dataCREATE INDEX idx_events_created ON events USING BRIN(created_at);
-- Table partitioningCREATE TABLE events (
id UUID DEFAULT gen_random_uuid(),
event_type VARCHAR(50),
payload JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
) PARTITIONBYRANGE (created_at);
CREATE TABLE events_2024_q1 PARTITIONOF events
FORVALUESFROM ('2024-01-01') TO ('2024-04-01');
CREATE TABLE events_2024_q2 PARTITIONOF events
FORVALUESFROM ('2024-04-01') TO ('2024-07-01');