MySQL Tabellen Layout / Datenspeicherung

Fabian17

Fabian23
ID: 304783
L
18 Mai 2007
1.674
105
Moin,

ich hab da mal eine Frage bzgl Datenbank (MySQL)

Undzwar arbeite ich jetzt wieder an meinem Gruppen-Addon (ähnlich der VZ Seiten)

Link

Habe das vor etwa einem Monat schon angefangen, hatte aber keinen Plan wies weiter geht...

undzwar komm ich einfach nicht drauf wie ich am Besten die Zugehörigkeit

Benutzer => Gruppe speichern soll, also in ein Tabellen Layout umsetze.

Die Benutzer haben eine fortlaufende ID zB "1" ist meine ID,

Die Gruppe: Beispielgruppe hat auch eine fortlaufende ID in dem Link "1"

Jetzt ist der Sinn einer Gruppe natürlich das mehrere Benutzer der Gruppe angehören

UserID | GroupID
1 | 1
2 | 1
4 | 1
1 | 2
7 | 2 etc..

Aber wenn ich etwas in dem Format speichere habe ich ja eine riesige Tabelle dann am Ende (wenn es Viele Gruppen mit vielen Benutzern gibt)

Also kann ich es so ja nicht wirklich abspeichern,

table_group_member
GroupID | GroupMember
1 | 2,4,5,3,6,1
2 | 1,2,4,5,10
3 | 1,5,2,4

So in etwa stelle ich mir das vor, wie es am Besten laufen könnte, nur leider habe ich dazu keinen Plan wie ich soetwas erstelle, und im php Script dann die Einträge durch ein "," getrennt und wieder gelesen werden -.-

Oder ist diese Denkweise überhaupt total falsch?

ich muss wie gesagt nur die Gruppen > 1:N < Benutzer zusammenfügen,

bin über jede Hilfe dankbar :)

Gruß,
Fabian
 
Aber wenn ich etwas in dem Format speichere habe ich ja eine riesige Tabelle dann am Ende (wenn es Viele Gruppen mit vielen Benutzern gibt)
Wenn ich mich recht entsinne wurden Datenbanken für große Datenmengen geschaffen ;)
Wenn sie zu groß wird (mehrere Milliarden Einträge) dann kannst du die Tabelle eben partitionieren.
In einer Gruppen-Tabelle 1 stehen die Gruppenzugehörigkeiten zu den Gruppen 1-9, in Tabelle 2 von 10-18 ....
In einer User-Tabelle stehen die User mit der Id 1 - 5000 und deren Gruppen, in einer Tabelle stehen .....

aber dazu musst du erstmal soviele Einträge haben....
Also deine Idee war komplett richtig und ist das Best-Practice.

table_group_member
GroupID | GroupMember
1 | 2,4,5,3,6,1
2 | 1,2,4,5,10
3 | 1,5,2,4
Verstoß gegen die 1. Normalform, Idee gleich wieder vergessen.
Wenigstens die 1. Normalform muss immer eingehalten werden :!:
 
1.Wenn ich mich recht entsinne wurden Datenbanken für große Datenmengen geschaffen ;)

Also deine Idee war komplett richtig und ist das Best-Practice.

zu 1. Stimmt schon eigentlich ;)

Aber Übersichtlich ist das am Ende dann ja nicht soo (naja wann schaut man schon mal inne SQL, wenns per Script läuft).

Dann werde ich das mal so versuchen.
Danke erstmal!
 
Aber Übersichtlich ist das am Ende dann ja nicht soo (naja wann schaut man schon mal inne SQL, wenns per Script läuft).

Du hast dich eine Speicherung der Daten in eine relationale Datenbank entschieden, dann musst du es eben so abbilden wie es am besten in ein relationales Modell passt, egal ob es "menschenlesbar" ist oder nicht ;)
 
zu 1. Stimmt schon eigentlich ;)

Aber Übersichtlich ist das am Ende dann ja nicht soo (naja wann schaut man schon mal inne SQL, wenns per Script läuft).

Dann werde ich das mal so versuchen.
Danke erstmal!

Die Übersichtlichkeit muss DICH in der DB ja nicht interessieren. Der Ansatz ist schon vollkommen korrekt. Ich habe solch Gruppengedöhns auch auf meiner Seite umgesetzt, genau nach dem Schema.

group_member hat zum einen eine fortlaufende ID, dann gruppenID, memberID, Status (gründer oder member), und noch ein paar andere Dinge.

Selbst wenn du 1000 Mitglieder in einer Gruppe hast, lässt Du ja nicht alle 1000 mit einmal anzeigen, sondern nur eine gewisse Anzahl + "Blättermöglichkeit". Wenn Du dann memberID und gruppenID auch noch indexieren lässt, gibt es keinen merklichen Unterschied, ob da nun 5000 oder 2,8Mio Einträge drin sind.
Und, falls doch, kann man nach 5 Jahren hornalte Gruppen auch mal droppen...

