• 27.04.2024, 12:37
  • Registrieren
  • Anmelden
  • Sie sind nicht angemeldet.

 

Lieber Besucher, herzlich willkommen bei: Aqua Computer Forum. Falls dies Ihr erster Besuch auf dieser Seite ist, lesen Sie sich bitte die Hilfe durch. Dort wird Ihnen die Bedienung dieser Seite näher erläutert. Darüber hinaus sollten Sie sich registrieren, um alle Funktionen dieser Seite nutzen zu können. Benutzen Sie das Registrierungsformular, um sich zu registrieren oder informieren Sie sich ausführlich über den Registrierungsvorgang. Falls Sie sich bereits zu einem früheren Zeitpunkt registriert haben, können Sie sich hier anmelden.

Datenbank für Forum

Freitag, 3. März 2006, 11:50

Hi,
hoffe hier sind nen paar sql experten unter euch ;)
(so wie ich euch kenne ist das garantiert so)

also ich bin dabei ne Datenbank für nen Forum zu erstellen und wollt euch mal fragen ob man noch was, in sachen performance, verbessern könnte?!

hab einige sachen redundant gehalten (um joins zu vermeiden)
und nen paar indizes angelegt

hier ist das script:

create table user(
id int unsigned auto_increment primary key,
name char(40) not null,
pw char(32) not null,
nick char(40) not null,
email char(60),
email_visible enum('y','n'),
geschlecht enum('w','m',''),
banned enum('y','n'),
admin enum('y','n'), #da fehlte enum
birth_day tinyint unsigned,
birth_month tinyint unsigned,
birth_year smallint unsigned,
city char(100),
website_titel char(100),
website_url char(255),
icq int unsigned,
aim char(100),
yim char(100),
jabber char(100),
pertext char(40),
picture char(100),
zeitformat char(20),
timedif tinyint,
signatur char(255),
posts int unsigned
);

create table board(
id int unsigned auto_increment primary key,
name char(50) not null,
lastposter char(40),
threads int unsigned,
posts int unsigned,
subtitle char(200)
);

create table thread (
id int unsigned auto_increment primary key,
topic char(100),
created_by int unsigned,
created_at datetime,
board_id int unsigned,
closed enum('y','n'),
sticky enum('y','n'),
lastposter char(40),
posts int unsigned
);

create table post (
id bigint unsigned auto_increment primary key,
written_at datetime,
edited tinyint unsigned ,
edited_by int unsigned,
user_id int unsigned,
thread_id int unsigned,
message text
);

create table km (
id bigint unsigned auto_increment primary key,
time timestamp,
from_user int unsigned,
to_user int unsigned,
titel char(30),
message text
);

create table moderator(
id int unsigned auto_increment primary key,
user_id int unsigned ,
board_id int unsigned
);

alter table user add index(id); #für die suche eines users anhand seiner id
alter table thread add index(id); #für die suche des threads von den posts
alter table thread add index(created_at); #für die sortierung der threads nach zeit
alter table thread add index(board_id); #für das selektieren der threads nach zeit geordnet
alter table post add index(thread_id); #für das suchen der posts zu den passenden threads
alter table post add index(written_at); #um die posts der zeit nach sortieren zu können; at nicht ad
alter table km add index(to_user); #um die kurzmitteilungen für den user selectieren zu können

edith sagt: hab mich verschrieben :-X

Re: Datenbank für Forum

Freitag, 3. März 2006, 12:20

bin selbst auch noch am optimieren und hab gerade noch was interessantes gefunden

alter table post add fulltext index(message); <-- fügt einen volltext index hinzu um volltext suchen zu ermöglichen 8)

Re: Datenbank für Forum

Freitag, 3. März 2006, 12:37

Redundante Daten sind ganz schlecht und sind ein Problem, wenn es um die Einhaltung der ACID-Anforderungen (hier speziell Konsistenz) geht. Mittels Normalisierung lassen sich redundante Daten entfernen und das sollte man auch unbedingt tun.

