Guide

Zeitstempel vs. DateTime: Vollständiger Leitfaden

Einführung

Bei der Softwareentwicklung und Datenbankverwaltung ist die Wahl zwischen den Typen Zeitstempel und DateTime eine wichtige Entscheidung, die sich auf die Speichereffizienz, die Abfrageleistung und das Anwendungsverhalten auswirkt. Dieser Leitfaden bietet einen umfassenden Vergleich, der Ihnen dabei hilft, fundierte Entscheidungen zu treffen.

Den Unterschied verstehen

Was ist ein Zeitstempel?

Ein Zeitstempel ist eine numerische Darstellung der Zeit, die die Anzahl der Sekunden/Millisekunden/Nanosekunden seit einer bestimmten Epoche zählt. Die häufigste Epoche ist die Unix-Epoche (1. Januar 1970, 00:00:00 UTC).

Was ist DateTime?

DateTime ist ein strukturierter Datentyp, der Datums- und Uhrzeitkomponenten separat speichert:

  • Jahr (z. B. 2025)
  • Monat (1-12)
  • Tag (1-31)
  • Stunde (0-23)
  • Minute (0-59)
  • Zweiter (0-59)
  • Enthält häufig Zeitzoneninformationen
FunktionZeitstempelDatumUhrzeit
DatentypNumerisch (Ganzzahl/Float)Strukturiertes Objekt mit separaten Komponenten
Speichergröße4-8 Bytes (abhängig von der Genauigkeit)Variable (normalerweise 16–24+ Bytes)
LesbarkeitNiedrig (Konvertierung erforderlich)Hoch (für Menschen lesbar)
IndizierungAusgezeichnet (Zahlenvergleich)Schlecht (erfordert String-Analyse)
ZeitzonenunterstützungImplizit (normalerweise UTC)Integriert (kann Zeitzonenversatz speichern)
SortierenSchnell (numerischer Vergleich)Langsam (erfordert Datum/Uhrzeit-Analyse)
ArithmetikSchnell (direkte Mathematik)Langsam (erfordert Datum/Uhrzeit-Konvertierung)

Speichervergleich

MySQL

AspektZEITSTEMPELDATUMZEIT
Reichweite01.01.1970 00:00:00 bis 19.01.2038 03:14:071000-01-01 00:00:00 bis 9999-12-31 23:59:59
Lagerung4 Byte8 Byte
ZeitzoneKeine ZeitzonenunterstützungSpeichert die Zeitzone separat
AnwendungsfallEreignisprotokollierung, Point-in-Time-VerfolgungKalenderdaten, Geschäftszeiten speichern

Wichtig: MySQL TIMESTAMP wird unter dem Jahr-2038-Problem leiden. Verwenden Sie DATETIME für Daten nach 2038 oder erwägen Sie ein Upgrade auf BIGINT-Zeitstempel.

PostgreSQL

AspektZEITSTEMPELTIMESTAMPTZ
Reichweite1970-01-01 00:00:00 bis 294276-12-31 23:59:594713 v. Chr. bis 294276 n. Chr.
Lagerung8 Byte8 Byte
ZeitzoneKeine ZeitzonenunterstützungSpeichert die Zeitzone separat
SekundenbruchteileNeinJa (Mikrosekundengenauigkeit)
AnwendungsfallEreignisprotokollierung, SystemereignissePräzise Geschäftszeit speichern

SQL Server

AspektDATUMZEITDATETIME2
PräzisionAuf 0,003 Sekunden genauAuf die nächsten 0,0000033 Sekunden
Reichweite1753-01-01 00:00:00 bis 9999-12-31 23:59:59.9970001-01-01 00:00:00 bis 9999-12-31 23:59:59.997
Lagerung8 Byte8 Byte
Zeichenlänge23 Zeichen (JJJJ-MM-TT HH:MM:SS)27 Zeichen (JJJJ-MM-TT HH:MM:SS.nnnnnnn)

Leistungsvergleich

Speichereffizienz

Zeitstempel sind 3-6x speichereffizienter als DateTime-Strings. Dies ist für Tabellen mit hohem Volumen von entscheidender Bedeutung und kann die Datenbankgröße erheblich reduzieren.

Abfrageleistung

