# SDS-02: Database Design ## 1. Database Overview ### 1.1 Database System - **Type**: PostgreSQL 14+ - **Encoding**: UTF-8 - **Connection Pooling**: pgxpool - **Migrations**: Custom migration system ### 1.2 Database Schema Organization - **Tables**: Organized by domain (users, storage, shares, etc.) - **Indexes**: Performance indexes on foreign keys and frequently queried columns - **Constraints**: Foreign keys, unique constraints, check constraints ## 2. Core Tables ### 2.1 Users & Authentication ```sql users ( id UUID PRIMARY KEY, username VARCHAR(255) UNIQUE NOT NULL, email VARCHAR(255) UNIQUE, password_hash VARCHAR(255) NOT NULL, is_active BOOLEAN DEFAULT true, created_at TIMESTAMP, updated_at TIMESTAMP ) roles ( id UUID PRIMARY KEY, name VARCHAR(255) UNIQUE NOT NULL, description TEXT, created_at TIMESTAMP, updated_at TIMESTAMP ) permissions ( id UUID PRIMARY KEY, resource VARCHAR(255) NOT NULL, action VARCHAR(255) NOT NULL, description TEXT, UNIQUE(resource, action) ) user_roles ( user_id UUID REFERENCES users(id), role_id UUID REFERENCES roles(id), PRIMARY KEY (user_id, role_id) ) role_permissions ( role_id UUID REFERENCES roles(id), permission_id UUID REFERENCES permissions(id), PRIMARY KEY (role_id, permission_id) ) groups ( id UUID PRIMARY KEY, name VARCHAR(255) UNIQUE NOT NULL, description TEXT, created_at TIMESTAMP, updated_at TIMESTAMP ) user_groups ( user_id UUID REFERENCES users(id), group_id UUID REFERENCES groups(id), PRIMARY KEY (user_id, group_id) ) ``` ### 2.2 Storage Tables ```sql zfs_pools ( id UUID PRIMARY KEY, name VARCHAR(255) UNIQUE NOT NULL, description TEXT, raid_level VARCHAR(50), status VARCHAR(50), total_capacity_bytes BIGINT, used_capacity_bytes BIGINT, health_status VARCHAR(50), created_at TIMESTAMP, updated_at TIMESTAMP, created_by UUID REFERENCES users(id) ) zfs_datasets ( id UUID PRIMARY KEY, name VARCHAR(255) NOT NULL, pool_name VARCHAR(255) REFERENCES zfs_pools(name), type VARCHAR(50), mount_point VARCHAR(255), used_bytes BIGINT, available_bytes BIGINT, compression VARCHAR(50), quota BIGINT, reservation BIGINT, created_at TIMESTAMP, UNIQUE(pool_name, name) ) physical_disks ( id UUID PRIMARY KEY, device_path VARCHAR(255) UNIQUE NOT NULL, vendor VARCHAR(255), model VARCHAR(255), serial_number VARCHAR(255), size_bytes BIGINT, type VARCHAR(50), status VARCHAR(50), last_synced_at TIMESTAMP ) storage_repositories ( id UUID PRIMARY KEY, name VARCHAR(255) UNIQUE NOT NULL, type VARCHAR(50), path VARCHAR(255), capacity_bytes BIGINT, used_bytes BIGINT, created_at TIMESTAMP, updated_at TIMESTAMP ) ``` ### 2.3 Shares Tables ```sql shares ( id UUID PRIMARY KEY, dataset_id UUID REFERENCES zfs_datasets(id), share_type VARCHAR(50), nfs_enabled BOOLEAN DEFAULT false, nfs_options TEXT, nfs_clients TEXT[], smb_enabled BOOLEAN DEFAULT false, smb_share_name VARCHAR(255), smb_path VARCHAR(255), smb_comment TEXT, smb_guest_ok BOOLEAN DEFAULT false, smb_read_only BOOLEAN DEFAULT false, smb_browseable BOOLEAN DEFAULT true, is_active BOOLEAN DEFAULT true, created_at TIMESTAMP, updated_at TIMESTAMP, created_by UUID REFERENCES users(id) ) ``` ### 2.4 iSCSI Tables ```sql iscsi_targets ( id UUID PRIMARY KEY, name VARCHAR(255) UNIQUE NOT NULL, alias VARCHAR(255), enabled BOOLEAN DEFAULT true, created_at TIMESTAMP, updated_at TIMESTAMP, created_by UUID REFERENCES users(id) ) iscsi_luns ( id UUID PRIMARY KEY, target_id UUID REFERENCES iscsi_targets(id), lun_number INTEGER, device_path VARCHAR(255), size_bytes BIGINT, created_at TIMESTAMP ) iscsi_initiators ( id UUID PRIMARY KEY, iqn VARCHAR(255) UNIQUE NOT NULL, created_at TIMESTAMP ) target_initiators ( target_id UUID REFERENCES iscsi_targets(id), initiator_id UUID REFERENCES iscsi_initiators(id), PRIMARY KEY (target_id, initiator_id) ) ``` ### 2.5 Tape Tables ```sql vtl_libraries ( id UUID PRIMARY KEY, name VARCHAR(255) UNIQUE NOT NULL, vendor VARCHAR(255), model VARCHAR(255), drive_count INTEGER, slot_count INTEGER, status VARCHAR(50), created_at TIMESTAMP, updated_at TIMESTAMP, created_by UUID REFERENCES users(id) ) physical_libraries ( id UUID PRIMARY KEY, vendor VARCHAR(255), model VARCHAR(255), serial_number VARCHAR(255), drive_count INTEGER, slot_count INTEGER, discovered_at TIMESTAMP ) ``` ### 2.6 Backup Tables ```sql backup_jobs ( id UUID PRIMARY KEY, name VARCHAR(255) UNIQUE NOT NULL, client_id INTEGER, fileset_id INTEGER, schedule VARCHAR(255), storage_pool_id INTEGER, enabled BOOLEAN DEFAULT true, created_at TIMESTAMP, updated_at TIMESTAMP, created_by UUID REFERENCES users(id) ) ``` ### 2.7 Monitoring Tables ```sql alerts ( id UUID PRIMARY KEY, rule_id UUID, severity VARCHAR(50), source VARCHAR(255), message TEXT, status VARCHAR(50), acknowledged_at TIMESTAMP, resolved_at TIMESTAMP, created_at TIMESTAMP ) alert_rules ( id UUID PRIMARY KEY, name VARCHAR(255) UNIQUE NOT NULL, description TEXT, source VARCHAR(255), condition_type VARCHAR(255), condition_config JSONB, severity VARCHAR(50), enabled BOOLEAN DEFAULT true, created_at TIMESTAMP, updated_at TIMESTAMP ) ``` ### 2.8 Audit Tables ```sql audit_logs ( id UUID PRIMARY KEY, user_id UUID REFERENCES users(id), action VARCHAR(255), resource_type VARCHAR(255), resource_id VARCHAR(255), method VARCHAR(10), path VARCHAR(255), ip_address VARCHAR(45), user_agent TEXT, request_body JSONB, response_status INTEGER, created_at TIMESTAMP ) ``` ### 2.9 Task Tables ```sql tasks ( id UUID PRIMARY KEY, type VARCHAR(255), status VARCHAR(50), progress INTEGER, result JSONB, error_message TEXT, created_at TIMESTAMP, updated_at TIMESTAMP, completed_at TIMESTAMP, created_by UUID REFERENCES users(id) ) ``` ## 3. Indexes ### 3.1 Performance Indexes ```sql -- Users CREATE INDEX idx_users_username ON users(username); CREATE INDEX idx_users_email ON users(email); -- Storage CREATE INDEX idx_zfs_pools_name ON zfs_pools(name); CREATE INDEX idx_zfs_datasets_pool_name ON zfs_datasets(pool_name); -- Shares CREATE INDEX idx_shares_dataset_id ON shares(dataset_id); CREATE INDEX idx_shares_created_by ON shares(created_by); -- iSCSI CREATE INDEX idx_iscsi_targets_name ON iscsi_targets(name); CREATE INDEX idx_iscsi_luns_target_id ON iscsi_luns(target_id); -- Monitoring CREATE INDEX idx_alerts_status ON alerts(status); CREATE INDEX idx_alerts_created_at ON alerts(created_at); CREATE INDEX idx_audit_logs_user_id ON audit_logs(user_id); CREATE INDEX idx_audit_logs_created_at ON audit_logs(created_at); ``` ## 4. Migrations ### 4.1 Migration System - **Location**: `db/migrations/` - **Naming**: `NNN_description.sql` - **Execution**: Sequential execution on startup - **Version Tracking**: `schema_migrations` table ### 4.2 Migration Files - `001_initial_schema.sql`: Core tables - `002_storage_and_tape_schema.sql`: Storage and tape tables - `003_performance_indexes.sql`: Performance indexes - `004_add_zfs_pools_table.sql`: ZFS pools - `005_add_zfs_datasets_table.sql`: ZFS datasets - `006_add_zfs_shares_and_iscsi.sql`: Shares and iSCSI - `007_add_vendor_to_vtl_libraries.sql`: VTL updates - `008_add_user_groups.sql`: User groups - `009_backup_jobs_schema.sql`: Backup jobs - `010_add_backup_permissions.sql`: Backup permissions - `011_sync_bacula_jobs_function.sql`: Bacula sync function ## 5. Data Relationships ### 5.1 Entity Relationships - **Users** → **Roles** (many-to-many) - **Roles** → **Permissions** (many-to-many) - **Users** → **Groups** (many-to-many) - **ZFS Pools** → **ZFS Datasets** (one-to-many) - **ZFS Datasets** → **Shares** (one-to-many) - **iSCSI Targets** → **LUNs** (one-to-many) - **iSCSI Targets** → **Initiators** (many-to-many) ## 6. Data Integrity ### 6.1 Constraints - **Primary Keys**: UUID primary keys for all tables - **Foreign Keys**: Referential integrity - **Unique Constraints**: Unique usernames, emails, names - **Check Constraints**: Valid status values, positive numbers ### 6.2 Cascading Rules - **ON DELETE CASCADE**: Child records deleted with parent - **ON DELETE RESTRICT**: Prevent deletion if referenced - **ON UPDATE CASCADE**: Update foreign keys on parent update ## 7. Query Optimization ### 7.1 Query Patterns - **Eager Loading**: Join related data when needed - **Pagination**: Limit and offset for large datasets - **Filtering**: WHERE clauses for filtering - **Sorting**: ORDER BY for sorted results ### 7.2 Caching Strategy - **Query Result Caching**: Cache frequently accessed queries - **Cache Invalidation**: Invalidate on write operations - **TTL**: Time-to-live for cached data ## 8. Backup & Recovery ### 8.1 Backup Strategy - **Regular Backups**: Daily database backups - **Point-in-Time Recovery**: WAL archiving - **Backup Retention**: 30 days retention ### 8.2 Recovery Procedures - **Full Restore**: Restore from backup - **Point-in-Time**: Restore to specific timestamp - **Selective Restore**: Restore specific tables