Seite 1 von 1
[solved]Aufgeräumte Datenbankstrukturen
Verfasst: Mi 12. Apr 2006, 07:05
von rethus
Hier noch ein Tip aus meinem eigenen CMS-System:
Ich habe gemerkt, das die Datenverwaltung in der Datenbank nicht geordnet ist (moment noch nicht aufregen... ich erkläre es

)
Wenn ich eine Sprache anlege, und losche... und anlege... und lösche... und anlege hab ich hinter der Sprace die ID 3 stehen. Ergo wird hier die Datenbankstruktur nicht chronologisch gehalten....
Mein Lösungsansatz (der wunderbar Funktioniert - ist langzeiterprobt ... 4 Jahre):
Erstellen einer Datenbank KeyBasket mit den Feldern:
DROP TABLE IF EXISTS keybasket;
CREATE TABLE keybasket (
key_id int(5) NOT NULL default '0',
tablename varchar(255) NOT NULL default ''
) TYPE=MyISAM COMMENT='Speichert die einzelnen Schlüssel, die in den Tabellen gelöscht wurden, um diese für neue Datensätze zu vergeben';
Beim löschen eines Datensatzes wird die ID des zu löschenden Datensatzes in die Tabelle Keybasket geschrieben, inkl. dem Tabellennamen, aus dem die ID Stammt.
Wenn nun im Modul Sprache (nur mal beispielsweise herangezogen) ein neuer Datensatz vorhanden ist, fragt er die Tabelle KeyBasket erst ab, ob für Ihn eine ID bereit liegt. Wenn ja, nimmt er diese, und löscht Sie aus dem KeyBasket, wenn nicht, erstellt er ganz normal einen neuen Datensatz.
In meinem System habe ich eine globale Datenbank-Schnittstellenklasse gehabt, die eine Implementierung einer solchen funktion innerhalb von 15 Minuten erlaubt... ich weiß leider noch nicht, wie das bei Contenido aufgebaut ist, weil ich mir den Quellcode noch nicht zur gemüte geführt habe....
1. Was haltet Ihr von der Idee?
2. Hat Contenido eine globale Datenbank-Schnittstelle, in der alle SQL-Anweisungen gekapselt sind?
Verfasst: Mi 12. Apr 2006, 07:28
von phpchris
Also ich finde das ist sowas wie "Das Rad neu erfinden".
Wo ist der Vorteil gegenüber, wenn man id=4 stehen hätte?
Verfasst: Mi 12. Apr 2006, 07:53
von Dodger77
Ich finde es jetzt schwierig, den Vorteil davon zu entdecken. Eine ID ist eine ID ist eine ID, ob jetzt 1 oder 42.
Verfasst: Mi 12. Apr 2006, 07:57
von phpchris
Sehe ich genau so.
Deine Idee, oder deine Lösung finde ich sehr gut.
Bloß ich denke, dass man sich hiermit nur eine Fehlerquelle einbaut.
Verfasst: Mi 12. Apr 2006, 12:00
von knb
Nur so nebenbei:
Die Tabelle in der Contenido die zuletzt vergebenen Ids speichert heisst <PREFIX>_sequence, also z.B. con_sequence.
Verfasst: Mi 12. Apr 2006, 13:00
von HerrB
2. Hat Contenido eine globale Datenbank-Schnittstelle, in der alle SQL-Anweisungen gekapselt sind?
Es gibt einen Ansatz. Bitte setze Dich mit dem Quell-Code auseinander.
Gruß
HerrB
Verfasst: Do 13. Apr 2006, 14:06
von rethus
knb hat geschrieben:Die Tabelle in der Contenido die nächsten zu vergebenden Ids speichert heisst <PREFIX>_sequence, also z.B. con_sequence.
Frage: Warum gibts so ne Tabelle, wenn die ID's sowieso nicht chronologisch vergeben werden?
PS: Kann schon versehen was Ihr meint... ...bin wahrscheinlich Ordnungsfanatiker

