Sollten Sie die Datenbank entwerfen, bevor der Anwendungscode geschrieben wird?


57

Was ist der einfachste und effizienteste Weg, eine Datenbank zu entwerfen? Aus meiner Sicht gibt es einige Optionen für das Design des Datenspeichers einer Anwendung:

  1. Entwerfen Sie die Datenbank so gut wie möglich, bevor Sie Anwendungscode schreiben . Dies gibt Ihnen den Vorteil, eine Basisdatenstruktur zu haben, von der Sie abarbeiten können. Dies hat meiner Meinung nach den Nachteil, dass Sie eine Vielzahl von Änderungen an den Anwendungsspezifikationen vornehmen müssen , die sich darauf auswirken, was / wo / wie sich die Daten während des gesamten Anwendungsentwicklungszyklus ändern.
  2. Entwerfen Sie die Datenbank, sobald die Anwendung zum Tragen kommt . Wenn Sie beim Schreiben der Anwendung einige Datenbankobjekte benötigen, entwickeln Sie die Datenbank parallel (chronologisch) zur Anwendung. Die Vorteile wären weniger Änderungen an der Datenbankstruktur, wie ich es sehe. Der Nachteil wäre die Aufteilung von Zeit und Entwicklungsaufwand zwischen Anwendungscode und Datenbankentwicklung.

Was ist Ihrer Erfahrung nach die produktivste und effizienteste Methode?



1
Vielleicht findest du flywaydb.org interessant. Es ermöglicht Ihnen die Versionskontrolle Ihres Datenbankschemas.
Thorbjørn Ravn Andersen

Antworten:


41

Neben anderen Antworten ...

Wenn Sie zuerst Ihr konzeptionelles Modell erfassen, sollten Umfang und Anforderungen definiert werden. Daraus können Sie Ihre logischen und physischen Datenmodelle ableiten.

Sobald dies meist statisch ist, haben Sie eine stabile Datenbank, gegen die Sie Ihre Anwendung erstellen können. Dies widerspricht Ihrer ersten Option.

Ihr zweiter Punkt endet in einem chaotischen, nicht zu wartenden Schlammballen . Das Datenmodell wird nie repariert: Wenn Sie es nicht im Voraus entworfen haben, haben Sie keine Zeit, es vor dem Versand zu reparieren. Sie werden zu beschäftigt sein, Dinge zusammen zu hacken.

Kleinere Änderungen am Schema, das Kombinieren oder Aufteilen von Tabellen, das Ändern von Beziehungen usw. werden durchgeführt, aber auf lokalisierten "Inseln" bleibt Ihr Modell + Basisdesign unverändert.


6
Und Stabilität ist wichtig, da Tabellen- und Ansichtsnamen, Spaltennamen, Namen gespeicherter Prozeduren usw. die öffentliche Schnittstelle der Datenbank sind. (Und früher oder später wird es viele Anwendungen geben, die diese Schnittstelle gemeinsam nutzen.)
Mike Sherrill 'Cat Recall'

Ich würde sagen, dies ist ein ziemlich idealisierter Ansatz. Ich habe die Erfahrung gemacht, dass sich von Zeit zu Zeit drastische Änderungen ergeben müssen, um agil zu sein und uns schnell an neue Anforderungen anzupassen und das Refactoring fortzusetzen.
Zinking

@zinking: Ich mache gerade das Agile-Ding.
21.

@gbn, Entschuldigung, die folgende Frage hier zu stellen. Ich habe keine Ahnung, wie ich mit dem Szenario umgehen soll. Bitte schauen Sie. stackoverflow.com/questions/46285924/… . Bitte schlagen Sie mir die bessere Lösung vor.
RGS

27

Es wird Ihnen schwer fallen, eine moderne Softwareabteilung zu finden, die keine Agile-Variante betreibt. DBAs hingegen stecken im Dunkeln und denken, dass die Antwort von @ RobPaller noch alltäglich ist.