Gruß
 
table_group_member
GroupID | GroupMember
1 | 2,4,5,3,6,1
2 | 1,2,4,5,10
3 | 1,5,2,4

Um Gottes Willen. 8O

  • Was machst du, wenn du wissen möchtest, in welchen Gruppen Benutzer x ist? Alle Gruppen ausgegeben, und dann unzählige Strings nach der richtigen ID durchsuchen?
  • Ein Benutzer wird gelöscht, du möchtest die BenutzerID aus den Tabelle "tblgruppen" löschen - wie stellst du dir das vor?

UserID | GroupID
1 | 1
2 | 1
4 | 1
1 | 2
7 | 2 etc..

So - und nicht anders (!) - solltest du es machen. Datensätze sollten möglichst atomar sein. ;)

Schau mal:

database.jpg
 


Dieses Format 1,2,3,4 habe ich mal in einem Fertigen Script gesehen (daher die Idee) da wurden Daten so abgespeichert

entweder:

aID | bID
1 | 1,2,4,5

oder

aID | bID
1 | 1|2|3|4|5

, Habs jetzt so gemacht wie ich erst wollte, dann doch nicht (Ihr habt mich dann doch überzeugt das das richtig wäre :p),

Welches Programm nutzt du um die Diagramme (dein Beispielbild) zu erzeugen?,

###

Jetzt bin ich bei einem "2ten" Problem, was aber wieder eher mehr mit PHP, zu tun hat,

Undzwar möchte ich gerne die Gruppen User Ausgeben wie bei einer "recht" bekannten Seite (möchte mal keinen Namen nennen :p)

picture.php


Soetwas halt..

Also zB 6 Spalten â 2 Zeilen

Ausgeben tue ich die benötigten Daten im Array

PHP:
{
$mitglieder .= 'Benutzerbild, Benutzername etc...';
}
(Die "datenhol querys habe ich mal weggelassen, kann sich ja vermutlich jeder denken)

Ich habe damals schon mal etwas ähnliches damit aufgebaut, ich weiß nur nicht mehr wie das genau ging -.-

Mit break oder so?

Also fülle das Array mit Daten, stoppe nach 6Spalten bilde neue Zeile fülle wieder bis 6Spalten STOP.

Weiß jemand gerade zufällig wie soetwas geht?

Gruß
 


PHP:
$mitgliedersql = "SELECT groupmemberID FROM ".PREFIX."groups_member WHERE groupID='".$id."'";
$dresult = mysql_query ($mitgliedersql);
while($array = mysql_fetch_array($dresult))
{
$mitglieder .= '<a href="index.php?site=profile&id='.$array['groupmemberID'].'"><img src="images/avatars/'.getavatar($array['groupmemberID']).'" widht="45" height="45" border="0" /></a>
'.getnickname($array['groupmemberID']).'';
}

Also der Ganze Aufbau ist in einer einzigen php Datei, die entsprechenden Templates werden dann eingebunden

mit

PHP:
		eval("\$groups = \"".gettemplate("groups")."\";");
		echo $groups;

Das Problem mit dem CSS ist dann aber das das php script doch das array solange befüllt bis keine Daten mehr vorhanden sind richtig?
 
Dieses Format 1,2,3,4 habe ich mal in einem Fertigen Script gesehen (daher die Idee) da wurden Daten so abgespeichert

aID | bID
1 | 1,2,4,5

Ich glaube dir, dass du es in einem fertigen System gesehen hast - aber diese Form der Datenverwaltung macht absolut keinen Sinn.
Warum, habe ich dir ja schon erklärt.

Also fülle das Array mit Daten, stoppe nach 6Spalten bilde neue Zeile fülle wieder bis 6Spalten STOP.

Die Daten, die du vorher aus der Datenbank abfragst, gehst du ja in einer while-Schleife durch.
Eigentlich sollte der Zeilenumbruch automatisch erfolgen, wenn dein CSS-Part stimmt, wenn du es aber unbedingt Serverseitig lösen möchtest:

PHP:
if($i%6 == 0)
 echo '<br>';

In der Variablen $i werden die Schleifendurchgänge mitgezählt. ;)

eval("\$groups = \"".gettemplate("groups")."\";");
echo $groups;

Hast du das Script geschrieben? 8O
 
1.Wenn du es aber unbedingt Serverseitig lösen möchtest:

PHP:
if($i%6 == 0)
 echo '<br>';

In der Variablen $i werden die Schleifendurchgänge mitgezählt. ;)



2.Hast du das Script geschrieben? 8O


1. Funktioniert ;), alle 6 Spalten kommt ne neue Zeile, kann man das auch noch einstellen das nach 2 Zeilen schluss ist? da er mir bei 13 Usern, noch eine neue Zeile reinmacht :/

