Feldprüfung

Hallo,

habe in der Tabelle ein Feld für die „Kategorie“.
In den Datensätzen steht meistens nur 1 Kategorie drinnen, z.B. „Allgemeines“ oder „Bilder“.

Wenn ich jetzt nur die Datensätze für „Allgemeines“ lesen möchte, verwende ich folgendes:

SELECT * FROM tabellenname WHERE cat=„Allgemeines“

Nun gibt es jedoch auch Datensätze die im Feld für die Kategorie den Wert „Allgemeines; Bilder“ eingetragen haben.

Mit obigen SQL Befehl wird so ein Datensatz leider nicht gelesen bzw. gefunden.

Gibt es hierfür eine einfache SELECT Anpassung? SQL mach ich erst ein paar Tage.

Gruß
Michael

Normalformen
Moin, Michael,

das Α und Ω für jede Auswertung ist eine normalisierte Tabelle. Das bedeutet in Deinem Fall schlicht, dass ein Feld keine zwei Inhalte trägt, sondern genau einen.

Der Designfehler lässt sich natürlich durch Murks Abfragen à la

 select \* from table 
 where field = "a"
 or field = "b"
 or field = "a;b"

umschiffen. Spätestens beim ersten Gruppieren fällst Du damit auf die Nase. Oder wenn ein dritter Wert dazukommt; dann wird der Select aufs neue überarbeitet. Bis der vierte kommt :smile:))

Falls zwischen 2 Entitäten eine m:n-Beziehung besteht, dann muss das in einer dritten Tabelle abgebildet werden, in der die beiden Primärschlüssel verknüpft sind.

Lies Dich mal ein, in der Brettbeschreibung sind ausgezeichnete Links angegeben.

Gruß Ralf

Hallo,
was Ralf geschrieben hat, ist erstmal natürlich richtig.
Trotzdem geht das natürlich auch noch mit dem LIKE Operator.

SELECT \* FROM tabellenname WHERE cat like "%Allgemeines%"

http://www.w3schools.com/sql/sql_like.asp

Wobei das % Zeichen ein Wildcart ist und von Datenbanksystem zu Datenbanksystem auch anders sein kann. Bei großen Tabellen kann das auch heftig auf die Performance gehen.

Trotzdem solltest du die Tabellen normalisieren. Sowas versaut einem die ganze Entwicklung. Außerdem bekomme ich immer Augenkrebs wenn ich solche Lösungen sehe.

Gruss
Joey

Designen statt hinterherzuhecheln
Moin, Michael,

was Joey da empfiehlt, hilft Dir zwar über diese Klippe, führt Dich aber nur näher an den Abgrund heran.

Die Anwender sind unglaublich erfinderisch1, wenn sie die Möglichkeit haben, Textfelder zu belegen. Aus „Allgemeines“ wird „Allgemein“, steht „Allgemeines“ an erster Stelle, dann kann es was anderes bedeuten als wenn „Bilder“ zuerst steht (glaub mir, ich habe das 20 Jahre lang gesehen). Und schon krempelst Du die Ärmel hoch und erfindest die nächste Krücke.

Einzige Abhilfe ist ein sauberes Datendesign, bei dem der Anwender keine Möglichkeit hat, ein Textfeld zu befüllen, stattdessen bietest Du ihm Dropdowns, aus denen er einen (in Worten: 1) Wert auswählen kann. Der Mehraufwand macht sich hundertfach bezahlt.

Gruß Ralf

1An Rechtschreib- oder Tippfehler mag ich erst gar nicht denken.

Moin,

Einzige Abhilfe ist ein sauberes Datendesign, bei dem der
Anwender keine Möglichkeit hat, ein Textfeld zu befüllen,
stattdessen bietest Du ihm Dropdowns, aus denen er einen (in
Worten: 1) Wert auswählen kann. Der Mehraufwand macht sich
hundertfach bezahlt.

Auch da gebe ich dir grundsätzlich recht, nur sollte das kein Dogma sein.

Nun will der werte Kunde nicht nur „Allgemeines“ alleine, sondern zusammen mit „Bilder“ eintragen. Ich mache jetzt eine nächste halbe Krücke mir Feld „cat1“ und „cat2“. Dumm wenn er dann mal ein drittes Attribut braucht. Also muss eine m:n Tabelle her. Schon habe ich aus einer Tabelle 3 Tabellen gemacht.