Das Ändern eines Datenbankschemas war noch nie so einfach wie das Ändern von Code. Aus diesem Grund zögerte man, bei der Datenbankentwicklung und -wartung einen agilen Ansatz zu wählen. Jetzt, da wir die Werkzeuge und Techniken haben, um ähnlich wie Entwickler zu arbeiten, sollten wir dies auf jeden Fall tun. Nur weil es nicht einfach ist, das Schema zu ändern, heißt das nicht, dass Sie es nicht können und dass Sie es nicht sollten.

Ich befürworte keinen willkürlichen Ansatz für das Datenbankdesign (siehe Kommentare), sondern nur einen Ansatz, der dem eines agilen Entwicklungsteams besser entspricht. Wenn Sie Teil eines agilen Projekts sind, werden Sie keine Arbeitsanforderungen haben, die möglicherweise ( oder möglicherweise nicht ) in der Zukunft auftreten. Entwerfen Sie also für das, was Sie wissen, dass es erforderlich ist, nicht für das, was möglicherweise erforderlich ist.

Ich schätze, das stimmt mit Ihrer Option 2 überein und ich vermute, dass ich in dieser Option in der Kälte stehe!


4
Agilität und Datenbanken gehen mit Einschränkungen einher. Agilität ist die Grenze für VLDBs: Möglicherweise ist nicht genügend Zeit vorhanden, um Änderungen an Milliarden Zeilentabellen zwischen den zu liefernden Ergebnissen zu validieren und zu testen. Und "Agile Entwicklung" ist nicht dasselbe wie "Umdenken", da es an Voraussicht mangelt
gbn 11.10.11

2
Hätte nicht besser sein können: Mangel an Voraussicht, aber ich denke nicht, dass das für die Frage relevant ist. Hier geht es nicht darum, ob Sie sich dem Design willkürlich nähern sollten, sondern ob sich Ihr Datenmodell mit der Anwendung weiterentwickeln sollte oder nicht. VLDB-Probleme rechtfertigen eine Bearbeitung, die ich hinzufügen werde.
Mark Storey-Smith

3
Ich lese die Frage als „eine neue App ohne DB noch“ eher dann „eine bestehende App erfordert Änderungen an die DB“
GBN

Ebenso vermisse ich irgendwo deinen Standpunkt :) Einen zum Plaudern mitnehmen?
Mark Storey-Smith

4
+1 für das allgemeine Empfinden Ihrer Antwort, aber "Das Ändern eines Datenbankschemas war noch nie so einfach wie das Ändern von Code" hängt wirklich davon ab, wie viel Code Sie haben (und wie alt er ist). IMO ist das Gegenteil der Fall
Jack Douglas

12

Ihr logisches Datenmodell sollte die Geschäftsanforderungen Ihrer Anwendung effektiv erfassen. Ihr physischer Datenbankentwurf sollte auf dem logischen Datenmodell basieren, kombiniert mit den notwendigen Änderungen, die Sie als DBA für erforderlich halten, um die Effizienz Ihres RDBMS zu maximieren.

Wenn Sie feststellen, dass Sie während des gesamten Softwareentwicklungszyklus Ihrer Anwendung zahlreiche Änderungen am zugrunde liegenden Datenbankdesign vornehmen müssen, weist dies auf zwei Dinge hin:

  1. Scope Creep - Sie gestatten die Einführung neuer Anforderungen zu einem unangemessenen Zeitpunkt.
  2. Unzureichende Geschäftsanforderungen - Ihre Datenmodellierer (oder Systemanalysten) haben die Anforderungen der Geschäftsanalysten nicht ausreichend übersetzt. Dies führte zu einem unvollständigen oder falschen Datenmodell, um die Anforderungen Ihrer Anwendung zu unterstützen.