JOINs muss man nicht vermeiden, die sind gar nicht so langsam, wie du vielleicht glaubst.

Wenn ich mich nicht ganz, ganz arg täusche, ist ein Primary Key
auch ein Index, du kannst bei deinen Index-Definitionen also einiges weglassen.

Übrigens: Meinst du nicht, du solltest *durchgehend* englische Namen für Tabellen und Spalten benutzen? :)

Re: Datenbank für Forum

Freitag, 3. März 2006, 12:55

ok namen sind geändert worden (alles englisch ;))

bei den redundanzen bin ich mir nicht ganz sicher, joins sind schon sehr rechenintensiv und ich wollte halt sehr performante db.

aber ich glaub ich werd die doch raushauen und mit joins arbeiten.

Re: Datenbank für Forum

Freitag, 3. März 2006, 12:56

ich bin jetzt nicht so der große db-admin, aber ein paar sachen sind mir aufgefallen, die sollten aber nicht viel bei der performance ausmachen.

- birth_day, _month, _year würde ich durch einen timestamp ersetzen.
ergibt bei der programmierung mehr möglichkeiten und die zeitzone ist auch unwichtig.

- icq, aim, yabber,... würde ich auslagern mit einer kreuztabelle.
dann kann man noch andere dienste hinzufügen ohne gleich alle user ändern zu müssen.

- was ist picture? ein link zu einer datei? auch da würde ich auslagern, dann kann man festlegen ob der user ein standard-bild, ein verlinktes bild auf eigenem webspace, ein individuelles bild auf dem forum-server oder ein blob in der datenbank hat.

- bei geschlecht fehlt t für transgender. ;)

- admin/banned usw würde ich durch eine user/rollen-struktur ersetzen, ich denke das man auch admins haben will die nicht alles dürfen

- hier im board finde ich ja sehr praktisch das ich sehe welche threads ich gelesen habe, und das funktioniert auch.
das würde ich auch noch einbauen.

was redundanzen angeht:
erst wenn du wirklich viele zugriffe gleichzeitig hast lohnt sich eine optimierung in diese richtung.
wobei nichts in der datenstruktur redundant sein sollte, sondern zb in ein paar views auf die die anwendung dann zugreift.

wenn es extrem wird partitioniert man eine tabelle, hier am ehesten die posts, dh. man hat mehrere post-tabellen, zb für die letzten tage und eine history, oder nach board getrennt.
sehe ich hier aber nicht die notwendigkeit für.
das ist aber keine redundanz, jedes post gibts nur einmal.

für die performance solltest du dir erstmal besser ein orm-framework (object-relational-mapping) für die anwendung suchen, das macht schon einiges aus und hilft auch durch die navigation der joins.
Gott hat die Welt ja nur in sieben Tagen erschaffen können, weil es keine installierte Basis gab.

Re: Datenbank für Forum

Freitag, 3. März 2006, 13:29

Zitat von »crushcoder«

- birth_day, _month, _year würde ich durch einen timestamp ersetzen.
ergibt bei der programmierung mehr möglichkeiten und die zeitzone ist auch unwichtig.



timestamp hab ich absichtlich nicht verwendet da dieser jedesmal mitgesetzt werden müsste wenn irgendeine änderung durchgeführt werden würde.

Zitat von »crushcoder«


- icq, aim, yabber,... würde ich auslagern mit einer kreuztabelle.
dann kann man noch andere dienste hinzufügen ohne gleich alle user ändern zu müssen.

ob ich eine neue spalte in die user tabelle einfüge oder in eine kreuztabelle macht überhaupt nichts aus, da muss ich ja bei jedem post in thread noch nen join machen, was sich wieder negativ auswirkt.

Zitat von »crushcoder«


- was ist picture? ein link zu einer datei? auch da würde ich auslagern, dann kann man festlegen ob der user ein standard-bild, ein verlinktes bild auf eigenem webspace, ein individuelles bild auf dem forum-server oder ein blob in der datenbank hat.