Wenn das nur einmal vorkommt wäre das OK. Es kommt aber immer mehrfach vor. Dann muss man joinen, Joinen, JOINen, JOINEN … und eine hundertfachen Aufwand in der Programmierung und der dahinter liegenden Komplexität.

Die große Kunst beim Datenbank-Design ist aus meiner 20-jährigen Erfahrung nicht das Normalisieren, sondern das bewusste De-Normalisieren.

Normalisieren kann man lernen, De-Normalisieren ist Erfahrung und Kenntnis der Problemstellung.

Gruss
Joey

Hi Joey,

Die große Kunst beim Datenbank-Design ist aus meiner
20-jährigen Erfahrung nicht das Normalisieren, sondern das
bewusste De-Normalisieren.

dabei sollte aber nicht in Vergessenheit geraten, dass De-Normalisieren ohne vorheriges Normalisieren garantiert in die Hose geht. Nicht umsonst trennt man gerne zwischen Datenmodell und Datenbankentwurf, auch bekannt als logisches und physisches Modell.

Gruß Ralf

Hallo,

danke für die Antworten.
So wie ihr schreibt, scheint SQL wohl ein eigenes Universum für sich zu sein… mit ganz anderen Gesetzen :smile:

Ich habe das jedenfalls mit „LIKE“ ausprobiert und es geht gut. Danke für diesen Tipp. Aber die Idee mit Felder „cat1“, „cat2“, „cat3“ (mehr werden wohl nicht benötigt) wäre vielleicht besser.

Jedenfalls ist das alles für ein eigenes Blogsystem und wenn dann mal 5000 Artikel (Datensätze) hinterlegt sind, ist das für ein privaten Blog schon viel aber für eine Datenbank ganz wenig.

Gruß
Michael

Hallo,

Die große Kunst beim Datenbank-Design ist aus meiner
20-jährigen Erfahrung nicht das Normalisieren, sondern das
bewusste De-Normalisieren.

Normalisieren kann man lernen, De-Normalisieren ist Erfahrung
und Kenntnis der Problemstellung.

das ist doch mal ne Aussage, die zur Diskussion einlädt. Zustimmen kann ich nicht, weil ich mir nicht anmaße, alle zukünftigen Anforderungen zu kennen.

Ich bin schon oft auf die Schnauze gefallen, weil sich die Anforderungen von Heute auf Morgen so starkt verändert haben, dass eine vollständige Normalisierung von Anfang an besser gewesen wäre. Erfahrung nützt da wenig, da man nicht immer von der Vergangenheit auf die Zukunft schließen kann. Nichts ist schlimmer als eine Datenbank, der man anmerkt, dass sie historisch gewachsen (also total vermurkst) ist. Ich versuche deshalb von Anfang an alles so flexibel wie möglich zu gestalten. Alles andere rächt sich irgendwann.

MfG
Stephan

Hallo Ralf,

dabei sollte aber nicht in Vergessenheit geraten, dass
De-Normalisieren ohne vorheriges Normalisieren garantiert in
die Hose geht.

Das ist klar. Erst muss das Idealbild erstellt werden und dann muss es auf Praxisuntauglichkeit und Geschwindigkeit getrimmt werden.

Gruss
Joey

Hallo,

Ich bin schon oft auf die Schnauze gefallen, weil sich die
Anforderungen von Heute auf Morgen so starkt verändert haben,
dass eine vollständige Normalisierung von Anfang an besser
gewesen wäre.

In solchen Fällen sind die Fehler nicht im Datenbankdesign gemacht worden, sondern schon bei der Planung der gesamten Anwendung.
Wenn jemand aus einem Mini einen Geländewagen machen möchte, dann geht das nicht. Auch wenn beides 4 Räder und ein Lenkrad hat.

Erfahrung nützt da wenig, da man nicht immer von
der Vergangenheit auf die Zukunft schließen kann.

Erfahrung hilft auch dort. Man kann eine Datenbank so designen, dass sie erweitert werden kann, ohne den Kern umzugestalten.

Nichts ist schlimmer als eine Datenbank, der man anmerkt, dass sie
historisch gewachsen (also total vermurkst) ist. Ich versuche
deshalb von Anfang an alles so flexibel wie möglich zu
gestalten. Alles andere rächt sich irgendwann.

Historisch gewachsene Datenbanken sind oft nicht von den richtigen Leuten entworfen und normalisiert worden.