Dies bedeutet, dass es nach der Übergabe einer Anwendung an die Produktion nicht ungewöhnlich ist, dass das Datenmodell wiederholt geändert werden muss, um die natürliche Entwicklung der Anwendung oder der zugrunde liegenden Geschäftsprozesse zu unterstützen.

Hoffe das hilft.


7
Das Hinzufügen vieler neuer Anforderungen im Verlauf eines Projekts ist nicht "unangemessen". Es ist etwas , das Ihre Entwicklungsmethoden sollten www.agilemanifesto.org/principles.html unterstützen und zu fördern
nvogel

1
Ich kenne einige der Prinzipien der agilen Entwicklung sehr gut und bin ein Befürworter dieser Prinzipien in einer Data-Warehousing-Funktion, in der dies für das Unternehmen sinnvoll ist. Vielen Dank für Ihren Kommentar.
RobPaller

11

Ich hatte den Luxus, mehrere Datenbanken mittlerer Komplexität zu entwerfen, die alle in Unternehmen verwendet werden und über verschiedene Frontends verfügen, darunter Web, Access und C #.

Normalerweise habe ich mich hingesetzt und das Datenbankschema im Voraus ausgearbeitet. Das ergab für mich immer den größten Sinn. Es gab jedoch keinen einzigen Fall, in dem ich keine Änderungen vorgenommen, keine neuen Tabellen hinzugefügt oder mit Aspekten gelebt habe, die mich störten und zu spät waren, um sie zu beheben.

Ich glaube nicht, dass die Heilung darin besteht, zuerst den Code zu schreiben. Und ich denke nicht, dass das Problem "unzureichende Geschäftsanforderungen" sind oder zumindest keine, die vollständig hätte gelöst werden können. Die Benutzer wissen nicht, was sie brauchen, und ich habe nicht die Macht, sie zum Nachdenken zu bewegen, klüger oder bewusster zu werden oder meine Fragen besser zu beantworten. Oder sie streiten sich und ich werde aufgefordert, etwas auf eine bestimmte Weise zu tun.

Die Systeme, die ich baue, befinden sich normalerweise in neuen Bereichen, in die noch niemand zuvor gegangen ist. Ich habe nicht das Buy-in von der Organisation, die Ressourcen oder die Werkzeuge, um die Art von Arbeit zu erledigen, die ein Entwicklerteam von hochkarätigen Designfachleuten leisten könnte, die zehnmal so viel als Team bezahlt bekommen, wie ich für das Einrichten von Dingen verdiene zweimal die Zeit.

Ich bin gut in dem, was ich tue. Aber es gibt nur einen von mir, der das in einer Umgebung macht, in der "keine Entwicklung stattfindet".

Trotzdem kann ich Geschäftsregeln immer besser erkennen. Und ich sehe eine Art dritte Option:

Zeichnen Sie vor dem Entwerfen der Datenbank und vor dem Schreiben von Code grobe Bildschirme, in denen die Funktionsweise der Anwendung dargestellt wird. Sie müssen von Hand gezeichnet sein, um zu verhindern, dass jemand einen Kommentar zur Schriftart, zur Größe oder zu den Abmessungen abgibt - Sie möchten nur eine Funktion.

Mit Transparentfolien und Papierstücken können Sie ein- und auswechseln, eine Person als Computer, zwei technisch nicht versierte Benutzer (zwei sprechen laut) und eine Person als Moderator, der Notizen macht und zeichnet die Nutzer über ihre Denkprozesse und Verwirrungen aufklären. Die Benutzer "klicken" und ziehen und schreiben in Kästchen, der "Computer" aktualisiert den Bildschirm und jeder kann das Design erleben. Sie lernen Dinge, die Sie sonst nicht gelernt hätten, bis weit in den Entwicklungsprozess hinein.

