Database Schema & Data Flow
Overview
The MyTradeX platform uses PostgreSQL as the primary database with a well-structured schema designed for high-performance trading operations. The database design follows normalization principles while optimizing for read-heavy operations typical in trading systems.
Database Design Philosophy
Core Principles
- ACID Compliance: Full transactional support for trading operations
- Performance Optimization: Strategic indexing and query optimization
- Data Integrity: Foreign key constraints and validation rules
- Audit Trail: Complete change tracking for regulatory compliance
- Scalability: Partitioning strategies for large data volumes
Technology Stack
- Database: PostgreSQL 15+
- Migration Tool: Liquibase
- Connection Pooling: HikariCP
- ORM: Spring Data JPA
Database Schema
1. Core Entities
Users Table
Purpose: User authentication and profile management
CREATE TABLE users (
id UUID PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL,
role VARCHAR(20) NOT NULL,
status VARCHAR(20) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
-- Indexes
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_role ON users(role);
CREATE INDEX idx_users_status ON users(status);
Field Descriptions:
id: Primary key (UUID for global uniqueness)email: Unique identifier for loginpassword_hash: Bcrypt hashed passwordname: User's display namerole: TRADER, ADMIN, BROKERstatus: ACTIVE, SUSPENDED, INACTIVE
Orders Table
Purpose: Trading order lifecycle management
CREATE TABLE orders (
id UUID PRIMARY KEY,
user_id UUID NOT NULL REFERENCES users(id),
symbol VARCHAR(20) NOT NULL,
side VARCHAR(4) NOT NULL, -- BUY, SELL
order_type VARCHAR(20) NOT NULL, -- MARKET, LIMIT, STOP, STOP_LIMIT
quantity DECIMAL(19,8) NOT NULL,
price DECIMAL(19,8),
stop_price DECIMAL(19,8),
time_in_force VARCHAR(10) NOT NULL, -- DAY, GTC, IOC, FOK
status VARCHAR(20) NOT NULL, -- NEW, PARTIAL, FILLED, CANCELLED, REJECTED
remaining_quantity DECIMAL(19,8) NOT NULL,
filled_quantity DECIMAL(19,8) DEFAULT 0,
average_fill_price DECIMAL(19,8),
protocol_order_id VARCHAR(50),
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
-- Constraints
CONSTRAINT chk_order_quantity CHECK (quantity > 0),
CONSTRAINT chk_order_price CHECK (order_type != 'LIMIT' OR price IS NOT NULL),
CONSTRAINT chk_order_stop_price CHECK (order_type != 'STOP_LIMIT' OR stop_price IS NOT NULL)
);
-- Indexes
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_orders_symbol ON orders(symbol);
CREATE INDEX idx_orders_status ON orders(status);
CREATE INDEX idx_orders_protocol_id ON orders(protocol_order_id);
CREATE INDEX idx_orders_created_at ON orders(created_at DESC);
CREATE INDEX idx_orders_symbol_status ON orders(symbol, status);
Order Lifecycle States:
NEW: Order created, awaiting executionPARTIAL: Partially filled, remaining quantityFILLED: Completely executedCANCELLED: User cancelled the orderREJECTED: Order rejected by exchange/system
Trades Table
Purpose: Completed trade records
CREATE TABLE trades (
id UUID PRIMARY KEY,
order_id UUID NOT NULL REFERENCES orders(id),
symbol VARCHAR(20) NOT NULL,
side VARCHAR(4) NOT NULL, -- BUY, SELL
quantity DECIMAL(19,8) NOT NULL,
price DECIMAL(19,8) NOT NULL,
buyer_id UUID NOT NULL REFERENCES users(id),
seller_id UUID NOT NULL REFERENCES users(id),
settlement_status VARCHAR(20) NOT NULL, -- PENDING, SETTLED, FAILED
protocol_trade_id VARCHAR(50),
trade_time TIMESTAMP NOT NULL DEFAULT NOW(),
settlement_date DATE,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
-- Constraints
CONSTRAINT chk_trade_quantity CHECK (quantity > 0),
CONSTRAINT chk_trade_price CHECK (price > 0),
CONSTRAINT chk_trade_parties CHECK (buyer_id != seller_id)
);
-- Indexes
CREATE INDEX idx_trades_order_id ON trades(order_id);
CREATE INDEX idx_trades_symbol ON trades(symbol);
CREATE INDEX idx_trades_buyer_id ON trades(buyer_id);
CREATE INDEX idx_trades_seller_id ON trades(seller_id);
CREATE INDEX idx_trades_settlement_status ON trades(settlement_status);
CREATE INDEX idx_trades_trade_time ON trades(trade_time DESC);
CREATE INDEX idx_trades_symbol_time ON trades(symbol, trade_time DESC);
Positions Table
Purpose: Portfolio positions and P&L tracking
CREATE TABLE positions (
id UUID PRIMARY KEY,
user_id UUID NOT NULL REFERENCES users(id),
symbol VARCHAR(20) NOT NULL,
quantity DECIMAL(19,8) NOT NULL,
average_cost DECIMAL(19,8) NOT NULL,
current_price DECIMAL(19,8),
unrealized_pnl DECIMAL(19,8) DEFAULT 0,
realized_pnl DECIMAL(19,8) DEFAULT 0,
last_updated TIMESTAMP NOT NULL DEFAULT NOW(),
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
-- Constraints
CONSTRAINT uk_positions_user_symbol UNIQUE (user_id, symbol)
);
-- Indexes
CREATE INDEX idx_positions_user_id ON positions(user_id);
CREATE INDEX idx_positions_symbol ON positions(symbol);
CREATE INDEX idx_positions_quantity ON positions(quantity);
CREATE INDEX idx_positions_pnl ON positions(unrealized_pnl);
Market Data Table
Purpose: Real-time and historical market data
CREATE TABLE market_data (
id UUID PRIMARY KEY,
symbol VARCHAR(20) NOT NULL,
last_price DECIMAL(19,8) NOT NULL,
bid_price DECIMAL(19,8),
ask_price DECIMAL(19,8),
bid_quantity DECIMAL(19,8),
ask_quantity DECIMAL(19,8),
volume BIGINT DEFAULT 0,
high_24h DECIMAL(19,8),
low_24h DECIMAL(19,8),
change_24h DECIMAL(10,4),
change_percent_24h DECIMAL(10,4),
timestamp TIMESTAMP NOT NULL DEFAULT NOW(),
-- Constraints
CONSTRAINT uk_market_data_symbol UNIQUE (symbol)
);
-- Indexes
CREATE INDEX idx_market_data_symbol ON market_data(symbol);
CREATE INDEX idx_market_data_timestamp ON market_data(timestamp DESC);
CREATE INDEX idx_market_data_last_price ON market_data(last_price);
Audit Logs Table
Purpose: System activity tracking for compliance
CREATE TABLE audit_logs (
id UUID PRIMARY KEY,
user_id UUID REFERENCES users(id),
action VARCHAR(100) NOT NULL,
resource_type VARCHAR(50) NOT NULL,
resource_id VARCHAR(100),
old_values JSONB,
new_values JSONB,
ip_address INET,
user_agent TEXT,
timestamp TIMESTAMP NOT NULL DEFAULT NOW(),
-- Indexes for common query patterns
CREATE INDEX idx_audit_logs_user_id ON audit_logs(user_id);
CREATE INDEX idx_audit_logs_action ON audit_logs(action);
CREATE INDEX idx_audit_logs_resource ON audit_logs(resource_type, resource_id);
CREATE INDEX idx_audit_logs_timestamp ON audit_logs(timestamp DESC);
);
2. Supporting Tables
Session Management
CREATE TABLE user_sessions (
id UUID PRIMARY KEY,
user_id UUID NOT NULL REFERENCES users(id),
session_token VARCHAR(255) NOT NULL,
refresh_token VARCHAR(255),
expires_at TIMESTAMP NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
CONSTRAINT uk_sessions_token UNIQUE (session_token)
);
CREATE INDEX idx_sessions_user_id ON user_sessions(user_id);
CREATE INDEX idx_sessions_expires ON user_sessions(expires_at);
Order History (Partitioned)
-- Orders partitioned by date for performance
CREATE TABLE orders_history (
LIKE orders INCLUDING ALL
) PARTITION BY RANGE (created_at);
-- Monthly partitions
CREATE TABLE orders_2024_01 PARTITION OF orders_history
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
CREATE TABLE orders_2024_02 PARTITION OF orders_history
FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');
Data Relationships
Entity Relationship Diagram
Data Flow Architecture
1. Order Processing Flow
2. Trade Execution Flow
3. Market Data Flow
Performance Optimization
1. Indexing Strategy
Primary Indexes:
- All foreign keys indexed
- Status columns for filtering
- Created timestamp for chronological queries
- Composite indexes for common query patterns
Query Optimization:
-- Efficient order queries
SELECT * FROM orders
WHERE user_id = ?
AND status IN ('NEW', 'PARTIAL')
ORDER BY created_at DESC
LIMIT 50;
-- Market data lookup
SELECT * FROM market_data
WHERE symbol = ?
ORDER BY timestamp DESC
LIMIT 1;
2. Partitioning Strategy
Time-based Partitioning:
- Orders table partitioned monthly
- Trades table partitioned monthly
- Audit logs table partitioned by year
- Automatic partition creation
Benefits:
- Improved query performance on recent data
- Efficient data archival
- Better index maintenance
- Reduced lock contention
3. Caching Strategy
Multi-level Caching:
- L1: Application-level cache (EhCache)
- L2: Database query cache
- L3: Redis for shared data
Cached Data:
- User sessions
- Market data snapshots
- Order book data
- User preferences
4. Connection Management
HikariCP Configuration:
spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
idle-timeout: 600000
max-lifetime: 1800000
connection-timeout: 30000
validation-timeout: 5000
Data Integrity & Constraints
1. Business Rules Enforcement
Order Validation:
- Quantity must be positive
- Limit orders require price
- Stop-limit orders require stop price
- Market orders cannot have price
Trade Validation:
- Buyer and seller must be different
- Trade quantity cannot exceed order remaining quantity
- Settlement must occur within regulatory timeframes
Position Validation:
- Position quantity can be positive (long) or negative (short)
- Average cost updated on each trade
- P&L calculated on position changes
2. Referential Integrity
Foreign Key Constraints:
- All relationships properly enforced
- Cascade delete for dependent records
- ON DELETE RESTRICT for critical entities
Check Constraints:
- Enum value validation
- Numeric range validation
- Business rule enforcement
3. Transaction Management
ACID Properties:
- All trading operations atomic
- Isolation level: READ_COMMITTED
- Consistent state throughout transactions
- Durability guaranteed through WAL
Deadlock Prevention:
- Consistent lock ordering
- Short transaction durations
- Optimistic locking where appropriate
Backup & Recovery
1. Backup Strategy
Continuous Backup:
- Point-in-time recovery (PITR)
- Daily full backups
- Hourly incremental backups
- Transaction log shipping
Retention Policy:
- 7 days of hourly backups
- 30 days of daily backups
- 12 months of weekly backups
- 7 years of monthly backups (regulatory requirement)
2. Recovery Procedures
Disaster Recovery:
- RTO: 15 minutes
- RPO: 5 minutes
- Cross-region replication
- Automated failover
Data Recovery:
- Point-in-time recovery
- Table-level restore
- Incremental recovery
- Validation procedures
Monitoring & Maintenance
1. Performance Monitoring
Key Metrics:
- Query response times
- Connection pool utilization
- Lock wait times
- Index usage statistics
Alerting:
- Slow query detection
- Connection pool exhaustion
- Deadlock detection
- Disk space warnings
2. Data Maintenance
Regular Tasks:
- VACUUM and ANALYZE
- Index rebuilds
- Partition management
- Statistics updates
Archival Procedures:
- Historical data archiving
- Partition rotation
- Backup verification
- Compliance reporting
Next: Real-time Communication
Continue to Real-time Communication for detailed WebSocket and event-driven architecture documentation.