wo ist das problem?! ob ich weiß ob das bild von einem externen server kommt oder nicht ist doch egal, nen url ist nen url

Zitat von »crushcoder«


- bei geschlecht fehlt t für transgender. ;)

ack. wird eingebaut

Zitat von »crushcoder«


- admin/banned usw würde ich durch eine user/rollen-struktur ersetzen, ich denke das man auch admins haben will die nicht alles dürfen

es gibt doch nichts anderes außer admins und moderatoren. daher die spalte ob man admin ist, und die moderatoren tabelle

Zitat von »crushcoder«


- hier im board finde ich ja sehr praktisch das ich sehe welche threads ich gelesen habe, und das funktioniert auch.
das würde ich auch noch einbauen.

^^ stimmt hab ich vollkommen vergessen
danke :)

Zitat von »crushcoder«


was redundanzen angeht:
erst wenn du wirklich viele zugriffe gleichzeitig hast lohnt sich eine optimierung in diese richtung.
wobei nichts in der datenstruktur redundant sein sollte, sondern zb in ein paar views auf die die anwendung dann zugreift.

redundanzen sind schon gestrichen
werd gleich mal das script überarbeiten und ein neues posten

Zitat von »crushcoder«


wenn es extrem wird partitioniert man eine tabelle, hier am ehesten die posts, dh. man hat mehrere post-tabellen, zb für die letzten tage und eine history, oder nach board getrennt.
sehe ich hier aber nicht die notwendigkeit für.
das ist aber keine redundanz, jedes post gibts nur einmal.

das wäre auch ne idee, aber dann kann man gleich mit textdateien arbeiten, wofür nen dbms wenn der nicht die posts in einer tabelle schnell durchsuchen kann?!

Zitat von »crushcoder«


für die performance solltest du dir erstmal besser ein orm-framework (object-relational-mapping) für die anwendung suchen, das macht schon einiges aus und hilft auch durch die navigation der joins.

ein was?!

neues script folgt sobald ich damit fertig bin ;)

Re: Datenbank für Forum

Freitag, 3. März 2006, 13:32

doppelpost für das neue script ;)

create table user(
id int unsigned auto_increment primary key,
name char(40) not null,
pw char(32) not null,
nick char(40) not null,
email char(60),
email_visible enum('y','n'),
geschlecht enum('w','m','t'),
banned enum('y','n'),
admin enum('y','n'),
birth_day tinyint unsigned,
birth_month tinyint unsigned,
birth_year smallint unsigned,
city char(100),
website_titel char(100),
website_url char(255),
icq int unsigned,
aim char(100),
yim char(100),
jabber char(100),
mytext char(40),
picture char(100),
timeformat char(20),
timedif tinyint,
signatur char(255),
posts int unsigned
);

create table board(
id int unsigned auto_increment primary key,
name char(50) not null,
lastposter char(40),
subtitle char(200)
);

create table thread (
id int unsigned auto_increment primary key,
topic char(100),
created_by int unsigned,
created_at datetime,
board_id int unsigned,
closed enum('y','n'),
sticky enum('y','n'),
lastposter char(40)
);

create table post (
id bigint unsigned auto_increment primary key,
written_at datetime,
edited tinyint unsigned ,
edited_by int unsigned,
user_id int unsigned,
thread_id int unsigned,
message text
);

create table km (
id bigint unsigned auto_increment primary key,
time timestamp,
from_user int unsigned,
to_user int unsigned,
titel char(30),
message text
);

create table moderator(
id int unsigned auto_increment primary key,
user_id int unsigned ,
board_id int unsigned
);

create table readed(
user_id int unsigned,
thread_id int unsigned,
readed enum('y','n')
);#wird gefüllt sobald ein user den thread liesst


