Antipatterns für die Arbeit mit Datenbanken

Hallo Habr! Ich präsentiere Ihnen die Übersetzung meines Artikels „Datenbank: Anti-Patterns“ .

Wenn Sie Daten speichern, ist dies ein wichtiger Teil Ihrer Anwendung. Sie können einfach und schnell eine Fehlerbehebung auf einer neuen Dating-Site beheben, sodass Bauer Joe aus Nordtexas endlich die letzte Nachricht von seinem Brieffreundliebhaber lesen und herausfinden kann, dass sie kahle Männer mag. Aber Gott bewahre, dass Sie Benutzerdaten verlieren oder ruinieren.

Bild
Silicon Valley, Staffel 2, Folge 8 .

Viele Entwickler verstehen diese einfache Wahrheit jedoch nicht vollständig. Ich bin seit vielen Jahren kein professioneller Programmierer mehr, aber ich habe bereits viele, viele Fehler gesehen, die von Leuten gemacht wurden, die mit der Datenbank arbeiten.

Hier sind nur diejenigen, die sofort in den Sinn kommen.

Fehlende Backups


Bild

"Backups erstellen" ist eine dieser Regeln (wie "Nicht unter der Wurzel arbeiten" oder "Sicherheitsgurte anlegen"), denen viele von uns zustimmen, die sie jedoch nicht befolgen, in der Hoffnung, dass anderen und nicht uns schlimme Dinge passieren.

Übrigens, wenn Sie die Wiederherstellung von Sicherungen nicht testen, können Sie davon ausgehen, dass Sie überhaupt keine Sicherungen haben. Lerne aus den Fehlern anderer :
Mit anderen Worten, von den fünf Sicherungstechnologien arbeitet niemand zuverlässig oder ist nicht konfiguriert. Am Ende haben wir die Daten aus dem vor 6 Stunden erstellten Backup wiederhergestellt.
Wir haben die Datenbankdaten innerhalb von 6 Stunden (Probleme, Zusammenführungsanforderungen, Benutzer, Kommentare, Snippets usw.) mit GitLab.com verloren.

NoSQL


Es kommt vor, dass Ihre Benutzer zu viele Inhalte für Erwachsene haben und diese zu oft ansehen. Die Datenmenge ist zu groß oder die Last ist zu hoch, als dass die relationale Datenbank sie verarbeiten könnte. Dies ist der Fall, wenn NoSQL-Technologien ins Spiel kommen. Software-Giganten wie Google kennen dies aus erster Hand.

Aber du bist nicht Google . Ein paar hundert Gigabyte sind keine „Big Data“, aber 1000 Kommentare pro Tag sind keine „hohe Last“. Höchstwahrscheinlich reicht PostgreSQL für Ihre Daten. Siehe: Es unterstützt sogar JSON und kann es indizieren .

Komm schon, möchten Sie ernsthaft eine zuverlässige Struktur für Funktionen opfern, die Sie nicht benötigen und - ehrlich gesagt - niemals benötigt werden? Sie werden nicht zum neuen Google - Sie haben nur ein Durcheinander in der Datenbank.

Zu lockeres Schema


Dies ist für NoSQL relevanter, aber Benutzer relationaler DBMS vergessen häufig oder sind zu faul, um alle erforderlichen Einschränkungen zu erstellen. Aufgrund eines Fehlers im Anwendungscode NULLkann dieser dort gespeichert werden, wo ein aussagekräftiger Wert erwartet wird, oder es kann ein Link zu einem fehlenden Eintrag erstellt werden. Anschließend bemerken Sie dies und korrigieren den Code, haben aber keine Ahnung, wie Sie die Daten reparieren sollen.

Natürliche Primärschlüssel


Stellen Sie sich vor, wir möchten Benutzer speichern, von denen jeder eine eindeutige E-Mail-Adresse haben muss. Die naheliegendste Lösung besteht darin, eine Tabelle usermit einer Spalte zu erstellen email, die auch der Primärschlüssel ist.

Leider kann der natürliche Schlüssel als primärer Schlüssel inakzeptabel werden, wenn sich die Anforderungen ändern (und sie sich ständig ändern). Heute PRIMARY KEY(email)funktioniert es und morgen beschließen wir, die Registrierung über Facebook hinzuzufügen und die E-Mail optional zu machen. Was ist besser: Generieren Sie eindeutige Adressen und fügen Sie ein Flag hinzu, das eine fiktive E-Mail kennzeichnet, oder ändern Sie den Primärschlüssel, alle Fremdschlüssel, auf die verwiesen userwird usw. usw.? Wir müssten uns nicht für das kleinere Übel entscheiden, wenn wir einfach einen Ersatzprimärschlüssel verwenden würden.

Logik im Speicher


Ich mag das aus zwei Gründen nicht:

  1. Anwendungscode ist normalerweise viel einfacher zu aktualisieren als ein Datenbankschema.
  2. Alle diese SQL-PLs erinnern mich an Pascal und sind genauso hässlich.

Umgebungsspezifische Migrationsskripte


Ich weiß, dass es manchmal keine Wahl gibt, aber im Allgemeinen ist es besser sicherzustellen, dass alle Umgebungen (Entwickler, Test, Produkt usw.) so ähnlich wie möglich sind. Je größer der Unterschied zwischen den Umgebungen ist, desto wahrscheinlicher ist es, dass ein Fehler gemacht wird und nur auf dem Produkt gefunden wird.

Normalerweise können sogar DML-Skripte universell sein. Meistens sind verschiedene Pläne rein böse.

Wenn ich daher umgebungsspezifische Labels in Liquibase-Skripten sehe, möchte ich töten.

Tolerante Migrationsskripte


IF NOT EXISTSund ähnliche Dinge in DDL sind nicht erforderlich, wenn in allen Umgebungen identische Schemata vorhanden sind, können jedoch Fehler maskieren. Wenn während des Datenbank-Updates etwas Unerwartetes passiert, möchte ich es lieber herausfinden und so schnell wie möglich beheben, anstatt mir eine Woche später den Kopf zu zerbrechen, wie das Problem behoben werden kann.

Nichtatomare Updates


Angenommen, Sie führen das Änderungsset auf Produktionsbasis aus und die Migration war nicht erfolgreich. Sie reparieren etwas und möchten es erneut versuchen. Wird es funktionieren? Was ist, wenn einige Änderungssatzvorgänge festgeschrieben werden, andere nicht?

Möglicherweise stellen Sie fest, dass dies tatsächlich eine Geschichte ist, bei der das Änderungsset idempotent sein sollte , und Sie werden Recht haben.

Leider verwenden viele Entwickler, die über Idempotenz nachdenken, IF NOT EXISTSoder ähnliches. Im vorherigen Abschnitt habe ich erklärt, warum dies böse ist.

Machen Sie stattdessen den Änderungssatz atomar . Im Fehlerfall werden die vorgenommenen Änderungen dann rückgängig gemacht, und Sie haben keine Probleme mit der nachfolgenden Anwendung dieses Änderungssatzes.

Aber seien Sie vorsichtig, wenn Sie mit Transaktionen rechnen. Zum Beispiel,Die Unterstützung für DDL-Ausdrücke in MySQL-Transaktionen ist dunkel und voller Horror. Daher erstelle ich beim Schreiben von Liquibase-Skripten für MySQL immer einen separaten Änderungssatz für jeden DDL-Ausdruck.

Welche Antimuster haben Sie gesehen?

Source: https://habr.com/ru/post/undefined/


All Articles