- Add PostgreSQL and SQLite database adapters with factory pattern - Add migration script for SQLite to PostgreSQL - Add production Dockerfiles and docker-compose configs - Add deployment documentation and scripts - Add BIA sync dashboard and matching service - Add data completeness configuration and components - Add new dashboard components (BusinessImportanceComparison, ComplexityDynamics, etc.) - Update various services and routes - Remove deprecated management-parameters.json and taxonomy files
12 KiB
Database Engine Aanbeveling - Azure Productie
Huidige Situatie
De applicatie gebruikt momenteel SQLite via better-sqlite3:
- cmdb-cache.db: ~20MB - CMDB object cache
- classifications.db: Classification history
Aanbeveling: PostgreSQL
Belangrijk: Azure Database for MariaDB wordt afgeschaft (retirement september 2025).
De keuze is daarom tussen PostgreSQL en MySQL (niet MariaDB).
PostgreSQL vs MySQL Vergelijking
| Feature | PostgreSQL | MySQL (Azure) |
|---|---|---|
| Azure Support | ✅ Flexible Server | ✅ Flexible Server |
| Kosten (B1ms) | ~€20-30/maand | ~€20-30/maand |
| JSON Support | ✅ JSONB (superieur) | ✅ JSON (basis) |
| Performance | ✅ Uitstekend | ✅ Goed |
| Concurrency | ✅ MVCC (zeer goed) | ✅ Goed |
| SQL Standards | ✅ Zeer compliant | ⚠️ Eigen dialect |
| Full-Text Search | ✅ Ingebouwd | ⚠️ Basis |
| Community | ✅ Groot & actief | ✅ Groot & actief |
| Development Tools | ✅ Uitstekend | ✅ Goed |
Voor jouw use case (JSON data, 20 gebruikers):
✅ PostgreSQL heeft voordeel:
- JSONB: Betere JSON performance en querying (gebruikt in huidige schema)
- MVCC: Betere concurrency voor 20 gelijktijdige gebruikers
- SQL Standards: Makkelijker migreren van SQLite
- Full-Text Search: Ingebouwd (handig voor toekomstige zoekfuncties)
✅ MySQL is ook goed:
- Vergelijkbare kosten
- Goede performance
- Veel gebruikt (bekende technologie)
Conclusie: Beide zijn goede keuzes. PostgreSQL heeft lichte voordelen voor JSON-heavy workloads en betere SQLite compatibiliteit.
Waarom PostgreSQL?
✅ Identieke Dev/Prod Stack
- Lokaal: PostgreSQL via Docker (gratis)
- Azure: Azure Database for PostgreSQL Flexible Server
- Zelfde database engine, zelfde SQL syntax
✅ Azure Integratie
- Native ondersteuning in Azure
- Managed service (geen server management)
- Betaalbaar: Basic tier ~€20-30/maand voor 20 gebruikers
✅ Performance
- Betere concurrency dan SQLite (20 gebruikers)
- Connection pooling (nodig voor web apps)
- Betere query performance bij groei
✅ Features
- JSON support (gebruikt in huidige schema)
- Transactions
- Foreign keys
- Full-text search (toekomstig)
✅ Development Experience
- Docker setup identiek aan productie
- Migraties mogelijk (Prisma, Knex, etc.)
- Betere tooling
Alternatief: SQLite Blijven
Voordelen:
- ✅ Geen migratie nodig
- ✅ Werkt in Azure App Service (file storage)
- ✅ Gratis
- ✅ Eenvoudig
Nadelen:
- ❌ Beperkte concurrency (kan problemen geven met 20 gebruikers)
- ❌ Geen connection pooling
- ❌ File-based (moeilijker backup/restore)
- ❌ Beperkte query performance bij groei
Conclusie: SQLite kan werken voor 20 gebruikers, maar PostgreSQL is beter voor productie.
Migratie naar PostgreSQL
Stappenplan
1. Database Abstraction Layer
Maak een database abstraction layer zodat we kunnen wisselen tussen SQLite (dev) en PostgreSQL (prod):
// backend/src/services/database/interface.ts
export interface DatabaseAdapter {
query(sql: string, params?: any[]): Promise<any[]>;
execute(sql: string, params?: any[]): Promise<void>;
transaction<T>(callback: (db: DatabaseAdapter) => Promise<T>): Promise<T>;
close(): Promise<void>;
}
2. PostgreSQL Adapter
// backend/src/services/database/postgresAdapter.ts
import { Pool } from 'pg';
export class PostgresAdapter implements DatabaseAdapter {
private pool: Pool;
constructor(connectionString: string) {
this.pool = new Pool({ connectionString });
}
async query(sql: string, params?: any[]): Promise<any[]> {
const result = await this.pool.query(sql, params);
return result.rows;
}
// ... implement other methods
}
3. SQLite Adapter (voor backward compatibility)
// backend/src/services/database/sqliteAdapter.ts
import Database from 'better-sqlite3';
export class SqliteAdapter implements DatabaseAdapter {
private db: Database.Database;
constructor(dbPath: string) {
this.db = new Database(dbPath);
}
async query(sql: string, params?: any[]): Promise<any[]> {
const stmt = this.db.prepare(sql);
return stmt.all(...(params || [])) as any[];
}
// ... implement other methods
}
4. Schema Migratie
SQLite → PostgreSQL verschillen:
INTEGER PRIMARY KEY AUTOINCREMENT→SERIAL PRIMARY KEYTEXT→TEXTofVARCHARJSON→JSONB(beter in PostgreSQL)ON CONFLICT→ON CONFLICT(werkt in beide)
SQLite → MySQL verschillen:
INTEGER PRIMARY KEY AUTOINCREMENT→INT AUTO_INCREMENT PRIMARY KEYTEXT→TEXTofVARCHAR(255)JSON→JSON(basis support)ON CONFLICT→ON DUPLICATE KEY UPDATE(andere syntax)
Azure Setup
Optie 1: Azure Database for PostgreSQL Flexible Server
Basic Tier (aanbevolen voor 20 gebruikers):
- Burstable B1ms: 1 vCore, 2GB RAM
- Storage: 32GB (meer dan genoeg voor 20MB database)
- Kosten: ~€20-30/maand
- Backup: 7 dagen retention (gratis)
Configuratie:
# Azure CLI
az postgres flexible-server create \
--resource-group rg-cmdb-gui \
--name psql-cmdb-gui \
--location westeurope \
--admin-user cmdbadmin \
--admin-password <secure-password> \
--sku-name Standard_B1ms \
--tier Burstable \
--storage-size 32 \
--version 15
Connection String:
postgresql://cmdbadmin:<password>@psql-cmdb-gui.postgres.database.azure.com:5432/cmdb?sslmode=require
Optie 2: Azure Database for MySQL Flexible Server
Basic Tier (aanbevolen voor 20 gebruikers):
- Burstable B1ms: 1 vCore, 2GB RAM
- Storage: 32GB (meer dan genoeg voor 20MB database)
- Kosten: ~€20-30/maand
- Backup: 7 dagen retention (gratis)
Configuratie:
# Azure CLI
az mysql flexible-server create \
--resource-group rg-cmdb-gui \
--name mysql-cmdb-gui \
--location westeurope \
--admin-user cmdbadmin \
--admin-password <secure-password> \
--sku-name Standard_B1ms \
--tier Burstable \
--storage-size 32 \
--version 8.0.21
Connection String:
mysql://cmdbadmin:<password>@mysql-cmdb-gui.mysql.database.azure.com:3306/cmdb?ssl-mode=REQUIRED
MySQL vs PostgreSQL voor jouw schema:
- JSON: MySQL heeft JSON type, maar PostgreSQL JSONB is sneller voor queries
- AUTOINCREMENT: MySQL gebruikt
AUTO_INCREMENT, PostgreSQL gebruiktSERIAL(beide werken) - ON CONFLICT: MySQL gebruikt
ON DUPLICATE KEY UPDATE, PostgreSQL gebruiktON CONFLICT(beide werken)
Local Development Setup
Optie 1: Docker Compose voor PostgreSQL
Voeg toe aan docker-compose.yml:
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: cmdb
POSTGRES_USER: cmdb
POSTGRES_PASSWORD: cmdb-dev
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U cmdb"]
interval: 10s
timeout: 5s
retries: 5
volumes:
postgres_data:
Optie 2: Docker Compose voor MySQL
Voeg toe aan docker-compose.yml:
services:
mysql:
image: mysql:8.0
environment:
MYSQL_DATABASE: cmdb
MYSQL_USER: cmdb
MYSQL_PASSWORD: cmdb-dev
MYSQL_ROOT_PASSWORD: root-dev
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
volumes:
mysql_data:
Environment variabelen (lokaal - PostgreSQL):
# .env.local
DATABASE_URL=postgresql://cmdb:cmdb-dev@localhost:5432/cmdb
# of
DATABASE_TYPE=postgres
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=cmdb
DATABASE_USER=cmdb
DATABASE_PASSWORD=cmdb-dev
Environment variabelen (Azure):
# Azure App Service Configuration
DATABASE_TYPE=postgres
DATABASE_HOST=psql-cmdb-gui.postgres.database.azure.com
DATABASE_PORT=5432
DATABASE_NAME=cmdb
DATABASE_USER=cmdbadmin
DATABASE_PASSWORD=<from-key-vault>
DATABASE_SSL=true
Environment variabelen (lokaal - MySQL):
# .env.local
DATABASE_URL=mysql://cmdb:cmdb-dev@localhost:3306/cmdb
# of
DATABASE_TYPE=mysql
DATABASE_HOST=localhost
DATABASE_PORT=3306
DATABASE_NAME=cmdb
DATABASE_USER=cmdb
DATABASE_PASSWORD=cmdb-dev
Environment variabelen (Azure - MySQL):
# Azure App Service Configuration
DATABASE_TYPE=mysql
DATABASE_HOST=mysql-cmdb-gui.mysql.database.azure.com
DATABASE_PORT=3306
DATABASE_NAME=cmdb
DATABASE_USER=cmdbadmin
DATABASE_PASSWORD=<from-key-vault>
DATABASE_SSL=true
Kosten Vergelijking
| Optie | Lokaal | Azure (maandelijks) | Totaal |
|---|---|---|---|
| PostgreSQL | Gratis (Docker) | €20-30 | €20-30 |
| MySQL | Gratis (Docker) | €20-30 | €20-30 |
| SQLite | Gratis | €0 (in App Service) | €0 |
| Azure SQL | SQL Server Express | €50-100 | €50-100 |
Aanbeveling: PostgreSQL - beste balans tussen kosten, performance en identieke stack.
MySQL is ook een goede keuze met vergelijkbare kosten en performance.
Migratie Script
SQLite naar PostgreSQL Converter
// scripts/migrate-sqlite-to-postgres.ts
import Database from 'better-sqlite3';
import { Pool } from 'pg';
async function migrate() {
// Connect to SQLite
const sqlite = new Database('./data/cmdb-cache.db');
// Connect to PostgreSQL
const pg = new Pool({
connectionString: process.env.DATABASE_URL
});
// Migrate cached_objects
const objects = sqlite.prepare('SELECT * FROM cached_objects').all();
for (const obj of objects) {
await pg.query(
`INSERT INTO cached_objects (id, object_key, object_type, label, data, jira_updated_at, jira_created_at, cached_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
ON CONFLICT (id) DO NOTHING`,
[obj.id, obj.object_key, obj.object_type, obj.label, obj.data, obj.jira_updated_at, obj.jira_created_at, obj.cached_at]
);
}
// Migrate relations, metadata, etc.
// ...
sqlite.close();
await pg.end();
}
Implementatie Plan
Fase 1: Database Abstraction (1-2 dagen)
- Maak
DatabaseAdapterinterface - Implementeer
PostgresAdapterenSqliteAdapter - Update
CacheStoreenDatabaseServiceom adapter te gebruiken
Fase 2: Local PostgreSQL Setup (0.5 dag)
- Voeg PostgreSQL toe aan docker-compose.yml
- Test lokaal met PostgreSQL
- Update environment configuratie
Fase 3: Schema Migratie (1 dag)
- Converteer SQLite schema naar PostgreSQL
- Maak migratie script
- Test migratie lokaal
Fase 4: Azure Setup (1 dag)
- Maak Azure Database for PostgreSQL
- Configureer connection string in Key Vault
- Test connectiviteit
Fase 5: Productie Migratie (0.5 dag)
- Migreer data van SQLite naar PostgreSQL
- Update App Service configuratie
- Test in productie
Totaal: ~3-4 dagen werk
Aanbeveling
🏆 PostgreSQL (Aanbevolen)
Gebruik PostgreSQL voor:
- ✅ Identieke dev/prod stack
- ✅ Betere JSON performance (JSONB)
- ✅ Betere concurrency (MVCC)
- ✅ Azure native ondersteuning
- ✅ Toekomstbestendig
- ✅ Betaalbaar (~€20-30/maand)
- ✅ Makkelijker migratie van SQLite (SQL syntax)
✅ MySQL (Ook goed)
MySQL is ook een goede keuze als:
- Je team meer ervaring heeft met MySQL
- Je voorkeur geeft aan MySQL ecosystem
- Vergelijkbare kosten en performance acceptabel zijn
- Je JSON queries niet te complex zijn
Nadelen t.o.v. PostgreSQL:
- ⚠️ Minder geavanceerde JSON support (geen JSONB)
- ⚠️ Minder SQL standards compliant
- ⚠️ Iets andere syntax voor conflicten
💰 SQLite (Minimale kosten)
SQLite blijft optie als:
- Je snel moet deployen zonder migratie
- Kosten kritiek zijn (€0 vs €20-30)
- Je accepteert beperkingen (concurrency, performance)
Conclusie: Voor jouw use case (JSON data, 20 gebruikers) is PostgreSQL de beste keuze, maar MySQL is ook prima. Beide zijn veel beter dan SQLite voor productie.
Next Steps
- Beslissing: PostgreSQL of SQLite blijven?
- Als PostgreSQL: Start met Fase 1 (Database Abstraction)
- Als SQLite: Documenteer beperkingen en overweeg toekomstige migratie