Add practical examples to multiple files

- LF9-03 Virtualisierung: Docker Compose + Volume examples
- LF6-02 Frontend: To-Do list practical example
- LF8-04 ETL: Complete ETL pipeline example
- LF6-04 Sicherheit: Express.js security headers
- LF2-04 Nutzwertanalyse: Cloud provider selection example
- LF9-04 Monitoring: Prometheus alerts + Python logging
This commit is contained in:
2026-03-13 12:01:15 +01:00
parent eb4a13ef7c
commit 7df533c7a2
7 changed files with 331 additions and 7 deletions

View File

@@ -80,6 +80,73 @@ Laptop B:
--- ---
## Praktisches Beispiel: Cloud-Anbieter Auswahl
### Szenario
Ein Unternehmen muss sich zwischen AWS, Azure und Google Cloud entscheiden.
### 1. Kriterien definieren
| Kriterium | Bedeutung |
|-----------|-----------|
| Preis | Kosten pro Monat |
| Leistung | Rechenleistung, Geschwindigkeit |
| Sicherheit | Zertifizierungen, Features |
| Support | Deutsche Ansprechpartner |
| Skalierbarkeit | Einfache Erweiterung |
### 2. Gewichtung
| Kriterium | Gewichtung |
|-----------|------------|
| Preis | 25% |
| Leistung | 30% |
| Sicherheit | 25% |
| Support | 10% |
| Skalierbarkeit | 10% |
| **Summe** | **100%** |
### 3. Bewertung (1-10)
| Kriterium | Gewichtung | AWS | Azure | Google Cloud |
|-----------|------------|-----|-------|--------------|
| Preis | 25% | 7 | 8 | 9 |
| Leistung | 30% | 9 | 8 | 9 |
| Sicherheit | 25% | 9 | 8 | 8 |
| Support | 10% | 7 | 8 | 6 |
| Skalierbarkeit | 10% | 9 | 8 | 9 |
### 4. Berechnung
```
AWS:
= 0,25×7 + 0,30×9 + 0,25×9 + 0,10×7 + 0,10×9
= 1,75 + 2,70 + 2,25 + 0,70 + 0,90
= 8,30
Azure:
= 0,25×8 + 0,30×8 + 0,25×8 + 0,10×8 + 0,10×8
= 2,00 + 2,40 + 2,00 + 0,80 + 0,80
= 8,00
Google Cloud:
= 0,25×9 + 0,30×9 + 0,25×8 + 0,10×6 + 0,10×9
= 2,25 + 2,70 + 2,00 + 0,60 + 0,90
= 8,45
```
### 5. Ergebnis
| Anbieter | Nutzwert | Rang |
|----------|----------|------|
| Google Cloud | 8,45 | 1 |
| AWS | 8,30 | 2 |
| Azure | 8,00 | 3 |
**Empfehlung:** Google Cloud (aufgrund des besten Preis-Leistungs-Verhältnisses)
---
## Vorlage ## Vorlage
### Nutzwertanalyse - Vorlage ### Nutzwertanalyse - Vorlage

View File