Vielleicht widerspreche ich mir selbst - vielleicht IST es besser, Anforderungen zu entdecken. Die Idee ist jedoch, zuerst die Anwendung zu entwerfen, ohne Code zu schreiben. Ich habe damit im kleinen Maßstab angefangen und es funktioniert! Trotz der Probleme in meiner Umgebung hilft es mir, die Datenbank von Anfang an besser zu gestalten. Ich erfahre, dass eine Spalte in eine neue übergeordnete Tabelle verschoben werden muss, da es mehrere Typen gibt. Ich erfahre, dass der Arbeitsvorrat Daueraufträge enthalten muss, die nicht aus dem integrierten Bestellsystem stammen. Ich lerne alle möglichen Dinge!

Meiner Meinung nach ist dies ein großer Gewinn.


+1 Gute Antwort. Die Entwicklung vereinfachter Anforderungen ist ein RIESIGES Plus in einem Projekt mit mehreren Stakeholdern.
Zayne S Halsall

10

Für die meisten Zwecke würde ich Option 2 wählen: Erstellen Sie die Datenbank parallel zu den anderen Komponenten. Wenn immer möglich, verwenden Sie einen iterativen Ansatz und stellen Sie bei der Erstellung der einzelnen Teile End-to-End-Funktionen bereit.

Dies erfordert eine gewisse Projektdisziplin. Wenden Sie die Normalisierung jedes Mal streng an (Boyce-Codd / Fifth Normal Form), wenn Sie die Datenbank ändern, damit Sie die Qualität beibehalten und kein ad-hoc und inkonsistentes Modell erhalten. Seien Sie so aggressiv wie möglich in Bezug auf Geschäftsregeln und damit verbundene Datenbankeinschränkungen. Im Zweifelsfall ist es besser, eine Einschränkung frühzeitig durchzusetzen - Sie können sie später jederzeit entfernen. Seien Sie bei der Implementierung von Architekturkomponenten intelligent, um die technische Verschuldung zu minimieren. Haben Sie einen guten Satz von Richtlinien für das Datenbankdesign, denen sich das gesamte Entwicklerteam anschließt.

All dies muss natürlich mit anderen guten Entwicklungspraktiken einhergehen: kontinuierliche Integration, Testautomatisierung und entscheidend aus Datenbanksicht die Erstellung von Testdaten. Die Testdatenerstellung von realistisch großen Daten sollte in jeder Iteration ohne Fehler erfolgen.


2
Glauben Sie nicht, dass ein gewisses Vorausdenken erforderlich wäre, um das konzeptuelle Modell zu definieren?
gbn

Einiges Vorausdenken mag nützlich sein, aber der Versuch, das gesamte Modell im Voraus zu definieren, ist normalerweise kontraproduktiv. Das Modell sollte mit den Geschäftsanforderungen übereinstimmen und mit den Projektergebnissen (einschließlich App) übereinstimmen, wenn sie sich entwickeln. Sie können und sollten nicht erwarten, dass sich diese Dinge nicht ändern. Auch das Erstellen des gesamten Modells im Voraus kann andere Entwicklungen behindern, da Dummy-Schnittstellen erstellt werden müssen, um noch nicht verwendete Teile des Schemas zu unterstützen.
nvogel

Ich vermute, @dportas und ich arbeite in ähnlichen Umgebungen :)
Mark Storey-Smith

9

In der Welt der Architektur wurde der Begriff "Form Follows Function" geprägt und später beim Bau von hohen Gebäuden befolgt. Gleiches gilt für die DB-Infrastruktur und die Anwendungsentwicklung.

Stellen Sie sich vor, Sie schreiben eine App und entscheiden spontan, dass Sie hier und dort einen Tisch benötigen. Wenn Ihre App fertig ist, wird eine große Anzahl von Tabellen als Arrays behandelt. Wenn Sie alle Tische nebeneinander betrachten, scheinen die Tische definitiv keinen Sinn und Zweck zu haben.

Leider werden einige Entwickler-Shops so etwas wie Memcached aufnehmen, es mit Daten in RAM laden (und es so wie ein Daten-Conduit behandeln) und eine Datenbank wie MySQL oder PostgreSQL einfach als Datenspeicher fungieren.

