Flashhilfe.de - Flash Community

[mySQL] abfrage über zwei tabellen

 


AntwortenRegistrieren Seite1  

springer#1
Benutzerbild von springer
Beiträge: 4909
Wohnort: zuhaus
Registriert: Apr 2004

12.07.2008, 21:58

folgende ausgangslage:

der wert 85 stellt eine seite dar. nun hab ich zwei tabellen. die eine (element) mit sämtlichen einträgen zu der seite (feld "pageid"). zusätzlich musste ich aufgrund eines hässlichen dummen denkfehlers eine zusätzliche tabelle erstellen (element_page_relation**). der sinn dieser tabelle ist, dass ich ein element unter umständen auf mehreren seiten haben möchte. nur kann ich ins feld pageid nicht zwei IDs eintragen. jetzt versuche ich aus der tabelle elements alle zeilen auszulesen die zum einen die entsprechende pageid eingetragen haben, und zum anderen einen eintrag in der tabelle element_page_relation mit entsprechenden feldern (elementid,pageid). ich habs mal soweit hinbekommen, dass ich alle auslesen kann, wenn in der tabelle element_page_relation nur ein eintrag mit derselben pageid vorhanden ist. es muss aber einen weg geben, auch wenn mehrere einträge vorhanden sind...

das ist mal die variante wenn nur ein datensatz in der 2.tabelle vorhanden ist.

PHP:
1
2
3
4
5
6
<?
// funktioniert nur bei einem eintrag in der element_page_relation 
SELECT FROM element,element_page_relation 
WHERE element
.pageid=85 OR element.lid=(SELECT elementid FROM element_page_relation WHERE pageid2=85)
?>


wird wahrscheinlich mit INNER JOIN/OUTER JOIN irgendwie gehen, bin da aber noch nicht ganz fit in der materie, und kriegs nicht hin. (vielleicht sitz ich auch einfach schon zu lange dran 8-|)

hat da vielleicht jemand eine idee oder einen ansatz?

