Zur Navigation

Sprachweiche [4]

mit weiteren seltsamen RegEx-Problemen

31 Ranma (Gast)

Mit der IF-Bedingung vor dem SELECT hätte ich das verstanden. Aber das geht wahrscheinlich nicht? So sehe ich nur, daß die Query schon doppelt so lang ist. Das dürfte kaum besser sein als zwei Kontexte?

Natürlich zeigt so ziemlich jedes Tutorial, daß man jede Query nochmal in einen IF-Zweig packen kann, für den Fall, daß ein Fehler auftritt und FALSE zurückgeliefert wird. Das habe ich bisher nicht gemacht. Wenn die Verbindung hergestellt werden kann, welche Fehler könnten dann noch auftreten? Ich halte schon die Verzweigung für die Verbindungsaufnahme mit der Datenbank für übertrieben, weil ich ja von der Existenz meiner Datenbank weiß und auch von der Existenz der Tabellen darin.

Würde man eine Installationsroutine schreiben, dann müßte man natürlich alles auf Existenz überprüfen. Aber so hätte ich doch nur mehr Aufwand? Und ohne den Mehraufwand halte ich eine zusätzliche Query für nicht so schlimm. Wollte man wirklich die Anzahl der Queries gering halten, dann würde doch niemand Funktionen wie eine Bewertung in ein Skript einbauen?
Ranma

09.10.2015 06:11

32 Jörg

So sehe ich nur, daß die Query schon doppelt so lang ist. Das dürfte kaum besser sein als zwei Kontexte?

Die Komplexität der SELECT-Statements wirkt sich ja nicht auf das Durchsuchen der Tabelle aus, sondern kommt erst bei den gefundenen Datensätzen zum Einsatz.

Wollte man wirklich die Anzahl der Queries gering halten, dann würde doch niemand Funktionen wie eine Bewertung in ein Skript einbauen?

Da verstehe ich den Zusammenhang nicht - was für Funktionen meinst du?

09.10.2015 11:22 | geändert: 09.10.2015 11:24

33 Ranma (Gast)

Ganz einfach: ich kapiere das nicht, daß das Finden einen größeren Aufwand bedeuten soll als das Suchen. Wenn ich ohne Computer etwas suche, dann macht das den ganzen Aufwand aus. Sobald ich fündig wurde, bin ich auch schon fertig und kann erleichtert aufatmen. Ich kann mir irgendwie nicht vorstellen, daß das im Fall eines Computerprogrammes anders sein soll. Eine kompliziertere Suche müßte mehr Aufwand bedeuten und mehr als eine Tabelle in der Datenbank zu durchsuchen müßte wiederum mehr Aufwand bedeuten.
Ranma

09.10.2015 13:11

34 Jörg

Aufwändig für die Datenbank ist das Durchsuchen der Tabelle / der Indizes - das abschließende Selektieren der Felder fällt da kaum ins Gewicht. Das gilt umso mehr, je mehr die betreffende Tabelle mit Datensätzen gefüllt ist.

Eine kompliziertere Suche müßte mehr Aufwand bedeuten

Die Suche ist ja nicht komplizierter.

In deiner Analogie wirst du nicht zweimal zum Suchen nach jeweils einem Gegenstand losgeschickt, sondern nur einmal zum Suchen nach zwei Gegenständen. Die Selektion ist dann nichts anderes als das Greifen der gefundenen Gegenstände.

09.10.2015 15:49 | geändert: 09.10.2015 15:54

35 Ranma (Gast)

Ich muß die vorgeschlagene Query noch ausprobieren. Zunächst mal habe ich versucht, sie anhand von Tutorials nachzuvollziehen. Die Query scheint eine nicht-triviale Angelegenheit zu sein. Schon die Verwendung von IF in SQL ist seltsam und nicht so ganz leicht zu verstehen. Noch habe ich folgende Verständnisprobleme:

1. Arbeitet MySQL die Query vom Ende her ab? Die Teile FROM und WHERE wären überflüssig, würde IF schon ausreichen, um die gesuchten Begriffe zu finden. Wahrscheinlich muß ich mir das so vorstellen, daß IF erst am Schluß an die Reihe kommt. Aber das gesuchte Wort steht nicht fest. Es muß statt 'Suchterm' ? stehen und das wären mehrere ? in der Query. Würde nicht jedes davon für eine eigene, erwartete Variable stehen?

