Umgestalten oder Aktualisieren von Datenbanken, um neue Funktionen zu nutzen


9

In mehreren Antworten auf eine Frage zum Datenbankschema wurde eine zusätzliche Tabelle vorgeschlagen, um eine Datenbank für eine Funktion zu normalisieren, die nicht Teil der aktuellen Anforderungen ist (eine UserDepartment-Tabelle, um eine Viele-zu-Viele-Beziehung zwischen Mitarbeitern / Benutzern und verschiedenen Abteilungen zu ermöglichen gehören.).

Nicht gegen Normalisierung. Wenn es um das Datenbankdesign geht, scheint es einen starken Druck zu geben, Funktionen aufzunehmen, von denen sie "sicher" sind, dass sie jemand in Zukunft haben möchte. Ist es so schwierig, der Datenbank Tabellen / Felder hinzuzufügen, um Funktionen zu berücksichtigen, dass die Tendenz besteht, zu viel zu entwickeln? Würden sie nicht wie der Rest der App bei Bedarf überarbeitet oder aktualisiert werden? Das Wiederherstellen von Dingen macht nie Spaß, aber das Verschieben von Daten von einer Tabelle in eine neue kann durchgeführt werden. Nur nicht sicher, wo diese Denkrichtung enden wird.

Bearbeiten: Es gibt so viel Abneigung dagegen, dass ich mich frage, wie viele Projekte am Ende keine Funktion hinzufügen, die eine drastische Datenbankänderung erfordert, oder nicht normalisierte Ansätze wie das Hinzufügen eines DepartmentID2-Felds anstelle einer neuen Tabelle. Die Notwendigkeit mehrerer Abteilungen für einen Mitarbeiter ist ein häufiges Domänenproblem. Ich habe nur nicht viele Datenbankschemata bemerkt, die mit vielen-zu-vielen-Beziehungen übersät sind.


1
+1 Danke, dass du das gefragt hast. Ich habe viel gelernt, als ich die Antworten auf meine ursprüngliche Frage gelesen habe, und dies ist auch ein aufschlussreicher Thread.
Jim

Antworten:


3

Es gibt ein ganzes Buch über Datenbank-Refactoring. Genau wie beim Code-Refactoring gibt es Standardmethoden für das Datenbank-Refactoring. Der einzige Unterschied besteht darin, dass Sie beim Code-Refactoring nicht den Status des Objekts / Codes berücksichtigen müssen, während Sie in Datenbanken die Daten berücksichtigen müssen, da der Verlust von Daten nicht gut für die Benutzer (oder für irgendjemanden) ist ).

Weitere Informationen zum Datenbank-Refactoring finden Sie hier .


Diese Seite hat die Frage in erster Linie
ausgelöst

14

Das Refactoring von Code ist einfach - Sie ändern einfach den Code und führen Ihre Regressionstests durch.

Das Refactoring von Datenbanken ist schwierig - Sie müssen (möglicherweise eine große Menge) Daten verschieben, sicherstellen, dass nichts davon gelöscht wird, und sicherstellen, dass die Einschränkungen im neuen Schema beibehalten werden. Wenn Sie Prüfungsanforderungen für die Daten haben, müssen Sie in der Lage sein, zu erklären, warum sie anders organisiert sind, und Pre-Refoctor-Daten mit Post-Refactor-Daten abgleichen zu können. Außerdem stimmt keines Ihrer alten Backups mit dem neuen Schema überein, was ein weiteres Risiko darstellt.

Gruseliges Zeug.


Datenbanktests sollten nicht anders sein. Alle Änderungen erfordern eine Prüfung und wirken sich auf Sicherungen aus. Wie viele Daten werden Sie sammeln, bevor Sie diesen Bedarf erkennen? Wenn Sie Daten konvertiert haben, ist diese Funktion noch offensichtlicher.
JeffO

8
+1 für @Mathew Flynn. Wie viele Daten werden Sie sammeln, bevor Sie diesen Bedarf erkennen? MILLIONEN Reihen. Ein weiteres Problem ist, dass IHR App oft nicht das einzige ist, das die Datenbank verwendet. In der Datenbank können viele Apps arbeiten, und Sie wissen möglicherweise nicht einmal, dass sie existieren (z. B. wilde "BI" -Apps). Änderungen in Datenbankschemata sind beängstigend.
Angelo

2
Manchmal Milliarden von Zeilen
HLGEM

1
Wenn Sie mit Milliarden von Zeilen zu tun haben, wissen Sie besser, wie man sie verschiebt
JeffO

3

Es gibt eine feine Grenze zwischen viel Zeit für das Engineering und ein wenig Zeit, um gerade genug Funktionen hinzuzufügen, um Ihnen in Zukunft viel Zeit zu sparen.


