PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : MySQL-Zwischenergebnisse wiederverwenden?


Privatrolf
2008-05-15, 16:14:48
Ahoi.

Ich habe quasi Arrays in einer MySQL-Tabelle. Da MySQL Arrays nicht nativ unterstützt, habe ich mich für einen String aus IDs mit Trennzeichen entschieden. Hierbei fällt relativ viel dumpfe Stringverarbeitung an, und vieles davon auch noch mehrfach wiederholt pro Statement.

Ich bin in Sachen SQL noch ziemlich grün hinter den Ohren, aber ich kann mir nicht vorstellen dass das besonders effizient ist. Ich frage mich nun ob es möglich ist, Teilergebnisse in einem SELECT-Statement zwischenzuspeichern und noch im gleichen Statement wiederzuverwenden, quasi analog zu temporären Variablen in Programmiersprachen.

Ich habe zB in bestimmten Situationen Lindwurm-Queries folgender Form:UPDATE content_cats SET `show`=TRIM(':' FROM
CONCAT_WS(':',NULLIF(SUBSTRING_INDEX(
CONCAT(':',`show`,':'),NULLIF(CONCAT(
':',SUBSTRING_INDEX(SUBSTRING_INDEX(
CONCAT(':',`show`,':'),':17:',1),':',-1),':'),'::'),1),''),'17',
NULLIF(SUBSTRING_INDEX(SUBSTRING_INDEX(
CONCAT(':',`show`,':'),':17:',1),':',-1),''),SUBSTRING_INDEX(
CONCAT(':',`show`,':'),':17:',-1)))
WHERE `cat`='' AND LOCATE(':17:',CONCAT(`show`,':'))!=0

Hier noch der PHP-Code der mir dieses Ding erzeugt hat:<?php
$ref='17';
$mref="'".":$ref:"."'";
$pre_ref="SUBSTRING_INDEX(CONCAT(':',`show`,':'),".$mref.",1)";
$post_ref="SUBSTRING_INDEX(CONCAT(':',`show`,':'),".$mref.",-1)";
$displaced="SUBSTRING_INDEX(".$pre_ref.",':',-1)";
$pre_displaced="SUBSTRING_INDEX(CONCAT(':',`show`,':'),NULLIF(CONCAT(':',".$displaced.",':'),'::'),1)";
$qc="UPDATE nodyn_content_cats SET `show`=".
"TRIM(':' FROM CONCAT_WS(':',NULLIF(".$pre_displaced.",''),'".$ref."',".
"NULLIF(".$displaced.",''),".$post_ref."))".
" WHERE `cat`='".$cat."' AND ".
"LOCATE('".":$ref:"."',CONCAT(`show`,':'))!=0";

print_r($qc);
?>Das muss alles in einem Rutsch durch. Ich wil Atomizität sicherstellen, und da ich PHP nutze, habe ich auch keine Möglichkeit mehrere Statements zu verketten. In einer (Heap-)Tabelle explizit cachen möchte ich nicht. Das wäre wohl noch weniger elegant (und noch weniger effizient).

Wie man nun im PHP-Code erkennt gibt es da bestimmte Unterterme die mehrfach vorkommen. Diese würde ich gerne nur einmal erzeugen und in Variablen ablegen, um sie dann im weiteren Verlauf der Query "einfach" wieder abrufen zu können. Falls das irgendwie geht.

c.p.d.
2008-05-15, 20:23:34
Ohne jetzt auf dein Problem einzugehen, würde ich dir empfehlen dich einmal etwas mit dem Thema Normalisierung auseinander zu setzen.

Wie immer empfiehlt sich der Themeneinstieg über wikipedia
http://en.wikipedia.org/wiki/Database_normalization

Privatrolf
2008-05-16, 14:59:37
Ohne jetzt auf dein Problem einzugehen, würde ich dir empfehlen dich einmal etwas mit dem Thema Normalisierung auseinander zu setzen.

Wie immer empfiehlt sich der Themeneinstieg über wikipedia
http://en.wikipedia.org/wiki/Database_normalizationIch hab' das schon ordentlich gemacht. Datensätze vernünftig strukturieren ist kein Prob, habe genug Erfahrung mit klassischer imperativer Programmierung um mir da keine großen Gedanken mehr machen zu müssen. Die SQL-Syntax ist halt noch relatives Neuland, aber die Tabellen die ich angelegt habe gehen IMO schon in Ordnung.


===

Nachdem bis jetzt noch keiner "ja, hier" geschrieen hat: gehe ich Recht in der Annahme dass das bei MySQL via PHP gar nicht geht? Dh dass man tatsächlich Terme deren Ergebnis man mehrfach in einer Query benötigt auch immer wieder neu Ausformulieren muss?

Falls die Query oben zu kompliziert ist, hier ein überschaubareres Beispiel:
SELECT CONCAT(
CONCAT_WS(' ','genau','das','gleiche'),
' - '
,CONCAT_WS(' ','genau','das','gleiche')
)Es gibt also keine Möglichkeit die Tatsache auszunutzen dass der erste und der dritte Term innerhalb der Klammer identisch sind. Korrekt?

Hardwaretoaster
2008-05-16, 16:32:08
Auch ohne den Code angeschaut zu haben: imperative Programmierung und Normalisierung von relationalen DBs sind zwei völlig verschiedene paar Schuhe.

Privatrolf
2008-05-17, 11:27:05
Äh. Möchte vielleicht noch jemand was beitragen was auch Themenbezug hat? Vielleicht sogar jemand der die Fragestellung gelesen hat?