2. Für die Lokalisierung ist es nicht notwendig, aber für die Verwendung als Wörterbuch habe ich noch einige zusätzliche Spalten vorgesehen. Zum Beispiel enthalten die FreeDict-Dateien für Englisch zusätzlich die Aussprache in Phonetik-Schrift. Wenn die schonmal da ist, dann will ich sie einbauen. Aber meistens ist so etwas nicht da, deshalb sind diese Spalten in meiner Datenbanktabelle optional. Für die müßte ich wohl auch IF-Teile in die Query einbauen. Aber manchmal werden die davon erwarteten Felder garnicht existieren. Wie wird die Query darauf reagieren?

3. Brauche ich wirklich Spalte für Spalte eine weitere IF-Anweisung oder kann ich innerhalb der IF-Anweisung auch mit Klammern zusammenfassen? Du hast die Bedingung der IF-Anweisung sicherlich nicht grundlos wiederholt?

4. Manchmal kann ein Eintrag doch eindeutig sein. Dann würden sämtliche ELSE-Teile ins Leere laufen. Darf das passieren?

So langsam verstehe ich die Struktur der Query, kann aber nicht abschätzen wie sie sich in welchem Fall verhalten wird. Das dürfte aber Voraussetzung für jede Anweisung sein, die man in ein Skript einbauen will.
Ranma

12.10.2015 05:55

36 Ranma (Gast)

Falls hier jemand liest, weil er sich für Wörterbücher interessiert:

http://dict.uni-leipzig.de/dictd

Die eigentlichen Wörterlisten befinden sich in dreifach gepackten Dateien auf sourceforge.net, aber die Suchfunktion dort findet die eher nicht. Von FreeDict aus führen passende Links direkt zu den richtigen Seiten der Sourceforge.
Ranma

12.10.2015 06:00

37 Ranma (Gast)

Vielleicht sollte ich meine Datenbank-Tabelle umstrukturieren? Wenn ich zusätzliche Spalten aufnehme, dann brauche ich die jeweils für die Quellsprache und für die Zielsprache. Also alles doppelt vorhanden und das nur, damit jeder Nutzer Übersetzungen für seine eigene Sprache eingeben kann. Natürlich müßte die Eingabe so bleiben, weil sie sonst für Interessierte zu schwierig werden könnte. Aber muß ich in der Datenbank alles doppelt haben? Aber wie könnte sonst festgestellt werden, welche Paare zusammengehören?
Ranma

12.10.2015 11:52

38 Jörg

OK, ich erklär nochmal anhand meiner Query, die ich noch um ein LIMIT Statement ergänzt habe, wie die Datenbank sucht

SELECT IF(Quelle = 'Suchterm', Zielsprache, Quellsprache) AS Sprache,
       IF(Quelle = 'Suchterm', Ziel, Quelle) AS Wort
FROM Woerterbuch
WHERE Quelle = 'Suchterm'
OR Ziel = 'Suchterm'
ORDER BY Sprache
LIMIT 10

1. mit den FROM und WHERE Statements wird festgelegt, in welcher Datenbank nach welchen Kriterien gesucht wird

FROM Woerterbuch
WHERE Quelle = 'Suchterm'
OR Ziel = 'Suchterm'

Damit ist die eigentliche Suche auch schon abgeschlossen!

2. mit dem ORDER BY Statement wird festgelegt, nach welchem Kriterium die gefunden Datensätze sortiert werden

ORDER BY Sprache

3. mit dem LIMIT Statement wird festgelegt, wieviele der sortierten Datensätze zurückgegeben werden.

LIMIT 10

4. das SELECT Statement schließlich bestimmt, welche Datenfelder der sortierten und limitierten Datensätze zurückgegeben werden

SELECT IF(Quelle = 'Suchterm', Zielsprache, Quellsprache) AS Sprache,
       IF(Quelle = 'Suchterm', Ziel, Quelle) AS Wort

Hier werden die Datenfelder in Abhängigkeit davon zurückgegeben, ob nun Quelle = 'Suchterm' oder Ziel = 'Suchterm'; im esteren Fall werden die Datenfelder Zielsprache und Ziel, im zweiten Fall die Datenfelder Quellsprache und Quelle

Die eigentliche Suche beinhaltet also nur Punkt 1. - die Punkte 2. bis 4. beinhalten gewissermaßen nur die Nachbereitung der gefundenen Datensätze.