BetriebZeitstempelDatumUhrzeit
GleichheitsprüfungO(1) – einzelner numerischer VergleichO(n) – erfordert String-Analyse und -Vergleich
Bereichsabfrage (WHERE col >= X AND col <= Y)O(1) – numerischer BereichO(n) – erfordert Datum/Uhrzeit-Analyse für jede Zeile
Sortieren (ORDER BY)O(n log n) – numerische SortierungO(n²) – String-Vergleich pro Zeile
IndizierungAusgezeichnet - kompakte numerischeSchlecht – große Zeichenfolgen für die Indizierung
Gruppierung/AggregationSchnell - numerische OperationenLangsam – erfordert Datum/Uhrzeit-Extraktion und -Konvertierung

Schlüsselfindung: Zeitstempel bieten eine deutlich bessere Abfrageleistung für alle Vorgänge außer dem String-Pattern-Matching. DateTime erfordert einen Analyseaufwand für jede Abfrage.

Best Practices

Wann Zeitstempel verwendet werden sollten

Zeitstempel verwenden, wenn:

  1. Ereignisprotokollierung und Zeitreihen

    • Anwendungsprotokolle, Sensordaten, Finanztransaktionen
    • Eine genaue chronologische Reihenfolge ist erforderlich
    • Vorteile: Schnelle Sortierung, kompakte Lagerung, einfache Sortimentsabfrage
  2. Point-in-Time-Tracking

    • Erfassen Sie die Erstellungs-/Änderungszeiten
    • Berechnen Sie Metriken für die Zeit bis zur Lösung
    • Vorteile: Einfache Arithmetik für Dauerberechnungen
  3. Systemereignisse und Planung

    • Cron-Jobs, Aufgabenwarteschlangen, Prozessüberwachung
    • Vorteile: Numerischer Vergleich für die Planungslogik
  4. Zeitliche Daten mit hohem Volumen

    • IoT-Sensorwerte, Leistungsmetriken
    • Vorteile: Speichereffizienz, Abfrageleistung
  5. API-Antworten und Ablauf

    • Token-Ablaufdaten, Cache-TTL
    • Vorteile: Einfacher numerischer Vergleich, minimaler Speicherplatz
  6. Caching und Sitzungsverwaltung

    • Cache-Schlüssel, Sitzungsablauf
    • Vorteile: Schnelle Invalidierung, einfache TTL-Arithmetik

Wann DateTime verwendet werden sollte

Verwenden Sie DateTime, wenn:

  1. Von Menschen lesbares Display
    • Benutzeroberfläche, die Benutzern Daten anzeigt
    • Kalenderansichten und Planer
  • Vorteile: Keine Konvertierung erforderlich, benutzerfreundliches Format
  1. Geschäftsdatumslogik

    • Arbeitstage, Feiertage, Geschäftsperioden
    • Vorteile: Integrierte Datumsberechnung, Zeitzonenverwaltung
  2. Mehrkomponentige Datumsdarstellung

    • Datums- und Uhrzeitkomponenten getrennt
    • Vorteile: Datenbankspezifische Optimierungen, Übersichtlichkeit
  3. Komplexe Datumsberechnungen

    • Wiederkehrende Termine, Jubiläen – Vorteile: Native Datumsbibliotheken verarbeiten Randfälle
  4. Zeitzonenabhängige Speicherung

    • Örtliche Geschäftszeiten, regionale Veranstaltungen
    • Vorteile: Korrekte Beibehaltung der Zeitzone
  5. Kalenderintegration

    • UI-Kalender, Planungssysteme
    • Vorteile: Direkte Zuordnung zu Kalenderdaten

Hybride Ansätze

Zeitstempel speichern, Index für Menschenlesbarkeit verwenden

Einige Systeme verwenden einen Hybridansatz:

  • Speichern Sie aus Effizienzgründen einen Zeitstempel in der Datenbank
  • Verwenden Sie berechnete Indizes oder Datenbankfunktionen, um bei Bedarf eine für Menschen lesbare Formatierung vorzunehmen
-- MySQL: Using computed column for human-readable format
CREATE TABLE events (
  id BIGINT PRIMARY KEY,
  event_timestamp BIGINT NOT NULL,
  event_date DATETIME AS (FROM_UNIXTIME(event_timestamp)),
  INDEX idx_timestamp (event_timestamp),
  INDEX idx_date (event_date)
);