1
Sie könnten diese Argumentation für eine oder zwei isolierte Instanzen vorbringen, aber wann summieren sich die Zeitabschnitte zu viel?
JeffO

Nach meiner eigenen Erfahrung ist dies bei der überwiegenden Mehrheit der Projekte der Fall. Aber ich würde auch vermuten, dass es mit Erfahrung kommt und sehr subjektiv ist :) Ich wäre überrascht, wenn jemand Ihnen ein genaues Rezept geben kann (daher die 'feine Linie').
0x4B1D

@ Jeff O: Es werden keine "Bits" sein. Eine Investition von 10% oder 20% der Entwicklungszeit in das Härten ist erforderlich, da das System sowohl den ursprünglich vorgesehenen Zeitrahmen als auch Ihre Beschäftigung überdauern kann.
Rwong

3

Ich denke, die Theorie ist, dass, wenn Sie eine Verknüpfungstabelle einfügen, um eine Viele-zu-Viele-Beziehung zwischen 2 Tabellen zu unterstützen, jeder, selbst wenn wirklich nur Viele-zu-Eins-Beziehungen in den Daten vorhanden sind, jeder die SQL so schreibt, dass, wenn überhaupt, eine Viele zu viele werden unterstützt, alles wird "einfach funktionieren".

In der Praxis habe ich normalerweise nicht festgestellt, dass dies wahr ist, aber ich nehme an, dass SQL näher an dem ist, was es sein muss, um die vielen zu vielen zu unterstützen, als es sonst gewesen wäre.

Aber speziell auf Ihre Frage zu bekommen, es tatsächlich ist eine ganze Menge Schmerz eine Beziehung von 1-zu-viele - viele-zu-viele - Umwandlung. Der Grund dafür ist, dass SQL nicht mit den gleichen Kapselungszielen wie Objekte entworfen wurde und die meisten Abfragen mehr Tabellen auf der Datenbankebene verwenden, als es für Benutzer angenehm wäre, wenn ein Objekt in der Geschäftsschicht sichtbar wäre.

Daher wirkt sich eine Änderung einer Viele-zu-Viele-Beziehung auf jede Abfrage aus, die die ursprünglichen 2 Tabellen umfasst. Dies hat häufig einen viel größeren Kaskadeneffekt als auf der Geschäftsschicht. Die Menschen unternehmen also erhebliche Anstrengungen, um dies zu verhindern.

IMHO wäre dies nicht erforderlich, wenn wir eine bessere Sprache als SQL hätten, um die relationale Algebra zu spezifizieren. Wenn es möglich wäre, eine SQL-Abfrage Stück für Stück nach Objekten aufzubauen, die nicht für jede Tabelle in der Abfrage sichtbar sein müssten, würde dies nicht passieren. Dinge wie LINQ (zu SQL oder zu Entities) versuchen dies zu lösen, aber es ist eine sehr komplexe Lösung und schwer zu optimieren (und ich war in DBA-Benutzergruppen, in denen LINQ erwähnt wird und jedes Mal ein kollektives Stöhnen auftritt). Ich träume von einer Datenbanksprache, die universell mit erstklassigen relationalen Algebra-Funktionen unterstützt wird ...

In der Zwischenzeit können Sie zwar von 1 zu vielen zu vielen zu vielen umgestalten, aber es kann eine Menge Arbeit sein.


Sie werden nicht jede Beziehung in eine Viele-zu-Viele-Beziehung verwandeln?
JeffO

@ Jeff O - Ich bin mir nicht sicher, ob ich deine Frage verstehe. Im Zweifelsfall modelliere ich so viele wie viele, um die Fallstricke zu vermeiden, die in verschiedenen Antworten auf Ihre ursprüngliche Frage erwähnt werden. Ich bin etwas vorsichtiger geworden, nachdem ich Datenbanken gepflegt habe, die wirklich fast alle Beziehungen zu vielen gemacht haben, weil sie Dinge wie das Erstellen von Ansichten getan haben, die die Beziehungen 1 zu viele erscheinen ließen (was in der Praxis in der Praxis der Fall war). sie alle waren). Sie hatten also das Schlimmste aus beiden Welten. Ich habe das noch nie bei meinen eigenen Entwürfen erlebt, aber es ist eine warnende Geschichte.
Psr

3

Normalerweise erkläre ich es den PHBs so - Code sind die Wände und das Dach, die Datenbank ist das Fundament.

Das Verschieben der Wände und das Ändern des Daches können durchgeführt werden. Das Wechseln des Fundaments erfordert viel Graben und Wiederaufbau der Wände und des Daches.