... bzw. hatte ich zuvor Funktionen, die so etwas brauchten...
=====
Ok, danke für die vielen Antworten.
Würde es helfen, wenn ich hier mal meine alte DB-Schnittstellendatei poste, in der ich die Funktionen gekapselt habe?
Übrigens ist eine solche DB-Schnittstellen-Klasse wunderbar... da hat man auch mal innerhalb von ein paar stunden ganz neue Features (Loging, Watchdog etc) inkludiert.... ist auf jedenfall der richtige weg für so ne tolle Anwendung wie Contenido...
Verfasst: Do 13. Apr 2006, 14:22
von Halchteranerin
rethus, nichts fuer ungut, aber warum bist du nicht bei deinem ach so tollen CMS geblieben oder kehrst dahin zurueck, wenn dir fast nichts bei Contenido passt und du alles umkrempeln wuerdest (am besten natuerlich nach dem Vorbild deines CMS)? Natuerlich kann man Verbesserungsvorschlaege machen, die, sofern sie sinnvoll erscheinen, auch IRGENDWANN uebernommen werden. Aber wenn ich mir deine Beitraege in diesem Monat angucke, ich glaube die meisten sind hier unter "Feature Requests" zu finden (und du bist erst seit Ende Maerz angemeldet), frage ich mich langsam, was du eigentlich bezweckst ...
Verfasst: Do 13. Apr 2006, 14:25
von Beleuchtfix
rethus hat geschrieben:Frage: Warum gibts so ne Tabelle, wenn die ID's sowieso nicht chronologisch vergeben werden?
Also die Nummern werden schon chronologisch vergeben, nur wenn ein Datensatz gelöscht wird, wird eine schon einmal vergebene Nummer nicht mehr neu vergeben. Ich glaube nicht, das das ein Problem ist. Über das warum kann ich nur Vermutungen anstellen, und die sind wahrscheinlich eh falsch.
Florian
Verfasst: Do 13. Apr 2006, 15:14
von HerrB
Das warum ist ganz einfach: Nicht alle Datenbank-Systeme, insbesondere Oracle bieten eine AutoIncrement-Spalte.
Oracle z.B. verfügt über einen eigenen Typ von Elementen, mit denen eineindeutige IDs erzeugt werden (Sequenzen). mySQL und MS Access verfügen über AutoIncrement, was SQL-Server verwendet, weiss ich gerade nicht.
D.h. die Art der Erzeugung ist von Datenbank-Hersteller zu Datenbank-Hersteller unterschiedlich: Tödlich in der Entwicklung, wenn man mehrere Systeme unterstützen möchte.
Außerdem ergibt AutoIncrement regelmäßig Probleme, wenn es um das Restore von Datensätzen geht - in mySQL vielleicht weniger, aber MS Access lässt es z.B. gar nicht erst zu, Zeilen mit freier ID einzutragen (auch wenn sie kleiner dem aktuellen max. Wert sind).
Daher ist es relativ verbreitet, bei Plattformunabhängigkeit die IDs selbst zu pflegen. Zur Natur von diesen IDs gehört auch, dass sie - einmal vergeben - nie wieder verwendet werden; die 3 Byte fallen nicht wirklich ins Gewicht und man vermeidet vermeidbare Probleme... (aufgrund eines anderen Fehler erscheinen auf einmal z.B. ungewollte Datensätze aus der Versenkung).
Gruß
HerrB
Verfasst: Do 13. Apr 2006, 15:26
von rethus
Und schon wieder etwas gelernt...
Danke HerrB

Verfasst: Do 13. Apr 2006, 16:10
von kummer
nur so nebenbei. eine id kostet nichts. davon gibt es so viele, dass auch über jahrtausende nicht alle zahlen verbraucht sind. ein rechenbeispiel. wenn du jede sekunde eine million einträge machen würdest und das über sagen wir mal 1000 jahre: dann hättest du gerade mal 3.16E16 werte verbraucht. und das ist nur ein bruchteil dessen, was verfügbar ist.
man braucht sich also durchaus keine sorgen zu machen bezüglich der id.
hinzu kommt ein umstand, den man nicht unter den tisch kehren sollte. innerhalb der datenbank besteht ordnung durch constraints. aber zuweilen werden id auch ausserhalb der anwendung selber verwendet (z.b. als kundennummer oder so). unter diesen umständen wäre es dann absolut ungünstig, wenn eine nummer nach gebrauch wieder frei gegeben und neu verwendet werden würde. sowas würde ich aus diesen (und weiteren) gründen unbedingt unterlassen.
Verfasst: Mi 19. Apr 2006, 09:16
von knb
ich denke das vergeben einer neuen nicht verwendeten id hat die Ordnung O(1) - d.h. der Aufwand ist konstant.
während das housekeeping von bereits vergebenen ids die Ordnung o(n) hätte oder vielleicht sogar O(n²)
etwas ad-hoc konstruiertes beispiel:
stell dir vor du hast zwei mandanten mit je 1000 artikeln , zufällig verteilte art_ids in den Contenido Tabelle wie z.B. con_art_lang
Jetzt willst Du alle Artikel eines mandanten löschen. es werden 1000 neue artids zum Recyclen freigegegeben. Die müssen alle in deine Keybasket tabelle eingetragen werden. => mindestens 1000 insert-intos in die "Keybasket" tabelle .
Wahrscheinlich musst Du die sachen auch zig-mal sortieren bevor du sie ablegen kannst, error handling und transaktionslogik wollten implementiert sein...
Denke mal wie gesagt, der Aufwand für den löschvorgang steigt (über-)proportional zur Menge der zu löschenden Objekte. Keybasket- Tabelle wäre potentieller Hotspot in der DB, und der Ansatz brächte wohl Performanceprobleme v.a. bei größeren Websites.
Der "con_sequence Tabellen Ansatz " dagegen ist Jahrzehnte alt und hat sich bewährt.