Ein Beispiel mal aus meiner Praxis:
In einer DB wurden Messkurven gespeichert. Eine Kurve besteht aus ca. 2000 Datenpunkten (x,y), es wurden jeweils ca .10 Kurven pro Messung ermittelt. Die Kurven mussten übereinander auf einer Webseite dargestellt werden.

Derjenige, der die DB entworfen hatte, hat die Kurvendaten in einer eigenen Tabelle gespeichert.

also: Messung 1*n Kurve 1*n Kurvenpunkte

Von der Normalisierung ist das OK.

Bei jedem Plot auf der Webseite mussten aber 20000 Datenpunkte aus der DB gezogen werden. Nachdem die Anzahl der Datenpunkte in der DB auf ca 100 Millionen gestiegen war, hat die Webseite sich mit einem Timeout verabschiedet. (Optimierungen der Tabelle und des Servers waren schon getätigt - im Rahmen des finanziell möglichen)

Lösung? De-Normalisieren. In dem Fall geht es, weil Datenpunkte entweder alle oder keiner gebraucht wird.

In der Tabelle „Kurven“ ein Blob Feld hinzufügen und die Kurvenpunkte dort als XML speichern. Tabelle „Kurvenpunkte“ löschen. Datenbank ist jetzt wieder unterbeschäftigt.

Derjenige, der die Datenbank entworfen hatte, wollte es richtig machen. Konnte sich aber nicht vorstellen welche Datenmengen dort am Ende gespeichert werden. Wenn er genug Erfahrung gehabt hätte, hätte er das 1) hinterfragt und 2) gleich einen anderen - De-Normalisierten - Ansatz gewählt.

Wie ich schon Ralf geschrieben habe. Normalisieren ist ganz, ganz wichtig. Aber eben nicht das Ende des Entwurf.

Gruss
Joey

Hallo,

Ein Beispiel mal aus meiner Praxis:
In einer DB wurden Messkurven gespeichert. Eine Kurve besteht
aus ca. 2000 Datenpunkten (x,y), es wurden jeweils ca .10
Kurven pro Messung ermittelt. Die Kurven mussten übereinander
auf einer Webseite dargestellt werden.

Derjenige, der die DB entworfen hatte, hat die Kurvendaten in
einer eigenen Tabelle gespeichert.

also: Messung 1*n Kurve 1*n Kurvenpunkte

Von der Normalisierung ist das OK.

Bei jedem Plot auf der Webseite mussten aber 20000 Datenpunkte
aus der DB gezogen werden. Nachdem die Anzahl der Datenpunkte
in der DB auf ca 100 Millionen gestiegen war, hat die Webseite
sich mit einem Timeout verabschiedet. (Optimierungen der
Tabelle und des Servers waren schon getätigt - im Rahmen des
finanziell möglichen)

Lösung? De-Normalisieren. In dem Fall geht es, weil
Datenpunkte entweder alle oder keiner gebraucht wird.

In der Tabelle „Kurven“ ein Blob Feld hinzufügen und die
Kurvenpunkte dort als XML speichern. Tabelle „Kurvenpunkte“
löschen. Datenbank ist jetzt wieder unterbeschäftigt.

Derjenige, der die Datenbank entworfen hatte, wollte es
richtig machen. Konnte sich aber nicht vorstellen welche
Datenmengen dort am Ende gespeichert werden. Wenn er genug
Erfahrung gehabt hätte, hätte er das 1) hinterfragt und 2)
gleich einen anderen - De-Normalisierten - Ansatz gewählt.

Derjenige, der die Datenbank entworfen hatte, hat es in meinen Augen auch vollkommen richtig gemacht. Die erwähnte Optimierung durch Denormalisierung hilft nämlich nur bei diesem konkreten Problem (Darstellung der Webseite). Bei anderen Aufgabenstellungen wird es dann wieder schwieriger, weil man das XML erst wieder aufdröseln muss.

Wie ich schon Ralf geschrieben habe. Normalisieren ist ganz,
ganz wichtig. Aber eben nicht das Ende des Entwurf.

Ich bevorzuge in solchen Fällen redundante Datenhaltung. Die Daten werden auf jeden Fall normalisiert gespeichert und für die Ausgabe nutze ich einfach spezielle Tabellen (meist schon mit aggregierten Daten), die per Trigger oder Job gefüllt werden.

MfG
Stephan