Skip to main content

database-design

Principles and practices for designing efficient, scalable, and maintainable database schemas across relational and NoSQL systems

Aller à l'installation

Informations de source

Dépôt
NeuralBlitz/Agent-Gateway
Dernière activité de la source
9 avril 2026 à 10:58
Langue détectée de SKILL.md
anglais
Étoiles
1
Forks
0

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
Database Design
description
Principles and practices for designing efficient, scalable, and maintainable database schemas across relational and NoSQL systems
license
MIT
compatibility
["Python 3.8+","SQLAlchemy 1.4+","psycopg2 2.9+","pymongo 4.0+"]
audience
Backend developers, data architects, system designers
category
databases
# Database Design ## What I Do I provide comprehensive guidance on database design principles, schema modeling, normalization, indexing strategies, and architectural decisions. I help choose between relational and NoSQL approaches, design for scalability, and implement data integrity patterns. ## When to Use Me - Starting new database projects - Schema migration and refactoring - Performance optimization - Choosing database technology - Normalization/denormalization decisions - Microservices data architecture - Data migration strategies - Audit and compliance requirements ## Core Concepts - **Normalization**: Reducing data redundancy (1NF, 2NF, 3NF, BCNF) - **Denormalization**: Intentionally adding redundancy for performance - **Primary Keys**: Unique entity identifiers (surrogate vs natural) - **Foreign Keys**: Referential integrity constraints - **Indexes**: Performance optimization structures - **Cardinality**: Uniqueness of column values - **Selectivity**: Index efficiency measurement - **Partitioning**: Horizontal data distribution - **Sharding**: Cross-node data distribution - **ACID**: Transaction guarantees - **CAP Theorem**: Consistency vs Availability trade-offs - **CQRS**: Command Query Responsibility Segregation ## Code Examples ### Relational Schema Design (SQLAlchemy) ```python from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Boolean, Index from sqlalchemy.orm import relationship from sqlalchemy.ext.declarative import declarative_base from datetime import datetime Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True, autoincrement=True) email = Column(String(255), unique=True, nullable=False, index=True) username = Column(String(50), unique=True, nullable=False = Column(String() password_hash255), nullable=False) is_active = Column(Boolean, default=True, nullable=False) created_at = Column(DateTime, default=datetime.utcnow, nullable=False) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) __table_args__ = ( Index('idx_users_active_email', 'email', 'is_active'), ) class Post(Base): __tablename__ = 'posts' id = Column(Integer, primary_key=True, autoincrement=True) user_id = Column(Integer, ForeignKey('users.id', ondelete='CASCADE'), nullable=False) title = Column(String(255), nullable=False) slug = Column(String(255), unique=True, nullable=False) content = Column(String, nullable=True) published_at = Column(DateTime, nullable=True) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) author = relationship('User', back_populates='posts') __table_args__ = ( Index('idx_posts_user_published', 'user_id', 'published_at'), ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'), ) User.posts = relationship('Post', order_by='Post.created_at.desc()', back_populates='author') ``` ### NoSQL Document Schema (MongoDB) ```python from datetime import datetime from typing import Optional, List, Dict, Any def create_product_schema() -> dict: return { 'bsonType': 'object', 'required': ['name', 'sku', 'price', 'inventory'], 'properties': { 'name': { 'bsonType': 'string', 'description': 'Product name' }, 'sku': { 'bsonType': 'string', 'description': 'Stock keeping unit' }, 'price': { 'bsonType': 'number', 'minimum': 0, 'description': 'Product price' }, 'inventory': { 'bsonType': 'object', 'required': ['quantity', 'warehouse'], 'properties': { 'quantity': {'bsonType': 'int', 'minimum': 0}, 'warehouse': {'bsonType': 'string'}, 'reserved': {'bsonType': 'int', 'minimum': 0} } }, 'categories': { 'bsonType': 'array', 'items': {'bsonType': 'string'} }, 'attributes': { 'bsonType': 'object', 'additionalProperties': True }, 'created_at': {'bsonType': 'date'}, 'updated_at': {'bsonType': 'date'} } } ``` ### Audit Trail Pattern ```python from datetime import datetime from typing import Optional, Dict, Any class AuditLogMixin: def to_audit_record(self, action: str, user_id: Optional[int] = None) -> Dict[str, Any]: return { 'entity_type': self.__class__.__name__, 'entity_id': getattr(self, 'id', None), 'action': action, 'changes': self._get_changes(), 'user_id': user_id, 'timestamp': datetime.utcnow().isoformat() } def _get_changes(self) -> Dict[str, Any]: return {} class AuditableMixin: def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._original_values = {} def __setattr__(self, key: str, value: Any) -> None: if hasattr(self, 'id') and key not in ('_original_values',): if key not in ('created_at', 'updated_at'): if key not in self._original_values: self._original_values[key] = getattr(self, key, None) super().__setattr__(key, value) ``` ### Soft Delete Pattern ```python from datetime import datetime from typing import TypeVar, Generic from sqlalchemy import Column, DateTime, Boolean from sqlalchemy.orm import declared_attr T = TypeVar('T') class SoftDeleteMixin: deleted_at = Column(DateTime, nullable=True) is_deleted = Column(Boolean, default=False, nullable=False, index=True) @declared_attr def __mapper_args__(cls): return { 'with_polymorphic': '*', 'always_refresh': True } class SoftDeleteRepository(Generic[T]): def query(self): return self.session.query(self.model).filter( self.model.is_deleted == False ) def delete(self, entity: T) -> None: entity.deleted_at = datetime.utcnow() entity.is_deleted = True self.session.add(entity) def hard_delete(self, entity: T) -> None: self.session.delete(entity) def find_deleted(self, limit: int = 100) -> list: return self.session.query(self.model).filter( self.model.is_deleted == True ).limit(limit).all() ``` ### Polymorphic Associations ```python from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint from sqlalchemy.orm import relationship class Comment(Base): __tablename__ = 'comments' id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey('users.id'), nullable=False) content = Column(String, nullable=False) commentable_type = Column(String(50), nullable=False) commentable_id = Column(Integer, nullable=False) created_at = Column(DateTime, default=datetime.utcnow) __mapper_args__ = { 'polymorphic_identity': 'comment', 'polymorphic_on': commentable_type } class CommentableMixin: @declared_attr def comments(cls): return relationship( 'Comment', primaryjoin=f'and_(Comment.commentable_id=={cls.__name__}.id, Comment.commentable_type=="{cls.__name__}")', backref='commentable', lazy='dynamic' ) class Post(CommentableMixin, Base): __tablename__ = 'posts' id = Column(Integer, primary_key=True) title = Column(String(255), nullable=False) content = Column(String) def add_comment(self, user_id: int, content: str) -> Comment: return Comment( user_id=user_id, content=content, commentable_type='Post', commentable_id=self.id ) ``` ## Best Practices 1. **Start Simple**: Design for current needs, not hypothetical future scale 2. **Choose the Right Tool**: Match database type to data access patterns 3. **Normalize First**: Start with normalized design, denormalize based on performance needs 4. **Index Strategically**: Index columns used in WHERE, JOIN, ORDER BY clauses 5. **Use Appropriate Data Types**: Choose smallest type that fits your data 6. **Plan for Growth**: Consider partitioning and sharding from the start 7. **Document Your Schema**: Maintain ER diagrams and data dictionaries 8. **Implement Soft Deletes**: Never truly delete critical business data 9. **Version Your Migrations**: Use migration tools (Alembic, Flyway) 10. **Test Performance Early**: Profile queries with realistic data volumes 11. **Use Constraints**: Enforce data integrity at the database level 12. **Separate Concerns**: Use different databases for different access patterns ## Common Patterns **Event Sourcing:** ```python class EventStore: def append(self, aggregate_id: str, events: list) -> None: for event in events: self.session.execute( """ INSERT INTO events (aggregate_id, event_type, data, created_at) VALUES (%s, %s, %s, %s) """, (aggregate_id, event['type'], json.dumps(event['data']), datetime.utcnow()) ) def get_events(self, aggregate_id: str) -> list: return self.session.execute( "SELECT * FROM events WHERE aggregate_id = ? ORDER BY created_at", (aggregate_id,) ).fetchall() ``` **Saga Pattern for Distributed Transactions:** ```python class OrderSaga: def execute(self, order_id: int) -> bool: try: self.create_order(order_id) self.reserve_inventory(order_id) self.process_payment(order_id) self.confirm_order(order_id) return True except SagaException as e: self.rollback(order_id, e.step) return False def rollback(self, order_id: int, failed_step: str) -> None: if failed_step == 'inventory': self.release_inventory(order_id) if failed_step == 'payment': self.refund_payment(order_id) self.cancel_order(order_id) ``` **Data Vault Modeling:** ```python # Hub (business keys) class CustomerHub: customer_id = Column(String, primary_key=True) load_date = Column(DateTime, primary_key=True) record_source = Column(String) # Satellite (contextual data) class CustomerSatellite: customer_id = Column(String, ForeignKey('hub_customer.customer_id'), primary_key=True) load_date = Column(DateTime, primary_key=True) hash_diff = Column(String) name = Column(String) email = Column(String) address = Column(String) # Link (relationships) class OrderLink: order_id = Column(String, primary_key=True) load_date = Column(DateTime, primary_key=True) customer_id = Column(String, ForeignKey('hub_customer.customer_id')) product_id = Column(String, ForeignKey('hub_product.product_id')) ```
Voir sur GitHub