alter table thread add index(created_at); #für die sortierung der threads nach zeit
alter table thread add index(board_id); #für das selektieren der threads nach zeit geordnet
alter table post add index(thread_id); #für das suchen der posts zu den passenden threads
alter table post add index(written_at); #um die posts der zeit nach sortieren zu können
alter table km add index(to_user); #um die kurzmitteilungen für den user selectieren zu können
alter table post add fulltext index(message);#um posts mit einer volltextsuche nach beiträgen zu durchsuchen

Re: Datenbank für Forum

Freitag, 3. März 2006, 20:44

Meinen Erfahrungen nach bringt ein ORM nur Performance in der Entwicklung, aber zu Ungunsten der technischen Performance. Heutzutage gibt es allerdings sehr viele Fälle, in denen diese Aufteilung durchaus weit akzeptabler ist als höhere Performance mit weitaus längerer Entwicklungszeit.

Re: Datenbank für Forum

Samstag, 4. März 2006, 01:28

das kommt drauf an (wie immer).
natürlich dient so ein orm-tool in erster linie der beschleunigung der entwicklung.
wenn man selber optimieren will ist dies bestimmt auch effektiver, dann aber sehr aufwendig.

hibernate zb fasst updates zusammen, updated nur wenn wirklich etwas verändert wird usw. und cached natürlich.
siehe: http://www.hibernate.org/15.html
ich glaube sowas wird selten selber programmiert.

was ein orm-tool ist:
wenn man objektorientiert programmiert muss man die daten aus der datenbank irgendwie in die objekte bekommen.
ein orm-tool kann dies mehr oder weniger automatisch oder per konfiguration erledigen.

d.h. das man manchmal sogar ohne sql auskommt.
oder auch das man auf constraints in einer tabelle über ein attribut im objekt zugreifen kann.
Gott hat die Welt ja nur in sieben Tagen erschaffen können, weil es keine installierte Basis gab.

Re: Datenbank für Forum

Mittwoch, 8. März 2006, 17:45

sry wenn ich mich hier mal so einklinke, aber ich bin auch grad am überlegen was für ne sql struktur ich für meine db aufbaue, speziell für die password spalte der jeweiligen user.. reicht es da das password als plain text in der sql db abzulegen, oder sollte man da besondere sicherheitsvorkehrungen treffen ?

edit: und kann mir noch wer erklären was

id int unsigned auto_increment primary key

genau bedeutet ? added der da für jeden eintrag in die tabelle ne neue id (also 1,2,3,4,..) ?

edit2: ich würd bei der user tabelle noch MSN als möglichkeit einbauen..

messi

Re: Datenbank für Forum

Mittwoch, 8. März 2006, 18:37

auto_increment bedeutet das er automatisch die id hochzählt.

unsigned heißt ohne vorzeichen, es geht also kein -1 (macht ja sinn bei ids).

primary key heißt das diese spalte jeden datensatz eindeutig identifiziert, deswegen muss die id immer unterschiedlich sein.

das passwort sollte man nie als klartext in die datenbank schreiben, das ist immer unsicher.
normalerweise hashed man es (früher md5, inzwischen braucht man was sichereres), d.h. man verschlüsselt es so das es nicht mehr entschlüsselt werden kann.
in den meisten fällen reicht das, man will ja meist nur das passwort überprüfen. falls es jm vergisst wird ein neues generiert.
Gott hat die Welt ja nur in sieben Tagen erschaffen können, weil es keine installierte Basis gab.

Re: Datenbank für Forum

Mittwoch, 8. März 2006, 19:04

Zitat von »crushcoder«

auto_increment bedeutet das er automatisch die id hochzählt.

unsigned heißt ohne vorzeichen, es geht also kein -1 (macht ja sinn bei ids).

primary key heißt das diese spalte jeden datensatz eindeutig identifiziert, deswegen muss die id immer unterschiedlich sein.

okay thx.. natürlich war mir der primary key bereits ein begriff ;)

Zitat von »crushcoder«


