5.6 KiB
Skinbase – User Schema Review & Upgrade Plan
Database: MySQL / Percona 8.x
Project: Skinbase (new system, no legacy dependencies)
Reviewed tables: users, user_profiles, user_social_links, user_statistics
1. Overview
The current user-related database schema is well designed, modern, and suitable
for long-term growth.
Key strengths include:
- Clear separation of concerns
- Proper use of foreign keys and cascading deletes
- BigInt primary keys
- Soft deletes on users
- Migration-friendly legacy password handling
This document summarizes:
- what is already good
- recommended optimizations
- future-proofing steps (non-breaking)
- performance considerations for scale
2. users Table
2.1 What’s Good
- Unique
usernameandemail legacy_password_algoallows smooth migration from old systemsneeds_password_resetimproves security posture- Role stored as string allows flexibility in early stages
- Soft deletes enabled
2.2 Recommended Indexes
Add indexes for common query patterns:
CREATE INDEX idx_users_active ON users (is_active);
CREATE INDEX idx_users_role ON users (role);
CREATE INDEX idx_users_last_visit ON users (last_visit_at);
These improve:
- active user filtering
- admin queries
- “last seen” or online user features
2.3 Future Role Normalization (Planned)
Current approach is fine short-term:
role = 'user' | 'admin' | 'moderator'
Planned future upgrade:
rolestableuser_rolespivot table (many-to-many)
This allows:
- multiple roles per user
- temporary or scoped roles
- better permission modeling
⚠️ No immediate action required — just avoid hard-coding role logic.
2.4 Optional Security Enhancements
Recommended additions (optional but advised):
last_password_change_at TIMESTAMP NULL,
failed_login_attempts INT UNSIGNED DEFAULT 0,
locked_until TIMESTAMP NULL
Enables:
- rate limiting
- temporary account locking
- better auditability
3. user_profiles Table
3.1 Strengths
- Clean one-to-one relationship with
users - Public profile data separated from auth data
- Nullable fields for progressive profile completion
- Inclusive gender enum with safe default
- Localization-ready (
language,country_code)
3.2 Country Handling Recommendation
Prefer using only:
country_code (ISO 3166-1 alpha-2)
Benefits:
- language-independent
- avoids inconsistent country naming
- easier frontend mapping
country text field can be deprecated later if needed.
3.3 Avatar & Media Metadata (Future)
Current:
avatar VARCHAR(255)
Recommended future approach:
avatar_hash CHAR(64)
avatar_ext VARCHAR(10)
avatar_updated_at TIMESTAMP
This aligns with:
- hash-based file storage
- CDN-friendly URLs
- cache invalidation control
4. user_social_links Table
4.1 Current Design
- One row per platform per user
- Unique constraint on
(user_id, platform) - Cascade delete enabled
This is solid.
4.2 Platform Normalization (Recommended)
Current:
platform VARCHAR(32)
Risk:
- inconsistent values (
twitter,x,Twitter, etc.)
Options:
Option A – Enum (simple):
ENUM('twitter','x','instagram','deviantart','artstation','github','website')
Option B – Reference Table (best long-term):
social_platforms- foreign key
platform_id
Option B is preferred for Skinbase as platforms evolve.
5. user_statistics Table
5.1 Strengths
- Isolated counters
- One row per user
- Minimal row size
- Clean FK relationship
5.2 Performance Warning (Important)
Avoid frequent direct updates like:
UPDATE user_statistics SET downloads = downloads + 1;
At scale, this causes:
- row locking
- write contention
- degraded performance
5.3 Recommended Strategy
- Use Redis (or in-memory cache) for real-time increments
- Periodically flush aggregated values to MySQL
- Use jobs / cron for batch updates
This ensures:
- fast user interactions
- scalable statistics tracking
6. Charset & Collation
Current:
utf8mb4_unicode_ci
This is correct and safe.
Optional upgrade (MySQL 8+):
utf8mb4_0900_ai_ci
Benefits:
- newer Unicode rules
- slightly better performance
Not required immediately.
7. Tables Planned for Future Expansion
Not required now, but expected as Skinbase grows:
7.1 user_activity_log
- logins
- uploads
- profile edits
- moderation actions
7.2 user_followers
- artist-to-artist following
- social graph features
7.3 user_settings
- privacy preferences
- notification settings
- email subscriptions
These should remain separate tables to avoid bloating users.
8. Laravel Implementation Notes
Recommended model casting:
protected $casts = [
'is_active' => 'boolean',
'needs_password_reset' => 'boolean',
'email_verified_at' => 'datetime',
'last_visit_at' => 'datetime',
];
Best practices:
- Eager load profiles (
with('profile')) - Cache public profile + statistics
- Keep statistics out of main user queries
9. Final Verdict
Schema quality: Excellent Scalability: Very good Migration readiness: Excellent Long-term Skinbase fit: Excellent
The current schema is production-ready and significantly better than typical legacy user databases. Most future improvements can be introduced without breaking changes.
Primary future wins:
- Redis-backed statistics
- normalized roles and social platforms
- hash-based media storage
Status: Approved for production Next steps: API design, public profile queries, legacy user migration