DateTime verwenden, konvertierte Zeitstempel im Cache speichern

Für Anwendungen, die sowohl effiziente Speicherung als auch schnelle Anzeige erfordern:

  • Speichern Sie DateTime zur besseren Lesbarkeit
  • Zwischenspeichern von konvertierten Zeitstempeln für Abfragen
  • Verwenden Sie separate Indizes für unterschiedliche Abfragemuster
// Application logic: cache both representations
const cache = new Map();

function getEvent(id) {
  if (cache.has(id)) {
    return cache.get(id);
  }

  const event = db.query('SELECT * FROM events WHERE id = ?', [id]);

  // Cache both forms
  cache.set(id, {
    timestamp: event.event_timestamp,
    date: event.event_date,
  });

  return event;
}

Implementierungsbeispiele

Best Practices für MySQL

MySQL-Implementierung

-- Recommendation: Use DATETIME for display, TIMESTAMP for range queries

-- Bad: Storing both (redundant)
CREATE TABLE orders_bad (
  id INT PRIMARY KEY,
  order_timestamp TIMESTAMP,
  order_date DATETIME,
  order_amount DECIMAL(10,2)
);

-- Good: Use TIMESTAMP for queries, generate DATETIME on demand
CREATE TABLE orders_good (
  id INT PRIMARY KEY,
  order_timestamp TIMESTAMP NOT NULL,
  order_amount DECIMAL(10,2)
);

-- Query: Range by timestamp (fast)
SELECT id, order_amount
FROM orders_good
WHERE order_timestamp >= UNIX_TIMESTAMP('2025-01-01 00:00:00')
  AND order_timestamp <= UNIX_TIMESTAMP('2025-01-31 23:59:59');

-- Application: Format on demand for display
SELECT id, 
       order_amount,
       DATE_FORMAT(order_timestamp, '%Y-%m-%d %H:%i') AS readable_date
FROM orders_good;

Best Practices für PostgreSQL

PostgreSQL-Implementierung

-- Use TIMESTAMPTZ for timezone-aware timestamps
CREATE TABLE events (
  id BIGSERIAL PRIMARY KEY,
  event_time TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  event_date TIMESTAMP WITH TIME ZONE 'UTC' AS (event_time AT TIME ZONE 'UTC'),
  INDEX idx_event_time (event_time)
);

-- Query by time range (efficient)
SELECT id, event_time
FROM events
WHERE event_time >= '2025-01-01 00:00:00 UTC'::timestamptz
  AND event_time < '2025-01-31 23:59:59 UTC'::timestamptz;

Best Practices für Anwendungen

JavaScript/Node.js

// Use timestamps for storage, format for display
const event = {
  timestamp: Date.now(),  // Unix timestamp in milliseconds
  created_at: new Date().toISOString(),  // ISO 8601 for storage
};

// Database query using timestamp (fast)
const events = db.query(`
  SELECT * FROM events 
  WHERE event_timestamp >= ? 
  ORDER BY event_timestamp
`, [event.timestamp]);

// Format timestamp for display
const formatDate = (timestamp) => {
  return new Date(timestamp).toLocaleString();
};
// Cache converted DateTime to avoid repeated conversions
const dateCache = new Map();

function getEventDate(eventId) {
  if (dateCache.has(eventId)) {
    return dateCache.get(eventId);
  }

  const { event_timestamp, created_at, updated_at } = await db.query(
    'SELECT event_timestamp, created_at, updated_at FROM events WHERE id = ?',
    [eventId]
  );

  // Cache formatted date (expensive conversion)
  dateCache.set(eventId, {
    formatted: formatDate(event_timestamp),
    created: formatDate(created_at),
    updated: formatDate(updated_at),
  });

  return dateCache.get(eventId);
}

Python

# Use timestamp for storage, datetime for display
from datetime import datetime

def create_event():
    return {
        'timestamp': int(datetime.now().timestamp()),  # Unix timestamp
        'created_at': datetime.now().isoformat()  # ISO 8601 for display
    }

def query_events_by_range(start_ts, end_ts):
    # Fast query using timestamp comparison
    start_dt = datetime.fromtimestamp(start_ts)
    end_dt = datetime.fromtimestamp(end_ts)

    # Query database
    events = Event.objects.filter(
        timestamp__gte=start_dt,
        timestamp__lte=end_dt
    )

    return events