@@ -6,13 +6,13 @@ Dieses Lernfeld behandelt die Entwicklung und Verwaltung von Datenbanken.
## Themen ## Themen
| Nr. | Thema | Beschreibung | | Nr. | Thema | Beschreibung | |
|-----|-------|-------------| | --- | ---------------------------- | --------------------- | ---------------------------------------- |
| 3.1 | [[LF3-01-Datenbankgrundlagen|Datenbankgrundlagen]] | Grundbegriffe, DBMS, Datenmodelle | | 3.1 | [[LF3-01-Datenbankgrundlagen | Datenbankgrundlagen]] | Grundbegriffe, DBMS, Datenmodelle |
| 3.2 | [[LF3-02-Datenmodellierung|Datenmodellierung]] | ER-Modell, Normalisierung | | 3.2 | [[LF3-02-Datenmodellierung | Datenmodellierung]] | ER-Modell, Normalisierung |
| 3.3 | [[LF3-03-SQL-Grundlagen|SQL-Grundlagen]] | SELECT, INSERT, UPDATE, DELETE | | 3.3 | [[LF3-03-SQL-Grundlagen | SQL-Grundlagen]] | SELECT, INSERT, UPDATE, DELETE |
| 3.4 | [[LF3-04-SQL-Abfragen|SQL-Abfragen]] | JOINs, Aggregatfunktionen, Unterabfragen | | 3.4 | [[LF3-04-SQL-Abfragen | SQL-Abfragen]] | JOINs, Aggregatfunktionen, Unterabfragen |
| 3.5 | [[LF3-05-Datenbankmanagement|Datenbankmanagement]] | Rechte, Sicherheit, Backup | | 3.5 | [[LF3-05-Datenbankmanagement | Datenbankmanagement]] | Rechte, Sicherheit, Backup |
## Lernziele ## Lernziele

View File

@@ -99,6 +99,45 @@ element.setAttribute("class", "neu");
element.getAttribute("href"); element.getAttribute("href");
``` ```
### Praktisches Beispiel: To-Do-Liste
```html
<!-- HTML -->
<input type="text" id="todo-input" placeholder="Neue Aufgabe">
<button id="add-btn">Hinzufügen</button>
<ul id="todo-list"></ul>
```
```javascript
// JavaScript
const input = document.getElementById('todo-input');
const button = document.getElementById('add-btn');
const list = document.getElementById('todo-list');
button.addEventListener('click', () => {
const text = input.value.trim();
if (text) {
// Neues Element erstellen
const li = document.createElement('li');
li.textContent = text;
// Löschen-Button
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'X';
deleteBtn.onclick = () => li.remove();
li.appendChild(deleteBtn);
list.appendChild(li);
input.value = '';
}
});
// Enter-Taste Support
input.addEventListener('keypress', (e) => {
if (e.key === 'Enter') button.click();
});
```
### Events ### Events
```javascript ```javascript

View File