mysql_dump

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?
CREATE TABLE 
`element` (
  `
lidint(11NOT NULL auto_increment,
  `
pageidint(11NOT NULL,
  `
nametext NOT NULL,
 
PRIMARY KEY  (`lid`)
ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=;



INSERT INTO `elementVALUES (185'Regul&auml;res Element');
INSERT INTO `elementVALUES (234'Wird auf anderer Seite verwendet');
INSERT INTO `elementVALUES (385'Reul&auml;res Element 2');
INSERT INTO `elementVALUES (482'Wird von anderer Seite verwendet 2');



CREATE TABLE `element_page_relation` (
  `
idint(11NOT NULL auto_increment,
  `
elementidint(11NOT NULL,
  `
pageid2int(11NOT NULL,
 
PRIMARY KEY  (`id`)
ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=;


INSERT INTO `element_page_relationVALUES (1485);
?>


** ich versuche hier "nur" eine schnelle übergangslösung zu finden, da ich das projekt nächste woche abgeben muss und nicht die zeit habe, den fehler zu beheben. ich weiss schon wie ich das mache, aber das benötigt etwas mehr zeit, weil da noch einiges hinten dran hängt...
lieber chips essen und danach voller zweifel sein, als voller zweifel chips essen...
Geändert von springer am 12.07.08 um 22:41 Uhr
Werbung
Beiträge: 0
Registriert: Feb 2016


springer#2
Benutzerbild von springer
Beiträge: 4909
Wohnort: zuhaus
Registriert: Apr 2004

Themenautor/in

13.07.2008, 10:47

ich sollte mehr schlafen... habs selbst hinbekommen....

PHP:
1
2
3
4
<?
SELECT DISTINCT 
FROM elements WHERE elements.pageid=85 OR elements.lid IN (SELECT elementid FROM element_page_relation WHERE pageid2=85) )
?>
lieber chips essen und danach voller zweifel sein, als voller zweifel chips essen...
Geändert von springer am 13.07.08 um 10:48 Uhr
Sebastian#3
Benutzerbild von SebastianFlashhilfe.de Moderator
Beiträge: 6981
Wohnort: München
Registriert: Jan 2002

17.07.2008, 15:44

Diese Verbindung mit den zwei Queries finde ich generell eher unschön und unperformant und versuche sie daher zu vermeiden. Jetzt habe ich auch gerade verstanden was Du erreichen willst.

Ich würde Dir folgendes raten:
Schmeiss pageid aus elements raus und erzeuge die andere Tabelle noch einmal neu:
PHP:
1
2
3
4
5
6
7
<?
CREATE TABLE 
`element_page_relation` (
  `
elementidint(11NOT NULL,
  `
pageidint(11NOT NULL
ENGINE=MyISAM  DEFAULT CHARSET=latin1;
?>

<- setz beide id Felder noch auf unsigned, da Du sicherlich keine Minuswerte haben wirst. Das gleiche gilt für die anderen int Felder in der anderen Tabelle.
Füg bei dieser Tabelle dann noch einen Index für pageid und elementid hinzu. Bei der anderen Tabelle reicht einer auf elementid. - die Primary Spalte würde ich ebenfalls löschen wenn Du sie nicht unbedingt brauchst.

Query wäre dann:
PHP:
1
2
3
4
<?
SELECT 
FROM element_page_relation epr LEFT JOIN element e ON(epr.elementid e.elementidWHERE epr.pageid 85
?>

Statt ON(epr.pageid = e.pageid) kannst Du auch USING(pageid) nehmen, wenn in beiden Tabellen die Spalte gleich heißt. Im Select sollte auf jeden Fall nicht * stehen, sondern nur die Spalten die Du auch wirklich benötigst. Selbst wenn es alle sein sollten, was bei dem JOIN ja nicht der Fall sein wird, solltest Du alle hinschreiben.
JavaScript & JavaFX Freelancer || Flashhilfe @ Twitter || XING Profil
Geändert von Sebastian am 17.07.08 um 15:45 Uhr
springer#4
Benutzerbild von springer
Beiträge: 4909
Wohnort: zuhaus
Registriert: Apr 2004

Themenautor/in

17.07.2008, 23:44

hab das nun mal so umgebaut wie du vorgeschlagen hast. funktioniert soweit...
auch hat sich mein dummer fehler damit eigentlich auch gleich behoben ;-)

die alte variante war allerdings sogar ein kleines bisschen performanter, da es sich um nicht allzuviele datensätze gehandelt hat....

0.00085020065307617
0.00074505805969238

aber danke für die hilfe und den nachtrag habs jetzt so angepasst...
lieber chips essen und danach voller zweifel sein, als voller zweifel chips essen...
Werbung
Beiträge: 0
Registriert: Feb 2016


Sebastian#5
Benutzerbild von SebastianFlashhilfe.de Moderator
Beiträge: 6981
Wohnort: München
Registriert: Jan 2002

18.07.2008, 00:10

Die Zeiten kann man nicht als Vergleichswert nehmen, da sie von Aufruf zu Aufruf variieren. Wenn Du wirklich wissen willst wie "gut" Dein Query ist, mußt Du ihn mit EXPLAIN testen.

Also z.B.:
PHP:
1
2
3
4
<?
EXPLAIN SELECT 
FROM element_page_relation epr LEFT JOIN element e USING(elementidWHERE epr.pageid 85
?>

-> USING ist schneller

Und dann hier nachlesen ob alles richtig ist:
http://dev.mysql.com/doc/refman/5.1/de/explain.html

Wenn Du dann noch die richtigen Indizies angelegt hast, sollte der SQL schneller sein.
JavaScript & JavaFX Freelancer || Flashhilfe @ Twitter || XING Profil
springer#6
Benutzerbild von springer
Beiträge: 4909
Wohnort: zuhaus
Registriert: Apr 2004

Themenautor/in

18.07.2008, 11:26

hab das mit EXPLAIN noch ausprobiert, muss mich da aber noch genauer einlesen...

kann man grundsätzlich sagen, dass die spalten rows, select_type und type das entscheidende für einen guten select sind?
lieber chips essen und danach voller zweifel sein, als voller zweifel chips essen...

Angehängte Dateien:
Bild explain.jpg54.49 KB
Sebastian#7
Benutzerbild von SebastianFlashhilfe.de Moderator
Beiträge: 6981
Wohnort: München
Registriert: Jan 2002

18.07.2008, 11:34

Ja. Ganz wichtig ist auch noch key. Dort sieht man nämlich das Du für den einen Query keine angelegt hast oder es sind keine Möglich. Jedenfalls macht das die Abfrage langsamer.

Aber man sieht auch ganz schön das er bei Deinem Query scheinbar alle Daten durchgeht. Da kannst Du Dir ja vorstellen das die Abfrage bei mehreren Einträgen dann viel viel langsamer wird.

Versuch mal in epr einen Index über zwei Spalten auf lid und pageid hinzuzufügen. ... ist nämlich komisch das er bei meinem Query in epr über 204 Zeilen geht. - oder willst Du auch 204 Ergebnisse? Wieviel Zeilen sind in der Tabelle?
JavaScript & JavaFX Freelancer || Flashhilfe @ Twitter || XING Profil
springer#8
Benutzerbild von springer
Beiträge: 4909
Wohnort: zuhaus
Registriert: Apr 2004

Themenautor/in

18.07.2008, 11:50

in epr sind genau 204 zeilen drin...
die ausgabe beschränkt sich allerdings auf deren 4 (für pageid 85)

den index hab ich eigentlich schon über beide spalten angelegt..
lieber chips essen und danach voller zweifel sein, als voller zweifel chips essen...

Angehängte Dateien:
Bild indizes.jpg7.88 KB
Sebastian#9
Benutzerbild von SebastianFlashhilfe.de Moderator
Beiträge: 6981
Wohnort: München
Registriert: Jan 2002

18.07.2008, 11:57

Ach so ok. Dann füg bitte noch mal ein pageid hinzu. - einzeln
Denke den anderen kannst Du dann löschen und nur einen für lid anlegen. Aber teste es ruhig vorher mal.
JavaScript & JavaFX Freelancer || Flashhilfe @ Twitter || XING Profil
springer#10
Benutzerbild von springer
Beiträge: 4909
Wohnort: zuhaus
Registriert: Apr 2004

Themenautor/in

18.07.2008, 12:25

mit index nur für pageid scheint es jetzt so zu sein wie du das überlegt hast....

ich hak hier mal ab, und nimm die letzte schnellste variante....
lieber chips essen und danach voller zweifel sein, als voller zweifel chips essen...

Angehängte Dateien:
Bild newindex.jpg11.30 KB

AntwortenRegistrieren Seite1  

Schnellantwort

Du musst registriert sein, um diese Funktion nutzen zu können.

 
Ähnliche Beiträge zum Thema
Partner Webseiten: art-and-law.de  Mediengestalter.info   php-resource.de   phpforum.de   phpwelt.de   Pixelio.de   Scubacube.de  
Haftungsausschluss   Datenschutzerklärung   Hier Werben   Impressum
© 1999-2019 Sebastian Wichmann - Flashhilfe.de