phpbar.de logo

Mailinglisten-Archive

Bug oder gewollt

Bug oder gewollt

Patrick Boettcher mysql-de_(at)_lists.bttr.org
Fri, 04 Oct 2002 07:39:49 +0200


--=====================_1280203==.ALT
Content-Type: text/plain; charset="iso-8859-1"; format=flowed
Content-Transfer-Encoding: quoted-printable

Hallo,

ich bin der Meinung ich habe entweder einen Bug entdeckt oder ein
inkonsequentes Verhalten von MySQL:

Ich habe folgende Tabellenstruktur:

id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
parent_id INT UNSIGNED,
name CHAR(30)

In dieser Struktur speichere ich eine gro=DFe Baumstruktur (bis zu 700 000
Datens=E4tze hatte ich schon, maximale Ebenentiefe war 15) ab, die sich=
 h=E4ufig
=E4ndert, weswegen "nested sets" nicht in Frage kommen.

Nun kommt es h=E4ufig vor, das ich =FCber eine Namenssuche irgendein Kind=
 finde
und den kompletten Weg nach oben brauche.

Bisher tat ich das clientseitig mit einer rekursiven Funktion, welche
jedesmal ein Select machte um die neue parent_id zu holen und dabei einen
Array mit Namen zusammenbastelte. Das ist nicht die feine englische Art,=20
aber hat
funktioniert.

Beim st=F6bern in der MySQL Doku traf ich auf user Variablen. Damit m=FCsste=
 es
eigentlich auch klappen, und man h=E4tte nur eine Abfrage und trotzdem den=
 Weg
nach oben.
Und zwar so:

SET _(at)_new_id:=3D<StartID>;
SELECT name, _(at)_new_id:=3Dparent_id FROM baum WHERE id=3D_(at)_new_id;

Da ja zuerst der WHERE-Block "compiled" wird, steht beim ersten mal in
_(at)_new_id auch der Startwert und nach dem erfolgreichen finden, wird erst der
neue Wert von der parent_id in _(at)_new_id gespeichert. Durch den neuen Wert in
_(at)_new_id w=FCrde jetzt auch der neue Parent gefunden werden, weil der
WHERE-Block erneut kompiliert wird. ABER: wegen des Baumes sind ja alle
Elternknoten in der Tabelle =FCber dem Startdatensatz und aus irgendeinem
(wahrscheinlich ein Optimierungs-)Grund f=E4ngt mysql nicht wieder von vorn=
 in
der Tabelle an zu suchen, obwohl sich die WHERE-Bedingung =E4ndert.
Das ist meiner Meinung nach das inkonsequente Verhalten:
Entweden mysql verbietet UserVariablen in der WHERE Klausel oder es beginnt,
bei der Benutzung von User Variablen (also bei sich =E4ndernden Where
Bedingungen) mit Suche erneut vorn am Table.

Woher ich weiss, dass es funktioniert, wenn man einen Table andersherum
erstellt also:

CREATE TABLE test SELECT * FROM baum ORDER BY id DESC;

(dann stehen alle h=F6heren Knoten unten) und die gleiche Abfrage macht,=20
klappt es. Den entstandenen Table immer wieder
umzudrehen ist zwar m=F6glich, aber durch die Dynamit=E4t nicht sinnvoll.

Wie kann mir geholfen werden?

Danke,
Patrick



--=====================_1280203==.ALT
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<html>
<font face=3D"Arial, Helvetica">Hallo,<br><br>
ich bin der Meinung ich habe entweder einen Bug entdeckt oder ein<br>
inkonsequentes Verhalten von MySQL:<br><br>
Ich habe folgende Tabellenstruktur:<br><br>
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,<br>
parent_id INT UNSIGNED,<br>
name CHAR(30)<br><br>
In dieser Struktur speichere ich eine gro=DFe Baumstruktur (bis zu 700
000<br>
Datens=E4tze hatte ich schon, maximale Ebenentiefe war 15) ab, die sich
h=E4ufig<br>
=E4ndert, weswegen &quot;nested sets&quot; nicht in Frage kommen.<br><br>
Nun kommt es h=E4ufig vor, das ich =FCber eine Namenssuche irgendein Kind
finde<br>
und den kompletten Weg nach oben brauche.<br><br>
Bisher tat ich das clientseitig mit einer rekursiven Funktion,
welche<br>
jedesmal ein Select machte um die neue parent_id zu holen und dabei
einen<br>
Array mit Namen zusammenbastelte. Das ist nicht die feine englische Art,
aber hat<br>
funktioniert.<br><br>
Beim st=F6bern in der MySQL Doku traf ich auf user Variablen. Damit m=FCsste
es<br>
eigentlich auch klappen, und man h=E4tte nur eine Abfrage und trotzdem den
Weg<br>
nach oben.<br>
Und zwar so:<br><br>
SET _(at)_new_id:=3D&lt;StartID&gt;;<br>
SELECT name, _(at)_new_id:=3Dparent_id FROM baum WHERE
</font><font face=3D"Arial, Helvetica"=
 color=3D"#0000FF"><u>id=3D_(at)_new_id</u></font><font face=3D"Arial,=
 Helvetica">;<br><br>
Da ja zuerst der WHERE-Block &quot;compiled&quot; wird, steht beim ersten
mal in<br>
_(at)_new_id auch der Startwert und nach dem erfolgreichen finden, wird erst
der<br>
neue Wert von der parent_id in _(at)_new_id gespeichert. Durch den neuen Wert
in<br>
_(at)_new_id w=FCrde jetzt auch der neue Parent gefunden werden, weil der<br>
WHERE-Block erneut kompiliert wird. ABER: wegen des Baumes sind ja
alle<br>
Elternknoten in der Tabelle =FCber dem Startdatensatz und aus
irgendeinem<br>
(wahrscheinlich ein Optimierungs-)Grund f=E4ngt mysql nicht wieder von vorn
in<br>
der Tabelle an zu suchen, obwohl sich die WHERE-Bedingung =E4ndert.<br>
Das ist meiner Meinung nach das inkonsequente Verhalten:<br>
Entweden mysql verbietet UserVariablen in der WHERE Klausel oder es
beginnt,<br>
bei der Benutzung von User Variablen (also bei sich =E4ndernden Where<br>
Bedingungen) mit Suche erneut vorn am Table.<br><br>
Woher ich weiss, dass es funktioniert, wenn man einen Table
andersherum<br>
erstellt also:<br><br>
CREATE TABLE test SELECT * FROM baum ORDER BY id DESC;<br><br>
(dann stehen alle h=F6heren Knoten unten) und die gleiche Abfrage macht,
klappt es. Den entstandenen Table immer wieder<br>
umzudrehen ist zwar m=F6glich, aber durch die Dynamit=E4t nicht
sinnvoll.<br><br>
Wie kann mir geholfen werden?<br><br>
Danke,<br>
Patrick<br><br>
</font><br>
</html>

--=====================_1280203==.ALT--

---
Infos zur Mailingliste, zur Teilnahme und zum An- und Abmelden unter
-->>  http://www.4t2.com/mysql 



php::bar PHP Wiki   -   Listenarchive