Was unerfahrene Entwickler (und Hochschulprofessoren) als "Over Engineering" bezeichnen, nennen erfahrene Entwickler "Zukunftssicherheit". Ungeachtet dessen, was in der Spezifikation angegeben ist, wissen Sie, was sich wahrscheinlich während des ALM ändern wird oder wo die Leistungsprobleme auftreten werden, sodass Sie Ihre Tabellenstruktur zunächst richtig gestalten möchten.

Das Ausrollen von Update-Skripten auf Kundenservern ist kein triviales Projekt, und alle DBAs der Kunden sind überall auf der Welt, um alles dreifach zu überprüfen. Einige zusätzliche Spalten und Tabellen sind doch nicht so schlecht.


1

Die allgemeine Regel ist , wenn eine Beziehung 12.59 ist aber möglicherweise in Zukunft viele viele sein dann es viele viele machen.

Der Mitarbeiter / die Abteilung ist ein klassisches Beispiel. In den meisten kleinen Unternehmen ist dies die meiste Zeit eine Eins-zu-Viele-Beziehung . Es gibt jedoch fast immer eine Situation, in der es viele zu viele werden - einer Ihrer Ingenieure steigt in das Management ein, ist jedoch weiterhin für die Unterstützung eines Produkts verantwortlich, das er während seiner Ingenieurzeit entwickelt hat, oder einer Ihrer Vertriebsmitarbeiter, zu dem er gewechselt ist Produktentwicklung, aber da er eine enge Beziehung zu einem wichtigen Kunden hat, ist er immer noch der Hauptverkäufer für diesen Kunden.

Es kostet nicht viel mehr, wenn eins zu viele als viele zu viele implementiert wird - aber die Umgestaltung einer Datenbank und einer Anwendung zur Unterstützung vieler zu vieler ist teuer und mit Schwierigkeiten verbunden.


Ich bin damit einverstanden, dass es viele ausgereifte Bereiche (wie HR) gibt, in denen der Kunde die Notwendigkeit nicht antizipiert, aber Sie wissen, dass dies zwangsläufig passieren wird.
JeffO

0

Es gibt zwei Möglichkeiten, das Design von Software (und wahrscheinlich viele andere Dinge) zu betrachten - eine taktische oder eine strategische Sichtweise. Jeder hat seine eigenen Vor- und Nachteile.

Selbst mit OO-Softwaremodifikationen ist es immer noch ein Problem, nicht nur der Codierungsteil ist schwierig, sondern der Prozess der Förderung einer Änderung der Produktion in einer Beschwerdeumgebung (angesichts des aktuellen Standes der Technik) ist für große Systeme, die es sein sollen, unwirklich 24/7 arbeiten.

Ich folge meinem Prinzip, das besagt: " Wenn möglich, gemeinsam genutzte Software-Artefakte strategisch entwerfen " - Dies mag so klingen, als ob es in irgendeiner Weise gegen das YAGNI-Prinzip verstößt. Dies ist jedoch meine Meinung. Dieser Ansatz garantiert weniger Nacharbeit bei den Kosten für Komplexität und Ressourcen.

In Ihrem Fall umfassen die zum Hinzufügen einer neuen Junction-Tabelle erforderlichen Aktivitäten: Entwurf, Entwurfsgenehmigung, Ändern des Schemas, Umschreiben mehrerer Methoden für CRUD für 3 Tabellen (mit Ausnahme einiger Lesevorgänge), Erstellen von Indizes, Erstellen einer GUI für die CRUD für die neue Tabelle, damit der Benutzer die PKs beim Erstellen, Aktualisieren der neuen Tabelle usw. auswählen kann. Oh, und vergessen Sie übrigens nicht Unit-Tests, Benutzerakzeptanztests, Systemtests und Produktionsförderung.

Wenn dies nicht ausreicht, kommt der wahre Albtraum vom Informationsverlust. Wenn Sie die Junction-Tabelle zunächst nicht hatten und beschlossen haben, die Daten zu erfassen, an denen die Zuordnung / Trennung zwischen einem Mitarbeiter und einer Abteilung stattgefunden hat, können Sie das Datum nicht automatisch in die Junction-Tabelle einfügen. Sie müssen diese manuell eingeben (wenn Sie die Daten haben).

Es ist also besser, dies von Anfang an vorauszusehen.


Alles ist von Anfang an besser vorauszusehen.
JeffO

0

Wie Matthew oben sagte, ist das Refactoring / Ändern von Datenbanken im Vergleich zu Software häufig aufwändiger, da auch die Verwaltung von Daten berücksichtigt werden muss. Es gibt Techniken, die helfen können, z. B. sicherzustellen, dass Sie über eine geeignete Suite von Datenbank-Unit-Tests verfügen, Client-Anwendungen mithilfe einer 'DB-API' von Ihrem Basisschema zu entkoppeln - Sprocs / Views usw.

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.