das passwort sollte man nie als klartext in die datenbank schreiben, das ist immer unsicher.
normalerweise hashed man es (früher md5, inzwischen braucht man was sichereres), d.h. man verschlüsselt es so das es nicht mehr entschlüsselt werden kann.
in den meisten fällen reicht das, man will ja meist nur das passwort überprüfen. falls es jm vergisst wird ein neues generiert.

mhm.. davon weiß ich so ziemlich gar nix.. hast du da irgendwelche quellen zu ? speziell für python..

messi

Re: Datenbank für Forum

Mittwoch, 8. März 2006, 19:39

python ist doch yogis ding ;D

http://www.python.org/doc/current/lib/crypto.html

http://de.wikipedia.org/wiki/MD5
http://de.wikipedia.org/wiki/Sicherer_Hash-Algorithmus

auch interessant, weniger mathematisch:
http://de.wikipedia.org/wiki/Salted_Hash
Gott hat die Welt ja nur in sieben Tagen erschaffen können, weil es keine installierte Basis gab.

Re: Datenbank für Forum

Mittwoch, 8. März 2006, 20:12

msn?
ne ich mag msn nicht :P
wer msn in seinem forum haben will soll sich nen anderes suchen :D

Re: Datenbank für Forum

Mittwoch, 8. März 2006, 20:31

Passwörter kannst du in deinem RDBMS mit den String-Funktion SHA1() oder MD5() als Hashes ablegen. Das ist unabhängig von der Programmiersprache (in der man es aber auch realisieren kann, was Vor- und Nachteile hat, die sich irgendwo auch ausspielen können).

Re: Datenbank für Forum

Mittwoch, 8. März 2006, 20:48

Zitat von »Y0Gi«

Passwörter kannst du in deinem RDBMS mit den String-Funktion SHA1() oder MD5() als Hashes ablegen. Das ist unabhängig von der Programmiersprache (in der man es aber auch realisieren kann, was Vor- und Nachteile hat, die sich irgendwo auch ausspielen können).


wie jetz ? ich hab phpmyadmin als rdbms für ne mysqldb, und wie mach ich aus den passwörtern nun sha1 oder md5 hashes ?
die muss ich ja via python generieren.. und dann als hash in die db schreiben.
wenn sich dann wer einlogt muss man aus dem eingegeben pass wieder nen hash bilden und den vergleichen, so richtig ?

messi

Re: Datenbank für Forum

Mittwoch, 8. März 2006, 20:59

Quellcode

1
SELECT SHA('RTFM');


;)

Ach ja: http://de.wikipedia.org/wiki/RDBMS


Zitat von »messi@T.B.S.«

wenn sich dann wer einlogt muss man aus dem eingegeben pass wieder nen hash bilden und den vergleichen, so richtig ?

Rrrrrichtig!

Vor kurzem habe ich in für einen Kurs an der Uni die Medienbibliothek Media.lib entwickelt. Ich will das Ding demnächst veröffentlichen, dann kannst du dir die technische Seite davon ansehen, die u.a. auch eine Benutzerverwaltung mit Rechten umfasst.

Re: Datenbank für Forum

Donnerstag, 9. März 2006, 12:00

Zitat von »Y0Gi«

Passwörter kannst du in deinem RDBMS mit den String-Funktion SHA1() oder MD5() als Hashes ablegen. Das ist unabhängig von der Programmiersprache (in der man es aber auch realisieren kann, was Vor- und Nachteile hat, die sich irgendwo auch ausspielen können).

dafür ist es abhängig von der datenbank, das hat auch seine vor- und nachteile.
Gott hat die Welt ja nur in sieben Tagen erschaffen können, weil es keine installierte Basis gab.

Re: Datenbank für Forum

Donnerstag, 9. März 2006, 13:34

Richtig. Aber irgendwas ist ja immer ;)

Re: Datenbank für Forum

Donnerstag, 9. März 2006, 14:06

Zitat von »Y0Gi«

Richtig. Aber irgendwas ist ja immer ;)


leider :-X