This document describes Lychee's database architecture, including core models, relationships, and the distinction between regular albums and smart albums.
Lychee's data layer is built around Eloquent ORM models that represent the main entities in the photo management system. The database supports MySQL, MariaDB, PostgreSQL, and SQLite.
System users with authentication and ownership relationships.
Key Fields:
id: Primary keyusername: Unique usernameemail: Email addresspassword: Hashed passwordmay_upload: Upload permission flagmay_edit_own_settings: Settings permission flag
Relationships:
- Has many
Album(owned albums) - Has many
Photo(owned photos) - Has many
PhotoRating - Belongs to
UserGroup(SE edition) - Has many
OauthCredential
User groups for permission management (SE edition).
OAuth authentication credentials linking users to external providers.
Regular photo albums with hierarchical tree structure using nested set model.
Key Fields:
id: Primary keytitle: Album titledescription: Optional descriptionowner_id: Foreign key to Userparent_id: Foreign key to parent Album (nullable)_lft,_rgt: Nested set boundaries for tree structureis_public: Public visibility flagis_nsfw: NSFW content flagis_link_required: Requires direct link flag
Relationships:
- Belongs to
User(owner) - Has many
Photo - Belongs to parent
Album(self-referential) - Has many child
Album(children) - Has many
AccessPermission
For detailed information about the tree structure implementation, see Album Tree Structure which explains the nested set model with _lft and _rgt boundaries.
Special albums that automatically contain photos with specific tags.
Key Fields:
id: Primary keytitle: Tag name- Similar visibility fields as Album
Relationships:
- Has many
Photothroughphoto_tagpivot table
For detailed information about the tag system, see Tag System.
Individual photos with metadata, EXIF data, and file information.
Key Fields:
id: Primary keytitle: Photo titledescription: Optional descriptionowner_id: Foreign key to Usertype: MIME typeoriginal_checksum: SHA-256 checksumis_public: Public visibility flagis_highlighted: Favorite flagtaken_at: Photo capture timestamplatitude,longitude: GPS coordinates
Relationships:
- Belongs to many
Albumthroughphoto_albumpivot table (many-to-many) - Belongs to
User(owner) - Has many
SizeVariant - Has one
Palette - Has many
Tagthroughphotos_tagspivot table - Has many
PhotoRating - Has one
Statistics(visit/download tracking)
Different size versions of photos (original, medium, small, thumb).
Key Fields:
id: Primary keyphoto_id: Foreign key to Phototype: Size variant type (original, medium2x, medium, small2x, small, thumb2x, thumb)width,height: Dimensionsfilesize: File size in bytesstorage_disk: Storage locationshort_path: Relative file path
Relationships:
- Belongs to
Photo
Color palette information extracted from photos.
Key Fields:
photo_id: Foreign key to Photo (primary key)colors: Array of dominant colors (hex values)
Relationships:
- Belongs to
Photo
User ratings for photos on a 1-5 star scale.
Key Fields:
photo_id: Foreign key to Photouser_id: Foreign key to Userrating: Integer rating value (1-5)
Unique Constraint:
- Composite unique index on (
photo_id,user_id) - one rating per user per photo
Relationships:
- Belongs to
Photo - Belongs to
User
Statistics:
- Average rating and count are computed via
PhotoStatisticsmodel - Current user's rating is exposed through
PhotoResource
Runtime configuration settings stored in database.
Key Fields:
key: Configuration key (primary key)value: Configuration value (string)cat: Category nametype_range: Validation type/rangeconfidentiality: Visibility level (0-3)
Type-safe Access Methods:
getValueAsString()getValueAsInt()getValueAsBool()getValueAsEnum()
Categories for organizing configuration options.
Granular access control for albums and photos.
Key Fields:
id: Primary keyuser_id: Foreign key to User (nullable)album_id: Foreign key to Albumgrants_full_photo_access: Full access flaggrants_download: Download permission flaggrants_upload: Upload permission flaggrants_edit: Edit permission flaggrants_delete: Delete permission flag
Relationships:
- Belongs to
User - Belongs to
Album
Photo and album statistics (count, sizes, etc.).
Background job execution history.
System performance and usage metrics.
Regular Albums (Album model):
- Stored in database with hierarchical tree structure
- Photos are explicitly assigned through relationships
- Can be created, deleted, and modified by users
- Support nested organization with parent-child relationships
- Use the nested set model for efficient tree operations
Smart Albums (extending BaseSmartAlbum):
- Virtual albums that exist only in memory
- Photos are included based on dynamic criteria (highlighted, recent, etc.)
- Cannot be created or deleted by users - they always exist when enabled
- Types: Recent, Highlighted, On This Day, Unsorted
For detailed information about Smart Albums, see app/SmartAlbums/README.md.
This dual approach allows Lychee to provide:
- Traditional album organization (user-created structure)
- Automatic categorization (system-generated views)
- Flexible photo access patterns
- Efficient querying for both stored and dynamic content
- Albums: Parent-child relationships using nested set model
- Users: Own albums and photos, belong to user groups (SE edition)
- Photos-Albums: Many-to-many through
photo_albumpivot table (photos can belong to multiple albums) - Tags: Many-to-many with photos through
photos_tagspivot table
- Photos: Owned by one user (but can belong to multiple albums)
- Size Variants: Multiple variants per photo
- Access Permissions: Multiple permissions per album
Proper indexing on frequently queried columns:
- Foreign keys (
owner_id,album_id,user_id) - Nested set boundaries (
_lft,_rgt) - Timestamps (
taken_at,created_at) - Visibility flags (
is_public,is_highlighted)
Eager loading enforced with Model::shouldBeStrict(), which throws an exception if a relationship is accessed before being loaded.
- Backend Architecture - Overall backend structure
- Album Tree Structure - Nested set model implementation
- Tag System - Tag architecture and operations
- Image Processing - Size variant generation and processing pipeline
Last updated: January 21, 2026