Beste Lezer,
Ik heb een vraagje, ik wil graag uit de tabel 'friends' uitlezen wie de vrienden zijn van de huidige ingelogde gebruiker ($data) en vervolgens aan de hand van de gebruikers die daaruit komen rollen wil ik (net als op Facebook) een soort tijdlijn met activiteiten onder elkaar weergeven.
Ziet er alsvolgt uit:
Dus met andere woorden: aan de hand van de gebruikers die uit de query $friends komen rollen, wil ik de laatste $actions ophalen.PHP Code:
$friends = mysql_query("SELECT * FROM `friends` WHERE `user`='".$data['ID']."'");
// Hier moet iets gebeuren om de gegevens uit de tabel friends (de vrienden van de gebruiker dus) vervolgens te laten selecteren uit de tabel actions.
$actions = mysql_query("SELECT * FROM `actions` WHERE `user`='".$eenvriend."' AND `hide`='0' ORDER BY `id` DESC");
while($action = mysql_fetch_assoc($actions)){
// DE ACTIEINHOUD
}
Hoe gaat dit in z'n werk?
- SQL tabellen combineren
-
15-04-2013, 15:54 #1
- Berichten
- 39
- Lid sinds
- 13 Jaar
SQL tabellen combineren
-
In de schijnwerper
-
15-04-2013, 16:09 #2
- Berichten
- 400
- Lid sinds
- 14 Jaar
Re: SQL tabellen combineren
Probeer als eerst het * in je SQL query zo veel mogelijk te vermijden, aangezien je hiermee bijna altijd onnodige informatie ophaalt wat de laadtijd van je pagina vertraagd. Al helemaal wanneer je iets met een timeline wilt doen.
Daarnaast zou ik een aparte tabel in je database aanmaken voor de timeline posts, en niet alle acties bij elkaar in één tabel proppen, hierdoor wordt het erg onoverzichterlijk en bevordert de laadtijd ook niet. Ik zal gaan voor aparte tabellen voor iedere actie, zoals wanneer iemand een post plaatst deze in de tabel timeline_Posts zetten en wanneer iemand een nieuwe vriend toevoegd deze in weer een aparte tabel plaatsen bijvoorbeeld in timeline_Friends. Bij elke row zet je de userId door wie hij is geplaatst. Zo kan je simpelweg alles van 1 persoon heel makkelijk sorteren.
Wanneer je meerdere resultaten eruit zal willen krijgen zou je de userId's van de vrienden moeten gaan ophalen uit de database door iets als dit te doen:
PHP Code:
<?
$suffix = "Posts"; // Zo haal ik alleen de timeline posts op
while($friend = mysql_fetch_assoc($getFriends)){ //Hier ga ik er vanuit dat ze zelf weet hoe je de vrienden op moet halen
$where .= "`userId` = '$friend['id']'";
if($i < mysql_num_rows($getFriends)){
$where .= " OR ";
}
$i ++;
}
$getTimeline = mysql_query("SELECT 'userId', 'content' FROM `timeline_$suffix` WHERE $where");
?>
-
15-04-2013, 16:52 #3
- Berichten
- 620
- Lid sinds
- 15 Jaar
Re: SQL tabellen combineren
Kan je niet beter 1 query uitvoeren? Bijvoorbeeld zo: Je hebt Henk die is ingelogd en Bas en Peter zijn de overige gebruikers. Dan kan je kijken bij elke gebruiker (in dit voorbeeld zijn het er 3) of die een vriend zijn van Henk. Ik weet niet precies hoe jouw database eruit ziet, misschien is dat ook handig om te vermelden (de structuur).
In sommige gevallen kan je ook gebruik maken van "LEFT JOIN WHERE..." waar je 2 tabellen samenvoegt tot 1 tijdelijke tabel die alleen voor die voor 1 query gebruikt wordt.
-
15-04-2013, 17:21 #4
- Berichten
- 153
- Lid sinds
- 14 Jaar
Re: SQL tabellen combineren
Volgens mij kan je betere een IN constructie gebruiken?
Code:SELECT `actionName` FROM `actions` WHERE userId IN (SELECT `friendId` FROM `friends` WHERE `UserId` = $data)
PS: Denk ook aan escaping!
-
15-04-2013, 22:10 #5
- Berichten
- 750
- Lid sinds
- 15 Jaar
Re: SQL tabellen combineren
@ Henry
Klopt de query werkt. maar de query is zwaar inefficiënt zeker wanneer beide tabellen over de 100 000 records bevatten aangezien deze query een full table scan gaat uitvoeren ook al gebruik je een geïndexeerd veld.
-
15-04-2013, 22:25 #6
- Berichten
- 153
- Lid sinds
- 14 Jaar
Re: SQL tabellen combineren
@ Raymond.
Volgens mij gebruikt MySQL gewoon een index scan wanneer dat kan hoor. Zie hieronder.
Verder, je ontkomt niet aan een geneste query. Je moet eerst de vrienden bepalen en daarna hun posts. Het moet in twee stappen. Algemene regel voor dit soort dingen is dan dat je het altijd zo veel mogelijk in een query moet stoppen, MySQL kan immers veel beter optimaliseren (pushen van selectie, prunen op basis van table packing e.d.) dan je applicatie code. Daarnaast bespaar je ook het heen en weer streamen van data (beyoned marginaal) en het interpreteren en encoden van de resultaten en query in een geinterpreteerde taal (marginaal) [[Overigens, de uitzondering bevestigd ook hier natuurlijk de regel ;)]]
Voorbeeld query
Code:EXPLAIN SELECT id FROM base_users WHERE id IN (SELECT userId FROM XXXXX_forms_edits)
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY base_users index NULL username 66 NULL 3 Using where; Using index
2 DEPENDENT SUBQUERY XXXXX_forms_edits index_subquery fk_XXXXX_forms_edits_users fk_XXXXX_forms_edits_users 5 func 4 Using index; Using where
-
16-04-2013, 07:17 #7
- Berichten
- 750
- Lid sinds
- 15 Jaar
Re: SQL tabellen combineren
@ Henry
Dank je, je hebt me inderdaad op een foutje betrapt de query welke jij aangeeft gebruikt geen full table scan. Ben het compleet met je eens dat de query in 1 keer naar de database moet behalve je genesteld subquery is niet efficiënt.
In dit geval kun je beter twee losse querys naar de database sturen welke een index gebruiken. Het type const, eq_ref of range querys zullen je geneste subquery aanzienlijk outperformen. Nog Beter is om een fatsoenlijke join te gebruiken waar ze voor gemaakt zijn om relaties te kunnen vinden.
Een full table scan is te herkennen aan het type ALL in combinatie met de aantal rows.
De explain van je query geeft met het type index en extra using index aan dat mysql de complete index scan moet uitvoeren om een match te kunnen vinden. Dit is na de complete table scan met type All de meeste slechtste geoptimaliseerde query welke je kan schrijven. Op een kleine table zal je subquery nog wel snel zijn in verband met de kleine index file maar meer mate je dataset groter wordt ga je merken dat de query steeds trager zal gaan worden.
Kortom subquery zijn vaak fubar en dien je zo veel mogelijk te vermijden.
-
16-04-2013, 10:35 #8
- Berichten
- 153
- Lid sinds
- 14 Jaar
Re: SQL tabellen combineren
In mijn geval zijn er, bij correcte evaluatie, twee onafhankelijke queries. De eerste om de Id's te bepalen, de tweede om de bijbehorende look up voor elk id te doen. En daar zit hem nou juist de crux, MySQL detecteert niet dat die queries onafhankelijk zijn. Dus jij hebt gelijk, de IN query is suboptimaal
Maarrrrr. Het is een bekende bug dat IN queries onterecht een dependent suquery opleveren en dus voor elke row in het resultaat uitgevoerd worden terwijl dat niet nodig is. Dus ik heb ook gelijk, een IN query zou net zo snel moeten zijn.
Bron: http://stackoverflow.com/questions/3...417190#3417190
Verder vind ik een IN query beschrijvender en is SQL een declaratieve taal dus vind ik dat ik net iets meer gelijk heb. ;) Jammer alleen dat het pas opgaat in MySQL 6.0.
EDIT: Om deze onverwacht interessante discussie ook voor TS interessant te maken: Een join is voorlopig de beste oplossing :(
@ Henry
Dank je, je hebt me inderdaad op een foutje betrapt de query welke jij aangeeft gebruikt geen full table scan. Ben het compleet met je eens dat de query in 1 keer naar de database moet behalve je genesteld subquery is niet efficiënt.
In dit geval kun je beter twee losse querys naar de database sturen welke een index gebruiken. Het type const, eq_ref of range querys zullen je geneste subquery aanzienlijk outperformen. Nog Beter is om een fatsoenlijke join te gebruiken waar ze voor gemaakt zijn om relaties te kunnen vinden.
Een full table scan is te herkennen aan het type ALL in combinatie met de aantal rows.
De explain van je query geeft met het type index en extra using index aan dat mysql de complete index scan moet uitvoeren om een match te kunnen vinden. Dit is na de complete table scan met type All de meeste slechtste geoptimaliseerde query welke je kan schrijven. Op een kleine table zal je subquery nog wel snel zijn in verband met de kleine index file maar meer mate je dataset groter wordt ga je merken dat de query steeds trager zal gaan worden.
Kortom subquery zijn vaak fubar en dien je zo veel mogelijk te vermijden.
Plaats een
- + Advertentie
- + Onderwerp
Marktplaats
Webmasterforum
- Websites algemeen
- Sitechecks
- Marketing
- Domeinen algemeen
- Waardebepaling
- CMS
- Wordpress
- Joomla
- Magento
- Google algemeen
- SEO
- Analytics
- Adsense
- Adwords
- HTML / XHTML
- CSS
- Programmeren
- PHP
- Javascript
- JQuery
- MySQL
- Ondernemen algemeen
- Belastingen
- Juridisch
- Grafisch ontwerp
- Hosting Algemeen
- Hardware Info
- Offtopic