|
|
#1 (permalink) | |||||||||||||||||||||||||||||||
|
schwankend^^
|
Hallo,
und schon wieder stehe ich vor einem kleinen Problem. Ich programmiere gerade ein kleines Backup-System für den Eigengebrauch und habe dort nun folgende Datenbankstruktur erstellt: Tabelle 1: global_backups Hier sind allgemeine Informationen zu den Backups enthalten
Tabelle 2: global_backups_kinds Hier sind die Backup-Arten zu den Backups gespeichert (MySQL oder FTP)
Tabelle 3: global_backups_projects Hier sind die Projekte gespeichert die in den einzelnen Backups gespeichert sind
Aus diesen Tabellen brauche ich nun ein Array, das wie folgt aussieht: PHP-Code:
PHP-Code:
Problem 1: Eine Blätterfunktion um die Einträge auf mehrere Seiten zu verteilen ist mit MySQL und LIMIT x, y nun nicht mehr möglich, da ich nicht weiß, welche Datenreihen zusammengehören, bevor ich das PHP-Script drüberlaufen gelassen habe. Ich müsste also generell alle Backups auslesen und dann mit PHP auf die verschiedenen Seiten verteilen. Problem 2: Eine Suchfunktion, die nach einzelnen Projekten sucht und dennoch alle in diesen Backups enthaltene Projekte ausgibt ist nun auch nicht mehr möglich, denn wenn ich eine WHERE `project_name` IN (...) einfüge, erhalte ich ja logischerweise auch im Result nur die Daten, nach denen ich gesucht habe und nicht mehr die anderen Daten. für eine derartige Suchfunktion müsste ich also auch wieder alle Daten auslesen und dann mit PHP diese Daten durchsuchen. In der Hoffnung, nicht bereits alle mit dem ganzen Text abgeschreckt zu haben: Gibt es hierfür vielleicht eine intelligentere Lösung mit MySQL? Vielen Dank im Vorraus. mfg Gsus |
|||||||||||||||||||||||||||||||
|
|
|
| Gesponsorte Links |
|
|
#2 (permalink) |
|
Multitalent
|
Ich verstehe ehrlich gesagt deine Tabellenstruktur nicht so ganz. Was sollen denn z.B. diese Projektnamen aussagen? Wäre es nicht möglich wenigstens die Tabellen 2 und 3 in einer zu verschmelzen?
Und vielleicht ging es sogar mit einer Tabelle. Es könnte schließlich auch mehrere Backups geben. Zwei könnten den letztlich selben Zeitpunkt haben aber verschiedene Typen beinhalten. Vermutlich wird das schon irgendwie ohne PHP-Umweg gehen, aber du müsstest eben mal erklären was der Zweck sein soll. |
|
|
|
|
|
#3 (permalink) |
|
bekämpft die Mächte des Bösen
|
So von Tabellennamen- und Inhalten würd ich von 2x n:m-Beziehung ausgehen. Also dass Kinds und ProjectNames sowas wie Tags für ein Backup sind. Falls ja, wären hier erstmal zwei neue zusätzliche Tabellen angebracht, um n:m ordentlich zu mappen.
|
|
|
|
|
|
#4 (permalink) |
|
schwankend^^
|
mhh eigentlich sind es zwei 1:n beziehungen
und zwar: ein backup kann mehrere (unbegrenzt viele) Projekte beinhalten. und ein backup kann auch ein oder zwei arten (kinds) nämlich ftp, mysql oder eben beides beinhalten. dabei ist dann eben in der backups-Tabelle die ID der PK, und in den anderen 2 jeweils die Kombination aus ID und zweitem feld. Das ganze soll dann den Sinn haben, dass man sowohl Backups von nur einem Projekt und einer Art (z.B. nur MySQL-backup eines Projektes) machen kann, oder auch von dem ganzen Server (alle Projekte, MySQL+FTP). |
|
|
|
|
#5 (permalink) | ||
|
bekämpft die Mächte des Bösen
|
Zitat:
Zitat:
Deiner Formulierung nach ist es nämlich nicht möglich, in einem Backup Projekt A nur MySQL und Projekt B mit MySQL+FTP zu sichern. |
||
|
|
|
|
|
#6 (permalink) | ||
|
schwankend^^
|
Zitat:
Darum liegt der PK auch auf der Kombination von Backup-Id und Projektname. Dadurch kann ja ein Projektname in beliebig vielen Backups vorkommen. Zitat:
mfg Gsus |
||
|
|
|
|
#7 (permalink) |
|
Erfahrener Benutzer
|
ich würde mal die Abfrage erweitern... (anders machen)
Also die Backup_ID ist ein PK? Und wenn inden Tabellen jeweils der PK den gleichen Namen besitzt, so versteh ich das hier jedenfalls, dann kann man auch nen einfachen JOIN machen mittels ",". Nun meine Variante mittels normalem JOIN (table1,table2,table3) : WHERE (tablename.Backup_ID = tablename2.Backup_ID AND tablename.Backup_ID = tablename3.Backup_ID) Ich weißleider nicht mehr wo der unterschied zwischem dem inner join, left join, right outer join oder so liegt, aber bisher habe ich alles mit einem normalen join lösen können, wenn die Struktur der tabellen drunter mindestens die 3.NF erfüllt |
|
|
|
|
|
#8 (permalink) | ||
|
bekämpft die Mächte des Bösen
|
Zitat:
Backupst du Projekte oder Projektnamen? Ich mach immer Sicherungen von den Projekten. Der Name wird ja durch das Projekt vorgegeben, den muss ich also nicht sichern ![]() Primary Key auf ID+Projektname is Quark. Eine ID-Spalte is implizit immer eine UID, also die is nie an ein anderes Datum geknüpft (außer an einen Foreign Key bei n:m). Ich käme also auf:
Zitat:
Wo werden unnötige Werte abgespeichert? edit: Solltest du so einen Fall doch noch konstruieren wollen, wie ich in Post #5 im unteren Absatz geschildert hab, könntest du Kind von Backup in BackupProject schieben. |
||
|
|
|
|
|
#9 (permalink) |
|
schwankend^^
|
Okay, offensichtlich habe ich mich falsch ausgedrückt
Meine aktuellen Tabellen: backups(backup_id, datum,...) backups_kind(backup_id, kind{mysql, ftp}) backups_projects(backup_id, project_name) eine Projekte-Tabelle habe ich ebenfalls: projects(project_name,...) Darüber hinaus habe ich die nötigen foreign keys (die sich hier durch die Namensgebung der Tabellenspalten denke ich selbst erklären) vergeben und auf CASCADE gestellt. Dadurch ist mein project_name sozusagen eine project_id (nur eben in anderen datenformat)! Es ist möglich, dass: a) ein Backup nur FTP, oder nur MySQL oder beides b) ein Backup mehr als ein Projekt umfässt Es ist nicht möglich, dass: a) ein Backup für Projekt 1 nur FTP und für Projekt 2 nur MySQL-Daten enthält (auch nicht in anderen Kombinationen) Daher kommt meine Struktur deiner doch schon sehr dicht, nur dass ich kind ebenfalls ausgelagert habe. Ich denke nun habe ich auch verstanden, was du mit deinen zwei bool Attributen meintest. Du meintest ein extra Feld ("kind") in der Bakup-Tabelle wo nun eine 0 (=nur FTP), 1 (=nur MySQL) oder 2(=FTP+MySQL) drinsteht? Habe ich das so richtig verstanden? Ich verstand folgendes: Zwei extra boolean spalten ("mysql" + "ftp") in denen dann jeweils eine 0 oder 1 drinsteht. dadurch habe ich unnötige Informationen gespeichert (nämlich ich speichere, was nicht in Backup enthalten ist, wenn ich eine 0 in der Tabelle habe. Diese Daten kann ich mir aber ableiten, wenn ich nur speichere, was da schon enthalten ist, denn alles andere ist bekanntlich nicht enthalten). Mit diesem Ansatz, könnte ich die Tabellenanzahl aber in der Tat um 1 verringern. Das löst nur leider immernoch nicht das eigentliche Problem mfg Gsus |
|
|
|
|
#10 (permalink) | ||||||||
|
bekämpft die Mächte des Bösen
|
Zitat:
Ok, verstanden. Dann bleibt dieses Attribut also an der Sicherung, nicht am n:m-Glied. Zitat:
Jetzt, wo das DB-Design klar is (ich geh also davon aus, dass deine kind-Tabelle verschwindet und als Attribut am Backup hängt), kann man sich dem Problem widmen. Problem 1: Da du ne n:m-Beziehung hast, wirst du wohl zwei Abfragen machen. Der JOIN - wie du schon richtig festgestellt hast - bringt unterschiedlich viele Zeilen pro Backup und kann somit nicht nach Backup seitenweise geblättert werden. Lösung: Code:
Problem 2: Die erste Abfrage aus Problem 1 wird um eine Unterabfrage erweitert. Code:
|
||||||||
|
|
|
|
|
#11 (permalink) | ||||||||||
|
Erfahrener Benutzer
|
Zitat:
n ist eine ganze Zahl ist DATETIME nicht ein reserviertes Wort bei sql ? Code:
Kind vom Typ int, weil 1 = ftp, 2 = mysql, 3 = ... was in php dann einfach auszuwerten ist. Code:
Geändert von tobomator (21.01.2012 um 17:22:41 Uhr) |
||||||||||
|
|
|
|
|
#12 (permalink) | ||||
|
schwankend^^
|
Zitat:
mfg Gsus |
||||
|
|
|
|
#13 (permalink) | |
|
bekämpft die Mächte des Bösen
|
Zitat:
Bsp: Backup 1 enthält Projekte A, B, C. Backup 2 enthält Projekte A, D. Suchst du nach Projekt A, kriegst du Backup 1 und Backup 2. Suchst du nach Projekt B, kriegst du nur Backup 1. Suchst du nach Projekt D, kriegst du nur Backup 2. Du kriegst deshalb alle, weil du ja explizit alle Projekte (unabhängig von einer Suche) aus der n:m-Beziehung abfragst (s. zweite Abfrage bei Problem 1). edit: Verständlicher: Die Suche schränkt nur nach den Backups ein, nicht nach den BackupProjects-Zeilen. Die werden ausgehend von den Backups nachgeladen. |
|
|
|
|
|
|
#14 (permalink) |
|
schwankend^^
|
Und wieder habe ich mich unverständlich ausgedrückt
Ich meinte damit: Das result des Subquerys ist nicht mit den zum gleichen Backup gehörigen anderen Datensätzen der gleichen Tabelle verbunden, weshalb ich nicht nach mehreren Projekten suchen kann. Um dein Beispiel zu benutzen: Backup 1 enthält Projekte A, B, C. Backup 2 enthält Projekte A, D. Backup 3 enthält Projekte A, B, D. Nun möchte ich nach A und B suchen können und Backup 1 und 3 erhalten, also alle Backups, in denen alle angegebenen Projekte (oder mehr) enthalten sind. mfg Gsus |
|
|
|
|
#15 (permalink) | ||||
|
bekämpft die Mächte des Bösen
|
Zitat:
In dem Fall würde ich dann eher dazutenden, dann du alle ProjectBackups aus der DB holst, die zu einem gesuchten Projekt passen, also in deinem Beispiel Code:
Das baust du dir dann relativ einfach in PHP. Es kommen der Reihe nach alle Projekte eines Backups, bevor das nächste Backup beginnt. Und die Projektnamen sind auch sortiert, d.h. du weißt genau in welcher Reihenfolge was zu erwarten is. |
||||
|
|
|
![]() |
| Gesponsorte Links |
| Anzeige |
| Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1) | |
| Themen-Optionen | |
| Ansicht | |
|
|
Ähnliche Themen
|
||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| [SQL] Passender Query? | tomtom | Programmierung | 6 | 13.11.2007 16:11:31 |
| [PHP] MySQL Query | sam940 | Programmierung | 3 | 08.12.2006 17:36:49 |