@@ -80,6 +80,29 @@ function escapeHtml(text) {
Content-Security-Policy: default-src 'self'; script-src 'self' Content-Security-Policy: default-src 'self'; script-src 'self'
``` ```
### Praktisches Beispiel: Express.js Sicherheits-Header
```javascript
const helmet = require('helmet');
const cors = require('cors');
app.use(helmet());
// CORS konfigurieren
app.use(cors({
origin: 'https://meine-app.de',
credentials: true
}));
// Rate Limiting
const rateLimit = require('express-rate-limit');
app.use('/api/', rateLimit({
windowMs: 15 * 60 * 1000, // 15 Minuten
max: 100, // Max 100 Anfragen
message: 'Zu viele Anfragen, bitte später versuchen'
}));
```
--- ---
## CSRF (Cross-Site Request Forgery) ## CSRF (Cross-Site Request Forgery)

View File

@@ -207,6 +207,81 @@ ETL - Fehlerstrategien
--- ---
## Praktisches Beispiel: Vollständiger ETL-Pipeline
```python
import pandas as pd
import requests
from sqlalchemy import create_engine
import logging
# Logging konfigurieren
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def etl_pipeline():
"""
Vollständiger ETL-Pipeline für Verkaufsdaten
"""
# === EXTRACT ===
logger.info("Starte Extraktion...")
# Aus CSV
kunden_df = pd.read_csv('daten/kunden.csv')
bestellungen_df = pd.read_csv('daten/bestellungen.csv')
# Aus API
try:
response = requests.get('https://api.shop.de/produkte', timeout=30)
produkte_df = pd.DataFrame(response.json())
except Exception as e:
logger.error(f"API Fehler: {e}")
produkte_df = pd.DataFrame()
logger.info(f"Extrahiert: {len(kunden_df)} Kunden, {len(bestellungen_df)} Bestellungen")
# === TRANSFORM ===
logger.info("Starte Transformation...")
# Daten bereinigen
kunden_df = kunden_df.drop_duplicates()
kunden_df['email'] = kunden_df['email'].str.lower().str.strip()
kunden_df['erstellt_am'] = pd.to_datetime(kunden_df['erstellt_am'])
# Berechnungen
bestellungen_df['umsatz_mit_mwst'] = bestellungen_df['umsatz_netto'] * 1.19
# JOIN: Bestellungen mit Kunden verbinden
merged_df = bestellungen_df.merge(
kunden_df[['kunden_id', 'name', 'stadt']],
on='kunden_id',
how='left'
)
# Aggregation: Umsatz pro Stadt
umsatz_pro_stadt = merged_df.groupby('stadt')['umsatz_netto'].sum().reset_index()
logger.info(f"Transformation abgeschlossen: {len(merged_df)} Datensätze")
# === LOAD ===
logger.info("Starte Laden...")
# Datenbank-Verbindung
engine = create_engine('postgresql://user:pass@localhost:5432/warehouse')
# In Datenbank laden
merged_df.to_sql('fact_bestellungen', engine, if_exists='replace', index=False)
umsatz_pro_stadt.to_sql('dim_umsatz_stadt', engine, if_exists='replace', index=False)
logger.info("ETL Pipeline erfolgreich abgeschlossen!")
if __name__ == '__main__':
etl_pipeline()
```
---
## Querverweise ## Querverweise
- [[LF8-03-Datenformate|Zurück: Datenformate]] - [[LF8-03-Datenformate|Zurück: Datenformate]]

View File

@@ -108,6 +108,59 @@ EXPOSE 3000
CMD ["node", "server.js"] CMD ["node", "server.js"]
``` ```
### Praktisches Beispiel: Docker Compose
```yaml
# docker-compose.yml
version: '3.8'
services:
# Webanwendung
app:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://db:5432/webapp
depends_on:
- db
- redis
# Datenbank
db:
image: postgres:15-alpine
volumes:
- db_data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=geheim
- POSTGRES_DB=webapp
# Cache
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
db_data:
```
### Praktisches Beispiel: Docker Volume
```bash
# Volume erstellen
docker volume create mydata
# Volume einhängen
docker run -v mydata:/data ubuntu
# Volumes auflisten
docker volume ls
# Unbenutzte Volumes löschen
docker volume prune
```
--- ---
## Kubernetes ## Kubernetes

View File

@@ -61,6 +61,73 @@ scrape_configs:
- targets: ['localhost:9100'] - targets: ['localhost:9100']
``` ```
### Praktisches Beispiel: Alert-Regeln
```yaml
# alerts.yml
groups:
- name: server_alerts
rules:
# Hohe CPU-Auslastung
- alert: HighCPU
expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "Hohe CPU-Auslastung auf {{ $labels.instance }}"
description: "CPU Auslastung ist seit 5 Minuten über 80%"
# Wenig Speicherplatz
- alert: DiskSpaceLow
expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 10
for: 2m
labels:
severity: critical
annotations:
summary: "Wenig Speicherplatz auf {{ $labels.instance }}"
# Service ausgefallen
- alert: ServiceDown
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "{{ $labels.job }} Service ausgefallen"
```
### Praktisches Beispiel: Python Logging
```python
import logging
import logging.handlers
import sys
# Logger konfigurieren
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(sys.stdout),
logging.handlers.RotatingFileHandler(
'app.log',
maxBytes=10_000_000, # 10 MB
backupCount=5
)
]
)
logger = logging.getLogger(__name__)
# Log-Ebenen nutzen
logger.debug("Detaillierte Debug-Info")
logger.info("Anwendung gestartet")
logger.warning("Warnung: Konfiguration fehlt")
logger.error("Fehler: Datenbank nicht erreichbar")
logger.critical("Kritisch: System muss heruntergefahren werden")
```
### Grafana Dashboard ### Grafana Dashboard
``` ```