Friedel: Welche Umsetzung ist seriöser?

Moin,

ich habe eine Usertabelle mit Adressdaten. Weiterhin viele andere Tabellen, die viele verschiedene Aktionen festhalten, die ein User so machen kann.

Was ist, wenn ein User seine Adresse ändert? Es soll ja so programmiert sein, dass Aktionen vor der Adressänderung auch mit alter Adresse angezeigt werden und Aktionen mit neuer Adresse natürlich mit der neuen Adresse.

Es geht mir also darum, historische Daten auf dem chronologisch korrekten Stand zu halten.

Hierzu habe ich 2 Möglichkeiten, weiß aber nicht, welche seriöser ist:

  1. Ich habe eine Zuordnungstabelle, die grundsätzlich 2 Dinge festhält, nämlich die UserID und die AktionenID. Dieser Tabelle könnte ich jedes mal die 5 variablen Userdaten mitgeben, sodaß ich diese Daten redundant vorhalte.

  2. Ich halte ja ohnehin fest, zu welchem Zeitpunkt der User welche Aktion macht. Wenn ich nun jede Adressänderung mit Datum in einer eigenen Tabelle festhalte, könnte ich zum Ausgabezeitpunkt dynamisch die chronologisch korrekte Adresse ermitteln.

Sicherlich kann Version 2 sehr viel Speicherplatz einsparen. Aber da ich mir nicht sicher bin, welche der beiden Varianten seriöser, nachhaltiger, sicherer (mir fällt kein geeigneterer Begriff ein) ist, frage ich hier nach.

Vielleicht habe ich ja auch was übersehen?

Danke für Eure Hinweise