Der Anreiz für die Verwendung einer Datenbank sollte sein, sie richtig zu betrachten: als RDBMS. Ja, ein relationales Datenbankverwaltungssystem. Wenn Sie ein RDBMS verwenden, sollte Ihr Ziel im Voraus nicht nur darin bestehen, Tabellen zum Speichern, sondern auch zum Abrufen einzurichten. Die Beziehungen zwischen Tabellen sollten nach den Daten modelliert werden, die Sie anzeigen möchten, und wie sie dargestellt werden. Dies sollte auf der Kohärenz und Integrität der Daten zusammen mit bekannten Geschäftsregeln basieren. Diese Geschäftsregeln können in Ihrer App (Perl, Python, Ruby, Java usw.) oder in der Datenbank codiert werden .

FAZIT

Ich würde auf jeden Fall Option 1 wählen. Dies erfordert eine ordnungsgemäße Planung, Datenmodellierung und fortlaufende Datenanalyse. Dies sollte jedoch die Datenbankänderungen auf lange Sicht minimieren.


1
@RolandoMySQLDBA, gehen Sie davon aus, dass ein Datenbankdesign, das während der App-Entwicklung erstellt wurde, schlechter ist als ein Design, das zuvor erstellt wurde? Warum? Das Gegenteil ist oft der Fall.
nvogel

1
@dportas: Mein Schwerpunkt liegt auf Option 1, um Änderungen im DB-Design zu minimieren. Ich habe zwei Drittel meiner technischen Karriere in Shops verbracht, in denen sehr komplexe Datenmodelle und Infrastrukturen fast monatlich aus einer Laune heraus verändert wurden. Ich habe mich auf solche Veränderungen konzentriert, weil die geschäftlichen Anforderungen und Ziele nicht in Stein gemeißelt waren. Ich bin in dieser Hinsicht ziemlich altmodisch. Es ist nichts Falsches daran, ein kleiner Außenseiter zu sein, solange das Design nicht viel „technische Schuld“ (Ja, ich lese deine Antwort) auf die Straße bringt.
RolandoMySQLDBA

2
+1 für 'Verwenden eines RDBMS als relationale Datenbank, nicht als Bit-Bucket für Arrays' - je nachdem, wie Sie vorgehen
Jack Douglas

2
@dportas: Während dies zutrifft (Änderung der Geschäftsregeln), ändert sich eine gut gestaltete Datenbank nicht grundlegend zwischen einer Iteration (oder einem Sprint oder was auch immer) und einer anderen, da sie alle relevanten Datenstrukturen des Arbeitsprozesses widerspiegelt. Wenn dies geschieht (radikale Änderung), bedeutet dies, dass die Erfassung von Geschäftsregeln fehlgeschlagen ist.
Fabricio Araujo

3
@dportas: Nicht alle DB-Änderungen, nur RADICAL. Kleinere Änderungen gehören zum Geschäft mit Software. Das Aufteilen der Daten in zwei verschiedene Datenbanken während der Arbeit ist jedoch ein Fehler beim Entwurf und bei der Erfassung der Geschäftsregeln. (Es ist mir tatsächlich passiert.
Fabricio Araujo

9

Ich denke, dass es getan werden sollte, bevor es irgendeinen tatsächlichen Code für die Anwendung gibt, aber nicht bevor die Anwendung entworfen ist.

Wenn ich alleine arbeite, ist mein typischer Workflow:

  1. Bestimmen Sie, was die Anwendung tun muss
  2. Überprüfen Sie, ob eine der Aufgaben für wiederverwendbare Komponenten aufgeschlüsselt werden kann
  3. Bestimmen Sie, wie jede Aufgabe mit dem Datenspeicher interagieren muss - welche Art von Fragen werden sie an die Daten stellen, wie oft werden sie schreiben, usw.
  4. Entwerfen Sie die Datenbank so, dass sie alle Fragen beantworten und für die häufigsten Aufgaben eine gute Leistung erbringen kann.
  5. Schreiben Sie die Anwendung.

Da ich häufig als Teil eines Teams arbeite und räumlich (und zeitlich) verstreut bin, haben wir in der Regel ein erstes Kickoff-Meeting:

  1. Bestimmen Sie, was die Anwendung tun muss.
  2. Bestimmen Sie, an welchen Stellen die Anwendung in eigenständige Komponenten aufgeteilt werden soll
  3. Bestimmen Sie, wie jede Komponente mit den anderen interagieren muss.
  4. Vereinbaren Sie eine API für jede der Interaktionen.

Dann kehren wir nach Hause zurück, schreiben unser Teil und wenn eine Komponente einen eigenen lokalen Speicher benötigt, solange der Betreuer für dieses Teil die API für ihr Modul konsistent hält. Der Hauptdatenspeicher wird als Modul mit einer eigenen API behandelt, und von den Benutzern wird erwartet, dass sie darauf schreiben. (In Fällen, in denen die Geschwindigkeit der Datenbank kritisch ist, ist die API die Tabellendefinition. Wenn Änderungen vorgenommen werden, verwenden wir Ansichten oder einen anderen Mechanismus, um die ältere Version darzustellen, bis alle Module aktualisiert werden können.)


1
Der Fall für Option 2 ist, dass Sie mit einer agilen Methodik nicht über die für den nächsten Sprint festgelegten Werte hinaus 1, 2 oder 3 kennen. Änderungen in Bezug auf Umfang, Anforderungen und Erwartungen sind unvermeidlich.
Mark Storey-Smith

8

Ich denke an die folgende Regel: "Sie können nur die Informationen aus der Datenbank abrufen, für die Sie Daten generieren müssen". Also entwerfe ich zuerst die Datenbank, später den Code.

Warum? Egal welche Metodologie / Sprache / Toolset ich verwende, wenn alle relevanten Daten gut gestaltet und in der DB gespeichert sind, kann ich sie abrufen. Egal ob in C # / Delphi / FORTRAN / COBOL / Assembly / VBA oder Crystal Reports; OO entworfen oder Ereignis / Daten / was auch immer getrieben; wendig oder Wasserfall. Wenn die Daten vorhanden sind, kann ich sie abrufen, wenn die von mir verwendeten Tools eine Verbindung zur Datenbank herstellen können. Ich kann die Verkaufsberichte erstellen, wenn ich die Aufträge für die Umsatzerlöse des Quartals AUSWÄHLEN kann - auch wenn ich sie byteweise auf Assembly schreiben muss.

Wenn die relevanten Daten nicht vorhanden oder gar nicht vorhanden, aber (un) strukturiert sind, kann ich die benötigten Informationen nicht abrufen - wie codiere ich sie?


7

Wie immer kommt es darauf an;)

Nehmen wir zum Beispiel an, wir haben einen in Python entwickelten kleinen Prototyp, der flache Dateien verwendet, und die Benutzer sind mit den Funktionen des Prototyps zufrieden. Wir müssen ihn also nur mit RDBMS als Back-End produzieren . Wenn dies der Fall ist, kann man davon ausgehen, dass es beim ersten Mal richtig ist - das Problem ist klein und klar definiert. In solchen Fällen ist eine Vorausplanung möglich.

Wenn wir andererseits die Anforderungen in einer agilen Umgebung ermitteln, benötigen wir einige Iterationen, um sie besser zu verstehen. In solchen Situationen entwickelt sich die Datenbank mit dem Rest der Anwendung. Dies ist, was wir normalerweise tun. Da wir Live-OLTP-Tabellen ohne Ausfallzeiten und mit geringem Risiko refaktorieren können, sind wir mit der Möglichkeit von Datenbank-Refaktorierungen vertraut.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.