MySQL optimal benutzen
ruben
- datenbank
0 King^Lully0 Vinzenz Mai0 ruben
Hallo!
Ich habe eigentlich kein unlösbares Problem, es geht mehr um die Performance und – naja – das Gefühl.
Ich finde MySQL in Kombination mit PHP ist sehr leicht zu benutzen, wenn man nur das Basiswissen in MySQL hat (also INSERT, UPDATE, REPLACE, DELETE und "wie installiere ich PHPmyAdmin").
Das liegt daran, dass man auf Umwegen vieles, was in MySQL geht, in PHP tun kann (zum Beispiel die Anzahl der Datensätze, die eine where-Klausel erfüllen zählen COUNT(*) oder count()).
Das ist aber oft nervig und schlägt sich vermutlich auch in der Performance nieder.
Nun habe ich also folgende Frage:
Der relevante Teil meiner Datenbank sieht so aus:
Tabelle "Vokabeln":
id | nutzer | sprache | vokabelspezifische Felder
Tabelle "Sprachen":
nutzer | sprache | sprachenspezifische Felder
Die Sprachen sind allgemeiner als die Vokabeln.
Nun ist es folgendermaßen:
Die Sprachen sollen nur die Vokabeln widerspiegeln.
Damit meine ich, dass es eine Sprache nur gibt, wenn es auch Vokabeln dieser Sprache gibt. Wenn alle Vokabeln einer Sprache gelöscht werden, soll es auch die Sprache nicht mehr geben.
Ich kann diesen Umstand umständlich mit PHP verwirklichen, indem ich bei jeder Vokabellöschung/-veränderung überprüfe, ob es die letzte war oder die erste und wenn dem so ist, die Tabelle "Sprachen" verändere.
Das nervt aber sehr.
Ich denke, es geht auch mit MySQL, vermutlich sogar recht komfortabel, aber ich weiß nicht genau, ob ich schon bei der Tabellenstruktur ansetzen muss, oder bei den Anfragen.
Ich hab mir meine Kenntnisse Stück für Stück angeeignet und deswegen bergen Dokumentationen, die es von Anfang an aufrollen viele redundante Informationen für mich. Vielleicht hätte ich anders an MySQL rangehen sollen, aber es ist wohl zu spät.
Ich arbeite mit MySQL 5.0.
Vielen Dank für hilfreiche Hinweise,
Ruben
Nun ist es folgendermaßen:
Die Sprachen sollen nur die Vokabeln widerspiegeln.
Damit meine ich, dass es eine Sprache nur gibt, wenn es auch Vokabeln dieser Sprache gibt.
Ich kenne das angeforderte feature als cascading deletes.
Allerdings rate ich davon ab solchen Mechanismen einzusetzen, der Nutzen ist ausgesprochen gering.
Ob MySQL das kann?
Mal hier klicken: ;)
http://www.google.de/search?hl=de&q=myslq+cascading+deletes&meta=
Nun ist es folgendermaßen:
Die Sprachen sollen nur die Vokabeln widerspiegeln.
Damit meine ich, dass es eine Sprache nur gibt, wenn es auch Vokabeln dieser Sprache gibt.Ich kenne das angeforderte feature als cascading deletes.
Allerdings rate ich davon ab solchen Mechanismen einzusetzen, der Nutzen ist ausgesprochen gering.
Ob MySQL das kann?
Mal hier klicken: ;)
http://www.google.de/search?hl=de&q=myslq+cascading+deletes&meta=
Bzw. ggf. allgemein googlen nach referentieller Integrität.
Mit kaskadierendem Löschen würde ich übrigens auch vorsichtig. Wobei hier die Frage ist, in welcher Richtung wirkt es. Wenn ich eine Sprache löschen, löscht kaskadierend ggf. alle Vokabeln. Jedoch soll ja hier beim Löschen der letzten Vokabel die zugehörige Sprache gelöscht werden (und nur dann).
Nick
Ob MySQL das kann?
Mal hier klicken: ;)
http://www.google.de/search?hl=de&q=mysql+cascading+deletes&meta=
Anscheinend ja, aber nur mit InnoDB (merklich langsamer als standard MyISAM).
Bzw. ggf. allgemein googlen nach referentieller Integrität.
Mit kaskadierendem Löschen wäre ich übrigens auch vorsichtig. Wobei hier die Frage ist, in welcher Richtung es wirkt. Wenn ich eine Sprache lösche, löschen Kaskaden ggf. alle Vokabeln. Jedoch soll ja hier beim Löschen der letzten Vokabel die zugehörige Sprache gelöscht werden (und nur dann).
Das ist eben die Frage, was hier die optimale Vorgehensweise ist.
Macht es Sinn, diesen etwas komplizierteren Datenbankaufbau in Kauf zu nehmen?
Gibt es Statements (ich kenn mich z.B. mit IF NOT EXISTS nicht aus), die es ohne den komplizierten Aufbau etwas leichter machen?
Oder am besten alles mit PHP und ich bleib meinen SELECT, DELETE, UPDATE, REPLACE?
Schöne Grüße,
Ruben
Hallo Ruben,
Die Sprachen sollen nur die Vokabeln widerspiegeln.
Damit meine ich, dass es eine Sprache nur gibt, wenn es auch Vokabeln dieser Sprache gibt. Wenn alle Vokabeln einer Sprache gelöscht werden, soll es auch die Sprache nicht mehr geben.
das ist in meinen Augen suboptimal.
Ändere Deine Einstellung - und mach es bestenfalls umgekehrt.
Wenn eine Sprache gelöscht wird, dann soll es auch keine Vokabeln dieser Sprache
mehr geben. Die Stichworte dazu wurden bereits genannt: Referentielle Integrität
durchsetzbar mit
ON DELETE CASCADE
bei MySQL nur bei Verwendung der InnoDB-Engine.
Willst Du Deine derzeitige Strategie beibehalten, so kannst Du dies
datenbankseitig mit Triggern erledigen. Diese übernehmen die Prüfung, die Du
derzeit in der API machst und löschen gegebenenfalls die Sprache aus der zweiten
Tabelle.
Nein, dies ist meiner Meinung nach keine gute Idee und erst recht nicht "optimal".
Eine Sprache hat meiner Meinung nach nichts damit zu tun, ob Vokabeln, Wörter
dazu abgespeichert sind. Umgekehrt solltest Du erst Vokabeln einer Sprache
abspeichern, nachdem Du diese Sprache angelegt hast. Deine
Spaltenbezeichnungen lassen (möglicherweise zu Unrecht) auf eine suboptimale
Tabellenstruktur schließen. Ohne ein paar Beispieldatensätze, insbesondere
auch mit den vokabel- und sprachenspezifischen Feldern läßt sich das aber
nicht endgültig beurteilen.
Freundliche Grüße
Vinzenz
das ist in meinen Augen suboptimal.
Ändere Deine Einstellung - und mach es bestenfalls umgekehrt.
Ich fürchte, ich habe die Datenbanksituation wirklich nicht ausreichend dargestellt. Ich bin mir aber sicher. Soweit ich deine Ausführungen bisher verstehe, will ich wirklich keine Kaskaden sondern Trigger (gibt es die auch für MyISAM-Tabellen)?
Wenn eine Sprache gelöscht wird, dann soll es auch keine Vokabeln dieser Sprache
mehr geben. Die Stichworte dazu wurden bereits genannt: Referentielle Integrität
durchsetzbar mit
ON DELETE CASCADE
bei MySQL nur bei Verwendung der InnoDB-Engine.
Willst Du Deine derzeitige Strategie beibehalten, so kannst Du dies
datenbankseitig mit Triggern erledigen. Diese übernehmen die Prüfung, die Du
derzeit in der API machst und löschen gegebenenfalls die Sprache aus der zweiten
Tabelle.
Die möchte ich beibehalten, ich illustriere warum an folgendem Beispiel.
Nein, dies ist meiner Meinung nach keine gute Idee und erst recht nicht "optimal".
Eine Sprache hat meiner Meinung nach nichts damit zu tun, ob Vokabeln, Wörter
dazu abgespeichert sind. Umgekehrt solltest Du erst Vokabeln einer Sprache
abspeichern, nachdem Du diese Sprache angelegt hast. Deine
Spaltenbezeichnungen lassen (möglicherweise zu Unrecht) auf eine suboptimale
Tabellenstruktur schließen. Ohne ein paar Beispieldatensätze, insbesondere
auch mit den vokabel- und sprachenspezifischen Feldern läßt sich das aber
nicht endgültig beurteilen.
Ich hoffe, so wird es klarer (ich hielt diese Informationen für redundant):
CREATE TABLE vokabeln
(
id
int(5) unsigned NOT NULL auto_increment,
user
varchar(255) NOT NULL default '',
sprache
varchar(255) NOT NULL default '',
bekannt
text NOT NULL,
fremd
text NOT NULL,
hinweis
text NOT NULL,
phase
tinyint(2) unsigned NOT NULL default '0',
zeit
int(8) unsigned NOT NULL default '0',
PRIMARY KEY (id
)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=10449 ;
vokabeln
vokabeln
VALUES (1, 'ruben', 'SCHWEDISCH', 'trinken', 'dricka', '', 5, 20060218);vokabeln
VALUES (23, 'ruben', 'SCHWEDISCH', 'Die Sonne scheint.', 'Solen skiner.', '', 5, 20060218);vokabeln
VALUES (121, 'ruben', 'SPANISCH', 'gelb', 'amarillo', '', 5, 19700101);vokabeln
VALUES (710, 'ruben', 'ENGLISCH', 'sich erfreuen/ergötzen', 'to regale', '', 5, 20061220);sprachen
(nutzer
varchar(255) NOT NULL default '',sprache
varchar(255) NOT NULL default '',zeichen
varchar(255) NOT NULL default '',abfrage
tinyint(1) NOT NULL default '0'sprachen
sprachen
VALUES ('ruben', 'englisch', 'x y z', 1);sprachen
VALUES ('ruben', 'franzoesisch', 'ï œ æ ë', 1);