Friedel

  1. Hi!

    1. Ich habe eine Zuordnungstabelle, die grundsätzlich 2 Dinge festhält, nämlich die UserID und die AktionenID. Dieser Tabelle könnte ich jedes mal die 5 variablen Userdaten mitgeben, sodaß ich diese Daten redundant vorhalte.

    Das wäre eine sehr einfache Möglichkeit, die auf Kosten des Speicherplatzes geht - was jedoch vermutlich nicht gravierend relevant ist. Beim Abfragen der historischen Daten hast du mit einer unverknüpften Abfrage alles beisammen, was den User betrifft. Diese Vorgehensweise entspricht auch eher der eines Papier-Büros, bei dem jedes Schreiben erneut mit Adressdaten versehen ist.

    1. Ich halte ja ohnehin fest, zu welchem Zeitpunkt der User welche Aktion macht. Wenn ich nun jede Adressänderung mit Datum in einer eigenen Tabelle festhalte, könnte ich zum Ausgabezeitpunkt dynamisch die chronologisch korrekte Adresse ermitteln.

    Du hast dann also eine Usertabelle mit der aktuellen Adresse und eine weitere mit den historischen Adressen? Das ist beim Erstellen einer Abfrage recht aufwendig, weil du da auch immer eine "ist zeitlich am nächsten dran"-Bedingung formulieren musst. Dazu selektiert man in der Regel die Daten älter oder jünger vom gefragten Zeitpunkt (je nachdem, ob das Bis- oder das Von-Datum gespeichert wurde), sortiert den Rest chronologisch und nimmt davon nur den ersten/letzten Datensatz. Mitunter lässt sich solch eine Limitierung nicht in einer Unterabfrage unterbringen.

    Aber wenn du sowieso schon eine extra Tabelle für Adressdaten anlegst, lass doch die Adresse in den Userdaten ganz weg und kennzeichne eine Adresse als aktuell. (Mit diesem Flag entfällt die "neueste"-Abfrage. Das Flag kann gezielt im WHERE angegeben werden.) Zu jedem Zeitpunkt lässt sich über die User-ID und eine Adressen-ID die damals gültige Adresse festhalten. Du ermittelst also die Adresse nicht aus der User-ID und dem Datum im Aktionen-Datensatz sondern über eine dort hinzugefügte Adressen-ID.

    Sicherlich kann Version 2 sehr viel Speicherplatz einsparen. Aber da ich mir nicht sicher bin, welche der beiden Varianten seriöser, nachhaltiger, sicherer (mir fällt kein geeigneterer Begriff ein) ist, frage ich hier nach.

    Seriösität ist nicht so wichtig. Effektivität und Effizienz sind in meinen Augen die maßgebenden Kriterien.

    Lo!

    1. Hi Dedlfix,

      Das wäre eine sehr einfache Möglichkeit, die auf Kosten des Speicherplatzes geht - was jedoch vermutlich nicht gravierend relevant ist.

      Aber, und hier geb ich Dir und Encoder recht, wirklich unschön.

      Du hast dann also eine Usertabelle mit der aktuellen Adresse und eine weitere mit den historischen Adressen?

      Nein, momentan ausschließlich die Usertabelle inkl. der aktuellen Adresse. Das ist gerade das, was mich stört. Denn so gehen die historischen Adressdaten zu den Useraktionen komplett verloren. An dieser Stelle kurz @Encoder: Sicher ist fraglich, ob man die Adressen historisch den Aktionen zuordnen will/muss. In meinem Fall macht es Sinn, sich dafür zu entscheiden.

      Aber wenn du sowieso schon eine extra Tabelle für Adressdaten anlegst, lass doch die Adresse in den Userdaten ganz weg und kennzeichne eine Adresse als aktuell. (Mit diesem Flag entfällt die "neueste"-Abfrage. Das Flag kann gezielt im WHERE angegeben werden.) Zu jedem Zeitpunkt lässt sich über die User-ID und eine Adressen-ID die damals gültige Adresse festhalten. Du ermittelst also die Adresse nicht aus der User-ID und dem Datum im Aktionen-Datensatz sondern über eine dort hinzugefügte Adressen-ID.

      Fantastische Idee. Schade, dass ich da nicht früher (vor Jahren) drauf gekommen bin. Leider wird das viel Arbeit. Skripte umschreiben und Daten reorganisieren :-(
      Aber ich habe einfach nicht bedacht, dass Adressen nichts Eindeutiges und vor allem auch im historischen Verlauf nebeneinander bestehen dürfen und somit normalisiert werden müssen!

      Seriösität ist nicht so wichtig. Effektivität und Effizienz sind in meinen Augen die maßgebenden Kriterien.

      Jo, so in etwa habe ich das auch gemeint. Seriös im Sinne von "es muss nicht einfach nur funktioniere, sondern es soll platzsparend, schnell, stabil und sicher umgesetzt sein".

      Frage noch, glaubst Du wirklich, dass der "Akzuell-Flag" viel bringt, verglichen damit, dass ich ja auch einfach die Adressen nach ID sortieren könnte und über Limit nur die aktuelle abgreife?

      Viele Grüße, Friedel

      1. Hi!

        Frage noch, glaubst Du wirklich, dass der "Akzuell-Flag" viel bringt, verglichen damit, dass ich ja auch einfach die Adressen nach ID sortieren könnte und über Limit nur die aktuelle abgreife?

        Wie gesagt, kann man das aktuell-Flag sehr simpel als Bedingung in der WHERE-Klausel angeben. Im Grunde genommen ist es überflüssig, da sich die aktuelle Adresse aus dem Datum ergibt. Aber das neueste bekommt man nur über eine sortierte Liste mit LIMIT oder mit MAX()/MIN() und Gruppierung abgefragt. Wenn du beispielsweise eine Liste aller User und ihrer aktuellen Adresse haben willst, reicht eine (Erweiterung der) WHERE-Klausel im Gegensatz zu einer korrelierten Unterabfrage.

        Die IDs solltest du jedenfalls nicht als Sortierkriterium verwenden, die sind zum Identifizieren und nur rein zufällig aufsteigend. Der Datumswertpasst schon vom Sinn her deutlich besser.

        Lo!

  2. Es soll ja so programmiert sein, dass Aktionen vor der Adressänderung auch mit alter Adresse angezeigt werden und Aktionen mit neuer Adresse natürlich mit der neuen Adresse.

    Wenn du dir das so definierst soll es so sein. Aber dein "ja" würd ich nicht so selbstverständlich ansehen. Erst mal will man halt wissen was ein User wann gemacht hat. Wo der da grad gewohnt hat, könnte ja auch erst mal egal sein. Kommt auf deine Anwendung an. Um was gehts denn?

    1. Ich habe eine Zuordnungstabelle, die grundsätzlich 2 Dinge festhält, nämlich die UserID und die AktionenID. Dieser Tabelle könnte ich jedes mal die 5 variablen Userdaten mitgeben, sodaß ich diese Daten redundant vorhalte.

    Pfui :-)
    Im Ernst, mach irgendwas, aber nicht sowas.

    Punkt 2 sieht schon viel besser aus. Irgendwo bräuchtest du halt eine Tabelle, in der ein User einmalig mit einer ID definiert ist. Alle weiteren Angaben zu ihm kannst du dann wirklich auslagern und mit einem Änderungsdatum versehen.

  3. hi,

    1. Ich habe eine Zuordnungstabelle, die grundsätzlich 2 Dinge festhält, nämlich die UserID und die AktionenID. Dieser Tabelle könnte ich jedes mal die 5 variablen Userdaten mitgeben, sodaß ich diese Daten redundant vorhalte.

    Warum 5 variable Userdaten mitschleppen? Reduziere das auf die UserId.

    1. Ich halte ja ohnehin fest, zu welchem Zeitpunkt der User welche Aktion macht. Wenn ich nun jede Adressänderung mit Datum in einer eigenen Tabelle festhalte, könnte ich zum Ausgabezeitpunkt dynamisch die chronologisch korrekte Adresse ermitteln.

    Auch die Adressänderung ist eine Aktion. Du hast da sicher eine Tabelle mit den User-Objekten und uid as primary key. Da würde ich nur die aktuelle Adresse reinschreiben. Was der vorher an Adressen hatte steht in der Aktionstabelle mit uid as foreign key.

    Hotti

    1. Auch die Adressänderung ist eine Aktion. Du hast da sicher eine Tabelle mit den User-Objekten und uid as primary key. Da würde ich nur die aktuelle Adresse reinschreiben. Was der vorher an Adressen hatte steht in der Aktionstabelle mit uid as foreign key.

      Hallo Hotti,

      die aktuellen Adressen in der Usertabelle zu belassen, käme mir schonmal sehr entgegen, denn dann könnte ich auf bereits vorhandene Daten "aufsetzen", sprich ich müsste die Usertabelle erstmal nicht ändern.

      Mein Problem ist dann aber folgendes: Wenn dann eine Adressänderung (oder z.B. Namensänderung wenn eine Frau heiratet) stattfindet, wie bringe ich der Historie dann bei, dass sie nicht mehr die Namen und Adresse aus der aktuellen Usertabelle nimmt, sondern den nun in die neue Tabelle kopierten "alten" Namen, bzw. Adresse?

      Grundsätzlich wäre es besser, Namen und Adresse aus der Usertabelle zu entfernen und in eine extra Tabelle zu packen. Aber dann müsste ich infolgedessen geschätzte ca. 1 fantastlillionen queries ändern (alleine knapp 50 Dateien mit jeweils 1-10 queries). Ich frage mich, ob ich daran vorbei kommen kann??

      Aber ich befürchte fast, das wird eine Lebensaufgabe. :-(

      Friedel

      1. hi Friedel,

        Mein Problem ist dann aber folgendes: Wenn dann eine Adressänderung (oder z.B. Namensänderung wenn eine Frau heiratet) stattfindet, wie bringe ich der Historie dann bei, dass sie nicht mehr die Namen und Adresse aus der aktuellen Usertabelle nimmt, sondern den nun in die neue Tabelle kopierten "alten" Namen, bzw. Adresse?

        Genau da ham wir wieder einen schlüssigen "Beweis" dafür, dass ein User eben nur einer Nummer entspringt ;-)

        Ja, ne, is klar, die UiD muss von allen Attributen unabhängig sein, das ist der Hack bei der Sache.

        Grundsätzlich wäre es besser, Namen und Adresse aus der Usertabelle zu entfernen und in eine extra Tabelle zu packen.

        Eine Nicht_Normalform zu haben ist keine Schande.

        Aber ich befürchte fast, das wird eine Lebensaufgabe. :-(

        Bringe OOP ins Spiel, da geht der Griff nicht in tausende Scripts oder Codezeilen.

        Hotti

        --
        Achtung dreifaches Mißverständnis: Bier in Massen.