2. Die Seite ansich basiert auf einem CMS, die einzelnen Scripte / Addons sind selbst gemacht (man kann sich halt unter umständen gut an anderen Funktionen bedienen)

Wie zB mein Gallery Bild Verlinkungs "Addon"
Beispiel.

Mit Google,Klamm und vorhandenen Funktionen kann man dort viel schaffen ;)
 
Ich hoffe mal deine getavatar- und getnickname-Funktionen führen selbst keine Querys aus, denn das wäre echt ineffizient:
12 Bilder * (1 Avatar-Abfrage + 1 Nickname Abfrage) = 24 Anfragen
 
Neues Problem, vermutlich neue Frage :)

Habe ja jetzt das schicke DB Modell

groupID | mitgliedID
1 | 2
2 | 2

etc...

Jetzt bin ich gerade dabei im Profil auszugeben in welchen Gruppen denn der User aktiv ist ;)

Also im Profil:

Gruppen:
*Gruppe1
*Gruppe2
etc..

Vorhaben:

Zuerst einmal:

SELECT groupID FROM table_group_member WHERE groupmemberID = $userID

damit erhalte ich dann doch die Gruppen ID, in denen der User vorkommt oder nicht?,
Nun habe ich ja die Gruppen ID erhalten, und kann aus der Tabelle Groups den Namen auslesen

SELET groupname FROM table_groups WHERE groupID = $groupID

jetzt kann ich den Namen ausgeben,
nur geht das nicht :(

PHP:
$ergebnis = safe_query("SELECT groupID FROM ".PREFIX."groups WHERE groupID='".$userID."'");
	$ds = mysql_fetch_array($ergebnis);	

$groupsql = "SELECT name FROM ".PREFIX."groups WHERE groupID='".$ds['groupID']."' LIMIT 10";
$dresult = mysql_query ($groupsql);
while($array = mysql_fetch_array($dresult))
{
$groups .= '<li>'.$array['name'].'</li>';
}
 
Zuletzt bearbeitet:
PHP:
$q = mysql_fetch_array(mysql_query("SELECT groupname FROM table_groups WHERE groupID = ".$groupID.""));
echo $q[0];

Ich empfehle dir, dich etwas mit den Grundlagen von PHP / MySQL zu beschäftigen. Wenn du bei solch leichten Aufgaben Probleme hast, dann wird deine Applikation am Ende garantiert über schwerwiegende Sicherheitslücken verfügen.
Und wenn du Fragen hast, solltest du selber im Internet nachschauen, statt jede Kleinigkeit nachfragen, sonst lernst du nichts.

Und das ist ja nicht Sinn der Sache. ;)
 
PHP:
$q = mysql_fetch_array(mysql_query("SELECT groupname FROM table_groups WHERE groupID = ".$groupID.""));
echo $q[0];

Das ist doch im Prinzip 1zu1 das selbe, was ich hatte nur das ich den safe_query nutze da die vom cms System so üblich ist.

nur das echo $q[0]; ist dazu gekommen

EDIT hatte oben nicht alles reingepostet sehe ich gerade,

EDIT2, obiger geposteter Code ging doch... hatte die ganze Zeit die falsche Datei (die Datei, die ich zuvor bearbeitet habe) hochgeladen... (nicht lachen :D)

Allerdings wird mit dem Schnippsel, nur 1 Gruppe je User ausgegeben, ich vermute da er nur 1x die erste groupID ausliest in dem der User ist. (die Oberste)
Also müsste ich theoretisch dort auch ein array laufen lassen oder nicht?
 
Zuletzt bearbeitet:
Oh Gott! Vergiss dieses 2x SELECTen mal ganz schnell wieder 8O
In MySQL gibts sowas wie Schlüssel und JOINs ;)

Drum überlegst du dir dein Datenbankmodell ja zu Beginn genau, um dann solche Abfragen effizient von MySQL durchführen zu lassen.

Die Gruppe hat eine ID (= hoffentlich der PRIMARY KEY), der sie eindeutig identifiziert. Diese ID ist Fremdschlüssel in deiner N:M-Beziehung Gruppe/Mitglied. Somit kannst du an die N:M-Beziehung sowohl Mitglied-, als auch Gruppentabelle ranJOINen.

In deinem Fall genügt Letzteres, wenn du vom Mitglied nichts haben willst. Möglich wäre aber ohne Probleme eine Abfrage "Gib mir alle Gruppenteilnehmer in Gruppe mit dem Namen 'Foo', die männlich sind und (z.b. weitere JOINs) mindestens 5 Freunde haben und in einem Ort wohnen, der mehr als 50.000 Einwohner hat".

Ein Buch zu Datenbanken ist dringend erforderlich, da hier komplett die Basics fehlen!

P.S. IDs sind numerisch! .... hoffentlich