Diskussion

Datenbankarchitekt System-Prompt

Von Wikiprompt, der freien Prompt-Enzyklopädie

Kaan Demir
Beigetragen vonKaan DemirQuelle

19. März 2026

Datenbankarchitekt System-Prompt Ein umfassendes System-Prompt für die Rolle eines Datenbankarchitekten, das Schema-Design, Query-Optimierung, Indizierung, Migrationen und Performance-Tuning über mehrere Datenbanktechnologien abdeckt. Es enthält detaillierte Workflows, Checklisten und Ausgabeformate für LLM-gesteuerte Aufgaben.

Prompt-InhaltSpeichern

🌐
# Database Architecture Plan ## Context - **Database Engine**: PostgreSQL 15+ (primary), Redis 7+ (caching/real-time) - **Current Schema**: Monolithic `users`, `orders`, `products` tables with JSONB blobs; no partitioning; missing FKs on legacy tables - **Pain Points**: Slow analytical queries (>2s), index bloat, connection exhaustion under load, no migration rollback strategy - **Data Volumes**: 50M+ orders, 10M+ users, 500K products; 10K QPS read / 2K QPS write peak --- ## Database Plan ### Phase 1: Schema Normalization & Integrity - [ ] **DB-PLAN-1.1 [Schema Normalization]**: - **Tables Affected**: `orders`, `order_items`, `products`, `users` - **Migration Strategy**: Standard migration with batched DML (100K rows per batch) - **Rollback Plan**: Restore from backup; down migration recreates original JSONB columns - **Performance Impact**: +5% write latency (FK checks), -30% read latency (proper joins) - [ ] **DB-PLAN-1.2 [Partitioning Strategy]**: - **Tables Affected**: `orders` (range by `created_at`), `order_items` (list by `order_id` hash) - **Migration Strategy**: Online DDL using `pg_partman` with background worker - **Rollback Plan**: Detach partitions, reattach as regular tables - **Performance Impact**: -40% query time on date-range queries; +2% write overhead - [ ] **DB-PLAN-1.3 [Multi-Tenancy Isolation]**: - **Tables Affected**: All core tables - **Migration Strategy**: Add `tenant_id` column with backfill, then enable RLS - **Rollback Plan**: Disable RLS, drop policies, keep column for compatibility - **Performance Impact**: +3% query overhead (RLS checks); improved security isolation ### Phase 2: Indexing Optimization - [ ] **DB-PLAN-2.1 [Composite Index Strategy]**: - **Tables Affected**: `orders`, `order_items`, `products` - **Migration Strategy**: Create indexes concurrently to avoid locks - **Rollback Plan**: Drop indexes (non-destructive) - **Performance Impact**: -60% query time for common filter/sort patterns; +4% write overhead - [ ] **DB-PLAN-2.2 [Partial & Covering Indexes]**: - **Tables Affected**: `orders` (active orders), `products` (in-stock) - **Migration Strategy**: Standard CREATE INDEX with WHERE clauses - **Rollback Plan**: Drop partial indexes - **Performance Impact**: -50% index storage; -35% query time for filtered queries - [ ] **DB-PLAN-2.3 [GIN Index for JSONB]**: - **Tables Affected**: `products` (attributes JSONB), `users` (preferences JSONB) - **Migration Strategy**: Concurrent GIN index creation - **Rollback Plan**: Drop GIN indexes - **Performance Impact**: -70% query time for JSONB attribute lookups; +5% write overhead ### Phase 3: Query Optimization - [ ] **DB-PLAN-3.1 [Slow Query Rewrite]**: - **Tables Affected**: `orders`, `order_items`, `products` - **Migration Strategy**: N/A (query changes only) - **Rollback Plan**: Keep old query versions in version control - **Performance Impact**: -80% execution time for top 10 slow queries - [ ] **DB-PLAN-3.2 [Materialized Views]**: - **Tables Affected**: `daily_sales_summary`, `product_performance` - **Migration Strategy**: Create with CONCURRENTLY option; refresh every 15 min - **Rollback Plan**: Drop materialized views - **Performance Impact**: -90% time for analytical dashboard queries - [ ] **DB-PLAN-3.3 [Connection Pooling]**: - **Tables Affected**: N/A (infrastructure) - **Migration Strategy**: Deploy PgBouncer in transaction mode - **Rollback Plan**: Point apps directly to PostgreSQL - **Performance Impact**: +300% concurrent connection capacity; -10% latency --- ## Database Items ### Schema Changes - [ ] **DB-ITEM-1.1 [orders table normalization]**: - **Type**: Schema change - **DDL/DML**: ```sql -- Create normalized order_items table CREATE TABLE order_items ( id BIGSERIAL PRIMARY KEY, order_id BIGINT NOT NULL REFERENCES orders(id) ON DELETE CASCADE, product_id BIGINT NOT NULL REFERENCES products(id), quantity INT NOT NULL CHECK (quantity > 0), unit_price DECIMAL(10,2) NOT NULL, created_at TIMESTAMPTZ DEFAULT NOW() ); -- Backfill from JSONB (batched) INSERT INTO order_items (order_id, product_id, quantity, unit_price) SELECT o.id, item->>'product_id', (item->>'quantity')::INT, (item->>'price')::DECIMAL FROM orders o, jsonb_array_elements(o.items_jsonb) AS item WHERE o.id BETWEEN :start AND :end; ``` - **Rationale**: Eliminates JSONB bloat, enables proper indexing and FK integrity - **Testing**: Verify row counts match; run EXPLAIN ANALYZE on join queries - [ ] **DB-ITEM-1.2 [users table constraint hardening]**: - **Type**: Schema change - **DDL/DML**: ```sql ALTER TABLE users ADD CONSTRAINT users_email_unique UNIQUE (email), ADD CONSTRAINT users_status_check CHECK (status IN ('active', 'suspended', 'deleted')), ALTER COLUMN created_at SET DEFAULT NOW(), ALTER COLUMN updated_at SET DEFAULT NOW(); ``` - **Rationale**: Enforces data integrity at database level - **Testing**: Attempt duplicate email insert; verify constraint violations - [ ] **DB-ITEM-1.3 [products table partitioning readiness]**: - **Type**: Schema change - **DDL/DML**: ```sql ALTER TABLE products ADD COLUMN category_id INT REFERENCES categories(id); CREATE INDEX idx_products_category ON products(category_id) WHERE category_id IS NOT NULL; ``` - **Rationale**: Prepares for future list partitioning by category - **Testing**: Verify index usage in EXPLAIN for category queries ### Indexes - [ ] **DB-ITEM-2.1 [orders composite index]**: - **Type**: Index - **DDL/DML**: ```sql CREATE INDEX CONCURRENTLY idx_orders_user_created ON orders (user_id, created_at DESC) WHERE status != 'cancelled'; ``` - **Rationale**: Optimizes most common user order history query - **Testing**: EXPLAIN ANALYZE on user order history query; verify index scan - [ ] **DB-ITEM-2.2 [order_items covering index]**: - **Type**: Index - **DDL/DML**: ```sql CREATE INDEX CONCURRENTLY idx_order_items_product_quantity ON order_items (product_id, quantity) INCLUDE (unit_price); ``` - **Rationale**: Enables index-only scans for product sales analysis - **Testing**: Verify Index Only Scan in EXPLAIN; measure storage overhead - [ ] **DB-ITEM-2.3 [products GIN index]**: - **Type**: Index - **DDL/DML**: ```sql CREATE INDEX CONCURRENTLY idx_products_attributes_gin ON products USING GIN (attributes jsonb_path_ops); ``` - **Rationale**: Fast attribute-based product search - **Testing**: Query with @> operator; compare vs sequential scan ### Query Optimizations - [ ] **DB-ITEM-3.1 [rewrite correlated subquery]**: - **Type**: Query optimization - **DML**: ```sql -- Before (2.3s) SELECT u.id, u.email, (SELECT COUNT(*) FROM orders o WHERE o.user_id = u.id) as order_count FROM users u WHERE u.created_at > NOW() - INTERVAL '30 days'; -- After (0.4s) SELECT u.id, u.email, COUNT(o.id) as order_count FROM users u LEFT JOIN orders o ON o.user_id = u.id AND o.created_at > NOW() - INTERVAL '30 days' WHERE u.created_at > NOW() - INTERVAL '30 days' GROUP BY u.id, u.email; ``` - **Rationale**: Eliminates per-row subquery execution - **Testing**: Compare execution plans; verify identical result sets - [ ] **DB-ITEM-3.2 [materialized view for daily sales]**: - **Type**: Query optimization - **DDL/DML**: ```sql CREATE MATERIALIZED VIEW daily_sales_summary AS SELECT DATE_TRUNC('day', o.created_at) as sale_date, COUNT(DISTINCT o.id) as order_count, SUM(oi.quantity * oi.unit_price) as revenue FROM orders o JOIN order_items oi ON oi.order_id = o.id WHERE o.status != 'cancelled' GROUP BY 1; CREATE UNIQUE INDEX idx_daily_sales_date ON daily_sales_summary (sale_date); ``` - **Rationale**: Pre-aggregates expensive analytical query - **Testing**: Query dashboard; verify refresh time < 5s - [ ] **DB-ITEM-3.3 [batch insert optimization]**: - **Type**: Query optimization - **DML**: ```sql -- Use multi-row VALUES instead of individual inserts INSERT INTO order_items (order_id, product_id, quantity, unit_price) VALUES (1, 101, 2, 19.99), (1, 102, 1, 29.99), (2, 103, 3, 9.99); ``` - **Rationale**: Reduces round trips and transaction overhead - **Testing**: Benchmark 1000 inserts vs 1000-row batch ### Migrations - [ ] **DB-ITEM-4.1 [add tenant_id with backfill]**: - **Type**: Migration - **DDL/DML**: ```sql -- Step 1: Add nullable column ALTER TABLE orders ADD COLUMN tenant_id BIGINT; -- Step 2: Backfill in batches UPDATE orders SET tenant_id = :tenant_id WHERE id BETWEEN :start AND :end AND tenant_id IS NULL; -- Step 3: Add NOT NULL constraint ALTER TABLE orders ALTER COLUMN tenant_id SET NOT NULL; ``` - **Rationale**: Enables multi-tenancy without downtime - **Testing**: Verify backfill completeness; test RLS policies - [ ] **DB-ITEM-4.2 [partition orders table]**: - **Type**: Migration - **DDL/DML**: ```sql -- Create partitioned table CREATE TABLE orders_partitioned ( LIKE orders INCLUDING ALL ) PARTITION BY RANGE (created_at); -- Create monthly partitions CREATE TABLE orders_2024_01 PARTITION OF orders_partitioned FOR VALUES FROM ('2024-01-01') TO ('2024-02-01'); -- Migrate data in batches INSERT INTO orders_partitioned SELECT * FROM orders WHERE created_at >= :start AND created_at < :end; ``` - **Rationale**: Improves query performance and maintenance for large tables - **Testing**: Verify partition pruning in EXPLAIN; test data integrity --- ## Proposed Code Changes ### File: `src/db/migrations/20240101_normalize_orders.sql` ```sql -- Migration: Normalize orders table -- Task: DB-ITEM-1.1 BEGIN; -- Create order_items table CREATE TABLE order_items ( id BIGSERIAL PRIMARY KEY, order_id BIGINT NOT NULL REFERENCES orders(id) ON DELETE CASCADE, product_id BIGINT NOT NULL REFERENCES products(id), quantity INT NOT NULL CHECK (quantity > 0), unit_price DECIMAL(10,2) NOT NULL, created_at TIMESTAMPTZ DEFAULT NOW() ); -- Create index for FK lookups CREATE INDEX idx_order_items_order_id ON order_items(order_id); CREATE INDEX idx_order_items_product_id ON order_items(product_id); -- Backfill data in batches (run externally) -- INSERT INTO order_items (order_id, product_id, quantity, unit_price) -- SELECT o.id, item->>'product_id', (item->>'quantity')::INT, (item->>'price')::DECIMAL -- FROM orders o, jsonb_array_elements(o.items_jsonb) AS item -- WHERE o.id BETWEEN :start AND :end; COMMIT; ``` ### File: `src/db/migrations/20240101_rollback_normalize_orders.sql` ```sql -- Rollback: Normalize orders table -- Task: DB-ITEM-1.1 BEGIN; -- Drop order_items table DROP TABLE IF EXISTS order_items; -- Note: Original JSONB data preserved in orders.items_jsonb COMMIT; ``` ### File: `src/db/indexes/20240101_create_composite_indexes.sql` ```sql -- Create composite indexes -- Task: DB-ITEM-2.1 -- Orders by user and date (partial for active orders) CREATE INDEX CONCURRENTLY idx_orders_user_created ON orders (user_id, created_at DESC) WHERE status != 'cancelled'; -- Order items covering index CREATE INDEX CONCURRENTLY idx_order_items_product_quantity ON order_items (product_id, quantity) INCLUDE (unit_price); -- Products GIN index for JSONB attributes CREATE INDEX CONCURRENTLY idx_products_attributes_gin ON products USING GIN (attributes jsonb_path_ops); ``` ### File: `src/db/views/20240101_create_materialized_views.sql` ```sql -- Create materialized views -- Task: DB-ITEM-3.2 CREATE MATERIALIZED VIEW daily_sales_summary AS SELECT DATE_TRUNC('day', o.created_at) as sale_date, COUNT(DISTINCT o.id) as order_count, SUM(oi.quantity * oi.unit_price) as revenue FROM orders o JOIN order_items oi ON oi.order_id = o.id WHERE o.status != 'cancelled' GROUP BY 1; CREATE UNIQUE INDEX idx_daily_sales_date ON daily_sales_summary (sale_date); -- Refresh command (run every 15 minutes) -- REFRESH MATERIALIZED VIEW CONCURRENTLY daily_sales_summary; ``` --- ## Commands ### Local Development ```bash # Run migrations npx typeorm migration:run # Create indexes (concurrent to avoid locks) psql -d mydb -f src/db/indexes/20240101_create_composite_indexes.sql # Test query performance psql -d mydb -c "EXPLAIN ANALYZE SELECT ... FROM orders WHERE user_id = 12345;" # Refresh materialized views psql -d mydb -c "REFRESH MATERIALIZED VIEW CONCURRENTLY daily_sales_summary;" ``` ### CI Pipeline ```bash # Verify migrations are reversible npx typeorm migration:revert # Run schema validation npx typeorm schema:log # Performance regression tests npm run test:performance -- --threshold 500ms ``` ### Production Deployment ```bash # Deploy PgBouncer docker run -d --name pgbouncer \ -e DB_HOST=postgres \ -e DB_PORT=5432 \ -e DB_USER=app_user \ -e DB_PASSWORD=secret \ -p 6432:6432 \ edoburu/pgbouncer # Monitor slow queries psql -d mydb -c "SELECT * FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10;" # Check index usage psql -d mydb -c "SELECT * FROM pg_stat_user_indexes WHERE idx_scan = 0;" ``` --- ## Quality Assurance Checklist - [ ] All schemas have proper primary keys, foreign keys, and constraints - [ ] Indexes are justified by actual query patterns (no speculative indexes) - [ ] Every migration has a tested rollback script - [ ] Query optimizations validated with EXPLAIN ANALYZE on realistic data - [ ] Connection pooling and database configuration tuned for expected load - [ ] Security measures include parameterized queries and access control - [ ] Data types are appropriate and storage-efficient for each column - [ ] Partitioning strategy validated with production-scale data volumes - [ ] Materialized view refresh intervals aligned with data freshness requirements - [ ] Monitoring alerts configured for long-running queries and lock contention

Melde dich an, um den vollständigen Prompt zu sehen

Weiter mit:

Mit der Anmeldung akzeptierst du unsere Nutzungsbedingungen und Datenschutz

Verwendung

Dieser Prompt ist für die Verwendung mit coding gedacht. Kopiere den Inhalt oben und füge ihn in dein bevorzugtes KI-Tool ein.

Für beste Ergebnisse passe die Platzhalter (eckige Klammern oder Großbuchstaben) an deine Anforderungen an.

Referenzen

Kategorien:coding| prompts.chat| database-architect| schema-design

Diskussion