# Cache formatted dates to avoid repeated conversions
from functools import lru_cache

@lru_cache(maxsize=1000)
def get_formatted_date(timestamp):
    # Expensive conversion (cached)
    return datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M')

Anti-Patterns

Häufige Fehler, die es zu vermeiden gilt:

  1. Speichern von Zeitstempel und Datum/Uhrzeit
   -- DON'T: This doubles storage and creates redundancy
   CREATE TABLE bad (
     id INT,
     created TIMESTAMP,
     created_date DATETIME  -- REDUNDANT
   );

```2. **DateTime für Bereichsabfragen verwenden**
```sql
   -- DON'T: This requires string parsing for every row
   SELECT * FROM events
   WHERE created_date >= '2025-01-01'
     AND created_date <= '2025-01-31';

```3. **Zeitstempel als VARCHAR speichern**
```sql
   -- DON'T: Loses numeric benefits and string operations
   CREATE TABLE bad (
     id INT,
     timestamp_str VARCHAR(255)  -- USE BIGINT
   );

```4. **Keine Indizes für Zeitstempelspalten verwenden**
```sql
   -- DON'T: Full table scans on large tables
   SELECT * FROM orders
   WHERE created_timestamp > UNIX_TIMESTAMP('2025-01-01');

```5. **Konvertieren des Zeitstempels in DateTime für jede Abfrage**
```javascript
   -- DON'T: Unnecessary CPU overhead
   events.forEach(event => {
     const date = new Date(event.timestamp * 1000);
     // Only convert for display, don't use in queries
   });

Migrationsstrategien

Von DateTime zu Timestamp

Wenn Sie vorhandene DateTime-Spalten in Zeitstempel migrieren müssen:

-- MySQL: Add new timestamp column with default value
ALTER TABLE orders ADD COLUMN order_timestamp BIGINT 
DEFAULT (UNIX_TIMESTAMP(created_at));

-- Backfill existing data
UPDATE orders 
SET order_timestamp = UNIX_TIMESTAMP(created_at)
WHERE order_timestamp IS NULL;

-- After verification, you can drop the old column
-- ALTER TABLE orders DROP COLUMN created_at;

Vom Zeitstempel zum DateTime

-- Use generated column for human-readable dates
SELECT 
  id,
  order_timestamp,
  DATE_FORMAT(order_timestamp, '%Y-%m-%d %H:%i') AS readable_date
FROM orders
WHERE order_timestamp >= UNIX_TIMESTAMP('2025-01-01 00:00:00');

Entscheidungsrahmen

Nutzen Sie diese Checkliste, um die richtige Wahl zu treffen:

FrageJa → ZeitstempelJa → DateTime
Müssen Sie Zeitbereichsabfragen durchführen?
Müssen Sie chronologisch sortieren?
Ist der Speicherplatz ein Problem?
Benötigen Sie schnelle Gleichheits-/Bereichsabfragen?
Benötigen Sie Zeitzonenunterstützung?
Benötigen Sie eine für Menschen lesbare Anzeige?
Gilt dies für die Ereignisprotokollierung oder für Zeitreihen?
Gilt das für Kalender-/Geschäftstermine?

Empfehlung: Viele Anwendungen profitieren von einem Hybridansatz – speichern Sie Zeitstempel für Abfragen, verwenden Sie berechnete Spalten oder Formatierung auf Anwendungsebene für die Anzeige.

Fazit

Die Wahl zwischen Zeitstempeln und DateTime ist keine allgemeingültige Entscheidung. Bedenken Sie:

  • Abfragemuster (wie Sie auf die Daten zugreifen)
  • Leistungsanforderungen (Datenvolumen, Abfragekomplexität)
  • Speicherbeschränkungen (Datenbankgröße, Speichernutzung)
  • Anforderungen an die Benutzererfahrung (Lesbarkeit, Lokalisierung)

Wichtige Erkenntnisse: Zeitstempel bieten eine überlegene Leistung für Datenvorgänge, während DateTime eine bessere Benutzererfahrung bietet. Die beste Lösung verwendet Zeitstempel oft intern und formatiert sie für die Anzeige bei Bedarf.

Verwandte Tools