2. Für die Lokalisierung ist es nicht notwendig, aber für die Verwendung als Wörterbuch habe ich noch einige zusätzliche Spalten vorgesehen. Zum Beispiel enthalten die FreeDict-Dateien für Englisch zusätzlich die Aussprache in Phonetik-Schrift. Wenn die schonmal da ist, dann will ich sie einbauen. Aber meistens ist so etwas nicht da, deshalb sind diese Spalten in meiner Datenbanktabelle optional. Für die müßte ich wohl auch IF-Teile in die Query einbauen. Aber manchmal werden die davon erwarteten Felder garnicht existieren. Wie wird die Query darauf reagieren?

Ich würde die Wörter (und ihr Sprachkürzel zur eindeutigen Identifizierung) mit ihren Eigenschaften wie z.B. die Aussprache oder Wortart in einer eigenen Tabelle `Woerter` unterbringen und diese dann joinen

3. Brauche ich wirklich Spalte für Spalte eine weitere IF-Anweisung oder kann ich innerhalb der IF-Anweisung auch mit Klammern zusammenfassen? Du hast die Bedingung der IF-Anweisung sicherlich nicht grundlos wiederholt?

Nur Spalten, die abhängig von einer Bedingung zurückgegeben werden, benötigen ein solches IF-Konstrukt

Vielleicht sollte ich meine Datenbank-Tabelle umstrukturieren? Wenn ich zusätzliche Spalten aufnehme, dann brauche ich die jeweils für die Quellsprache und für die Zielsprache. Also alles doppelt vorhanden und das nur, damit jeder Nutzer Übersetzungen für seine eigene Sprache eingeben kann. Natürlich müßte die Eingabe so bleiben, weil sie sonst für Interessierte zu schwierig werden könnte. Aber muß ich in der Datenbank alles doppelt haben? Aber wie könnte sonst festgestellt werden, welche Paare zusammengehören?

Die eindeutigen Begriffe würde ich wie oben beschrieben in einer eigenen Tabelle `Woerter` unterbringen. In `Woerterbuch` stehen dann die Entsprechungen der Wörter. In `Woerter` sollte es keine Doppelungen geben, während ein Wort in `Woerterbuch` durchaus mehrere Entsprechungen haben kann. Und dass es Entsprechungen gibt A -> B und B -> A ist keine Doppelung, denn es ist wegen der von dir auch festgestellten Uneindeutigkeiten eben nicht zwangsläufig so, dass immer genauso hin- wie rückübersetzt wird

12.10.2015 17:57 | geändert: 12.10.2015 18:02

39 Ranma (Gast)

Die Query noch ohne den Teil mit LIMIT (oder gar JOIN) erbringt:


Warning: mysqli_stmt_bind_param(): Number of variables doesn't match number of parameters in prepared statement

Statt 'Suchterm' habe ich ? in die Query geschrieben und anscheinend werden alle ? gezählt. mysqli_stmt_bind_param() enthält aber nur den Hinweis auf einen einzelnen String, der natürlich dafür vorgesehen ist, 'Suchterm' darin aufzunehmen.

Ich nehme an, das mit der extra Tabelle ist die berüchtigte Normalisierung? Dann sollte ich das wohl machen. Aber die Query wird dadurch nicht einfacher?
Ranma

13.10.2015 09:49

40 Jörg

Statt 'Suchterm' habe ich ? in die Query geschrieben und anscheinend werden alle ? gezählt. mysqli_stmt_bind_param() enthält aber nur den Hinweis auf einen einzelnen String, der natürlich dafür vorgesehen ist, 'Suchterm' darin aufzunehmen.

Den vier '?' muss jeweils eine Variable als Argument in mysqli_stmt_bind_param() zugeordnet werden - in dem vorliegenden Fall ist es immer ein und dieselbe (die den Begriff 'Suchterm' beinhaltet). Also so in der Art:

$stmt = mysqli_prepare($link, 
"SELECT IF(Quelle = ?, Zielsprache, Quellsprache) AS Sprache,
        IF(Quelle = ?, Ziel, Quelle) AS Wort
FROM Woerterbuch
WHERE Quelle = ?
OR Ziel = ?
ORDER BY Sprache");
mysqli_stmt_bind_param($stmt, 'ssss', $suchterm, $suchterm, $suchterm, $suchterm);

Ich nehme an, das mit der extra Tabelle ist die berüchtigte Normalisierung?

Ja

Aber die Query wird dadurch nicht einfacher?

Das nicht, sie erspart einem aber einige Nachteile einer nicht normalisierten Datenbank.

13.10.2015 16:05 | geändert: 13.10.2015 16:11