CK knows Wayne!

Kompromisse und andere Widerlichkeiten

Published at by Christian Kruse, updated at
Filed under: Computer

Im Rahmen eines größeren CRM-Projekts (etwa 5 Mio Kunden-Datensätze) arbeite ich aktuell mit einer Tabelle „Kunden.” Um Projekt-spezifisch und ohne Sourcecode-Änderungen zusätzliche Informationen (etwa projektspezifische Informationen) speichern zu können, gibt es, verknüpft über „Kunden_ID” (1:n) eine Tabelle „Kunden_Zusatzinfos.” Die Tabelle ist eine einfache, Kunden_ID-Name-Wert-Tabelle, so dass generisch Informationen gespeichert werden können. Das ist natürlich allein schon ein Kompromiss, allerdings nicht sinnvoll anders zu lösen. Soweit, so schlecht.

Ein Problem tritt nun auf, wenn man eine Menge von Kontakten abruft, zu der ein bestimmtes Feld hinzu „gejoint” werden soll, also etwa so:

SELECT a.*,b.value AS specific_field FROM Kunden AS a LEFT JOIN Kunden_Zusatzinfos AS b ON a.Kunden_ID = b.Kunden_ID AND b.field = 'specific_field' WHERE suchkriterium

Je nach Anzahl der Kontakte kann diese Query extrem lange dauern, da aus einer zweiten Tabelle gejoint werden muss, die etwa 10x so viele Datensätze enthält. Zwar gibt es genau für sowas einen Index, aber auch der kann nur begrenzt helfen.

Abhilfe musste ich mir hier schaffen, indem ich in der Kunden-Tabelle eine weitere Spalte hinzugefügt habe, in der die Zusatz-Daten zu dem Kontakt als Array in JSON-Syntax gespeichert werden. Also z. B. ein Kontakt hat die Felder „ciao,” „newsletter,” und „lead,” so sähe das JSON-Feld so aus: {"ciao": 0, "newsletter": 1, "lead": 0}.

So kann ich ohne zusätzlichen Join alle Zusatzfelder mit auslesen. Allerdings zieht diese Methode den Nachteil der doppelten Datenhaltung mit sich: ich habe die Zusatz-Tabelle, in der die Daten stehen und die ich weiterhin brauche, um Kontakte nach spezifischen Zusatzfeldern suchen zu können und ich habe, sozusagen als Cache, das Zusatz-Feld mit der JSON-Syntax. Aber andererseits ist das halt einfach um etwa den Faktor 15 schneller als der zusätzliche Join.

Aber vielleicht fällt jemandem ja noch etwas anderes ein?

Four fucking comments!

Comment Feed: RSS / Atom
Gravatar

Jeena wrote

at

Na dazu gibt es ja Trigger und Views damit du dir über die doppelte Datenhaltung keinen kopf mehr machen musst?

Gravatar

Christian Kruse wrote

at

Na, darum geht es ja nicht. Ich möchte einfach eine Lösung, kein herumdoktorn an den Symptomen.

Gravatar

Jeena Paradies wrote

at

Flickr macht das ja auch durch denormalisieren. Ich glaube so eine pauschale Antwort gibt es kaum, obwohl, du könntest ja vom Relationalen-Datenbankschema weggehen und was Objektorientiertes nutzen, wo die Daten schöner reinpassen, das bedeutet wiederum sehr viel Arbeit, aber du bekommst es ja bezahlt ;)

Gravatar

Christian Kruse wrote

at

Nein, kann ich nicht. Die Daten sind von Natur aus relational. Kunden <=> Kunden_Zusatzinfos ist ja nicht die einzige Relation.

Your Comment

You can use MarkDown to format your comment: *Word* for italic, **Word** for bold, images will get removed.




Because of massive spam attacks you may only post if you can answer the following question: