INSERT INTO `mgenre` VALUES (1,'Aktion','Action',1); INSERT INTO `mgenre` VALUES (2,'Erotik','Adult',2); INSERT INTO `mgenre` VALUES (3,'Eventyr','Adventure',4); INSERT INTO `mgenre` VALUES (4,'Animation','Animation',8); INSERT INTO `mgenre` VALUES (6,'Komedie','Comedy',16); INSERT INTO `mgenre` VALUES (7,'Krimi','Crime',32); INSERT INTO `mgenre` VALUES (8,'Dokumentar','Documentary',64); INSERT INTO `mgenre` VALUES (9,'Drama','Drama',128); INSERT INTO `mgenre` VALUES (10,'Familie','Family',256); INSERT INTO `mgenre` VALUES (11,'Fantasi','Fantasy',512); INSERT INTO `mgenre` VALUES (13,'Quiz','Game-Show',1024); INSERT INTO `mgenre` VALUES (15,'Gyser','Horror',2048); INSERT INTO `mgenre` VALUES (16,'Musik','Music',4096); INSERT INTO `mgenre` VALUES (17,'Musikalsk','Musical',8192); INSERT INTO `mgenre` VALUES (18,'Mystik','Mystery',16384); INSERT INTO `mgenre` VALUES (19,'Nyheder','News',32768); INSERT INTO `mgenre` VALUES (20,'Realitet-TV','Reality-TV',65536); INSERT INTO `mgenre` VALUES (21,'Romantik','Romance',131072); INSERT INTO `mgenre` VALUES (22,'Sci-Fi','Sci-Fi',262144); INSERT INTO `mgenre` VALUES (23,'Kort','Short',524288); INSERT INTO `mgenre` VALUES (24,'Sport','Sport',1048576); INSERT INTO `mgenre` VALUES (25,'Underholdning','Talk-Show',2097152); INSERT INTO `mgenre` VALUES (26,'Spænding','Thriller',4194304); INSERT INTO `mgenre` VALUES (27,'Krig','War',8388608); INSERT INTO `mgenre` VALUES (28,'Western','Western',16777216);
INSERT INTO `movie` VALUES (1,'Men in Black II',262161); INSERT INTO `movie` VALUES (2,'Tomb Raider, Lara Croft',517); INSERT INTO `movie` VALUES (3,'Terminator, The',4456449); # SQL
// Viser alle $strSQL = "SELECT m.id, m.title, GROUP_CONCAT(g.da ORDER BY g.da ASC SEPARATOR ' / ') AS ggenre, m.genre FROM movie m INNER JOIN mgenre g ON (m.genre & g.genre) GROUP BY m.id ORDER BY m.id DESC;";
// Søgning på Action(1) og Sci-Fi(262144) $strSQL = "SELECT m.id, m.title, GROUP_CONCAT(g.da ORDER BY g.da ASC SEPARATOR ' / ') AS AGenre, m.genre FROM movie m INNER JOIN mgenre g ON (m.genre & g.genre) WHERE (1 & m.genre) AND (262144 & m.genre) GROUP BY m.id ORDER BY m.title;";
1) Du kan kun have 31 kategorier med en int 2) Din join kan ikke udnytte indexeringer. Er du i gang med at registrere Det kongelige Biblioteks samlinger, så går det måske galt. Hjemmesamlingen går godt.
Normalt vil man lave en "mange-til-mange" tabel mellem dvd-er og kategorier. Det virker som spild af plads, men sql-maskinen kan så udnytte indexering.
Så kan du umiddelbart have mere end 31, men sql-maskinen kan igen ikke udnytte indexering. I begge tilfælde "overtræder" du første normalform for relationelle databaser - som egentlig bare siger, at man skal have data opbevaret så sql-maskinen nemt kan udnytte dem.
En liste som "2,4,6,1,10" kan have en mening, hvis man aldrig søger eller joiner på den. Men ellers er det en "mange-til-mange" ("many-to-many" hvis du vil søge efter det på nettet), du skal have fat i.
Og endelig kan man overveje om det i virkeligheden betyder noget. Der er forskel på en applikation på din egen PC med få data (alle løsninger vil være hurtige nok), og på en mange-bruger løsning med mange forespørgsler med mange data på et delt webhotel. ;)
Jah, det er jo ikke det mest tilgængelige du har fundet. Hvad har du lavet i de 3 tabeller, der er nødvendige ? Vi kan tænke på indexer senere - det skal bare virke først.
Ja altså faktis har jeg ikke fået lavet noget som virker.. :D kun det du kan se ^
Iden er at man kan tilføje en film og vælge flere genre og noget oprindelse (Dansk, Udenlandsk, Dansk børnefilm, Udenlandsk børnefilm) og så ville det jo være smart at lave det så der kan tilkobles flere bruger..
Så hvis du vil hjælpe med at lave de tabeller som skal bruges og lidt SQL til at hente/tilføje/slette.
INSERT INTO `genre` VALUES (1,'Action','Action'); INSERT INTO `genre` VALUES (2,'Erotik','Adult'); INSERT INTO `genre` VALUES (3,'Eventyr','Adventure'); INSERT INTO `genre` VALUES (4,'Animation','Animation'); INSERT INTO `genre` VALUES (6,'Komedie','Comedy'); INSERT INTO `genre` VALUES (7,'Krimi','Crime'); INSERT INTO `genre` VALUES (8,'Dokumentar','Documentary'); INSERT INTO `genre` VALUES (9,'Drama','Drama'); INSERT INTO `genre` VALUES (10,'Familie','Family'); INSERT INTO `genre` VALUES (11,'Fantasi','Fantasy'); INSERT INTO `genre` VALUES (13,'Quiz','Game-Show'); INSERT INTO `genre` VALUES (15,'Gyser','Horror'); INSERT INTO `genre` VALUES (16,'Musik','Music'); INSERT INTO `genre` VALUES (17,'Musical','Musical'); INSERT INTO `genre` VALUES (18,'Mystik','Mystery'); INSERT INTO `genre` VALUES (19,'Nyheder','News'); INSERT INTO `genre` VALUES (20,'Realitet-TV','Reality-TV'); INSERT INTO `genre` VALUES (21,'Romantik','Romance'); INSERT INTO `genre` VALUES (22,'Sci-Fi','Sci-Fi'); INSERT INTO `genre` VALUES (23,'Kort','Short'); INSERT INTO `genre` VALUES (24,'Sport','Sport'); INSERT INTO `genre` VALUES (25,'Underholdning','Talk-Show'); INSERT INTO `genre` VALUES (26,'Spænding','Thriller'); INSERT INTO `genre` VALUES (27,'Krig','War'); INSERT INTO `genre` VALUES (28,'Western','Western');
INSERT INTO `movie` VALUES (1,'Men in Black II'); INSERT INTO `movie` VALUES (2,'Tomb Raider, Lara Croft'); INSERT INTO `movie` VALUES (3,'Terminator, The');
INSERT INTO `movie_rel` VALUES (1,1,1); INSERT INTO `movie_rel` VALUES (2,1,6); INSERT INTO `movie_rel` VALUES (3,1,22); INSERT INTO `movie_rel` VALUES (4,2,1); INSERT INTO `movie_rel` VALUES (5,2,3); INSERT INTO `movie_rel` VALUES (6,2,11); INSERT INTO `movie_rel` VALUES (7,3,1); INSERT INTO `movie_rel` VALUES (8,3,22); INSERT INTO `movie_rel` VALUES (9,3,26);
1) Givet en film-id, skal du have titel og samtlige genrer ud 2) Skal du også kunne finde film, der har en given genre 3) Skal du også kunne finde film, der har en af flere genrer 4) Skal du også kunne finde film, der har alle af en liste af genrer
I alle tilfælde skal du nok lave joins mellem alle 3 tabeller. Jeg vender tilbage lidt senere.
INSERT INTO `users_movie_rel` VALUES (1,1,1); INSERT INTO `users_movie_rel` VALUES (2,1,2); INSERT INTO `users_movie_rel` VALUES (3,2,3); INSERT INTO `users_movie_rel` VALUES (4,2,1);
Når nu har jeg fået lavet det så jeg kan få title og genre ud fra movie table.
SELECT m.id, m.title, GROUP_CONCAT(g.en ORDER BY g.en ASC SEPARATOR ' / ') AS genre FROM movie_rel mr INNER JOIN genre g ON (mr.genreid = g.id) INNER JOIN movie m ON (mr.movieid = m.id) GROUP BY mr.movieid ORDER BY m.title ASC
id | title | genre ---------------------------------------------------------- 1 | Men in Black II | Action / Comedy / Sci-Fi 2 | Terminator, The | Action / Sci-Fi / Thriller 3 | Tomb Raider, Lara Croft | Action / Adventure / Fantasy
Men kan ikke finde ud af hvordan jeg så (søger) på en genre uden at genre kun viser den man (søger) på.
Altså fx. WHERE g.id = 1 så får jeg kun (Action) ud i genre, der skulle den alivel vise de andre opdelt med (/)
SELECT m.id, m.title, GROUP_CONCAT(g.en ORDER BY g.en ASC SEPARATOR ' / ') AS genre FROM movie_rel mr INNER JOIN genre g ON (mr.genreid = g.id) INNER JOIN movie m ON (mr.movieid = m.id) WHERE g.id = 1 GROUP BY mr.movieid ORDER BY m.title ASC
id | title | genre ---------------------------------------------------------- 1 | Men in Black II | Action 2 | Terminator, The | Action 3 | Tomb Raider, Lara Croft | Action
God morgen ;) Jeg kigger på det et par gange i dag. Men til dit spørgsmål:
SELECT m.id, m.title, GROUP_CONCAT( g.en ORDER BY g.en ASC SEPARATOR ' / ' ) AS genre FROM movie_rel mr INNER JOIN genre g ON ( mr.genreid = g.id ) INNER JOIN movie m ON ( mr.movieid = m.id ) WHERE m.id IN (
SELECT DISTINCT movie.id FROM movie JOIN movie_rel ON movie.id = movie_rel.movieid WHERE movie_rel.genreid =22 ) GROUP BY m.id ORDER BY m.title ASC
INSERT INTO `users` VALUES (1,'sjh'); INSERT INTO `users` VALUES (2,'erikjacobsen');
INSERT INTO `users_movie_rel` VALUES (1,1,1); INSERT INTO `users_movie_rel` VALUES (2,1,2); INSERT INTO `users_movie_rel` VALUES (3,2,3); INSERT INTO `users_movie_rel` VALUES (4,2,1);
Ja det var så lige det jeg havede tinkt mig at du skulle lave :D
den her virker.. der skal bare lige kobles users på..
SELECT m.id, m.title, GROUP_CONCAT( g.en ORDER BY g.en ASC SEPARATOR ' / ' ) AS genre FROM movie_rel mr INNER JOIN genre g ON ( mr.genreid = g.id ) INNER JOIN movie m ON ( mr.movieid = m.id ) WHERE m.id IN (
SELECT DISTINCT movie.id FROM movie JOIN movie_rel ON movie.id = movie_rel.movieid WHERE movie_rel.genreid =22 ) GROUP BY m.id ORDER BY m.title ASC
SELECT m.id, m.title, GROUP_CONCAT( g.en ORDER BY g.en ASC SEPARATOR ' / ' ) AS genre FROM movie_rel mr INNER JOIN genre g ON ( mr.genreid = g.id ) INNER JOIN movie m ON ( mr.movieid = m.id ) INNER JOIN users_movie_rel u ON ( mr.movieid = u.movieid ) WHERE m.id IN ( SELECT DISTINCT movie.id FROM movie JOIN movie_rel ON movie.id = movie_rel.movieid WHERE movie_rel.genreid =22 ) AND u.userid=2 GROUP BY m.id ORDER BY m.title ASC
Ok har flyttet lidt rundt på det men det skulle vel være det samme ik ? (...WHERE u.userid = 2 AND m.id IN...)
SELECT m.id, m.title, GROUP_CONCAT(g.en ORDER BY g.en ASC SEPARATOR ' / ') AS genre FROM movie_rel mr INNER JOIN genre g ON (mr.genreid = g.id) INNER JOIN movie m ON (mr.movieid = m.id) INNER JOIN users_movie_rel u ON (mr.movieid = u.movieid) WHERE u.userid = 2 AND m.id IN ( SELECT DISTINCT movie.id FROM movie JOIN movie_rel ON movie.id = movie_rel.movieid WHERE movie_rel.genreid = 22 ) GROUP BY m.id ORDER BY m.title ASC
Hvad med den Index.. -> PRIMARY KEY (`a_id`,`b_id`)
1) Der er automatisk index på en primærnøgle 2) Der bør sættes index på fremmednøgler (også selv om man ikke angiver dem som fremmednøgler). Der er typisk de felter, der ikke er primærnøgler, som man anvender i en "JOIN ON ..." 3) Dertil kommer så kunsten at se, om der er andre felter, man søger på med noget i retning af " WHERE felt='værdi' ", hvor det kan betale sig.
Et index på et felt gør søgning generelt hurtigere, men det tager længere tid at indsætte og opdatere rækker. I 3) skal man nemlig lige regne ud om de andre betingelser man har (med indexer på), vil gøre antallet af rækker, hvor man skal lave sammenligningen med " felt='værdi' ", så lille, at det ikke kan betale sig med et index.
Men lav 1) og 2), og vent og se hvor langsomt det går. Det er ikke til at vide hvilke SQL-forespørgsler du ender med, mens du udvikler. Brug gerne MySqls EXPLAIN kommando til at finde ud af hvordan en given forespørgsel udføres, og lav indexer ud fra det.
Jeg samler slet ikke på point, tak. Du kan ikke bruge en EXPLAIN før der er så mange data i tabellen, som du regner med at bruge. Måske derfor der står ALL nogle steder (indikerer et tablescan, altså en masse rækker der løbes igennem) - men det kan nemt ændre sig ved en stor tabel.
Det jeg mener er at udregningsrækkefølgen også bestemmes af størrelserne af tabeller og delresultater, så man skal ikke lægge noget i at der vælges en "tablescan" for små tabeller - det kan nemt være det hurtigste. Det er først ved de store indexer bliver udnyttet fuldt ud.
Fandt lige en lille fejl (WHERE dmr.genreid = 22 AND dmr.genreid = 1) Den giver null selv om genreid har både 1 og 22
SELECT m.id, m.title, GROUP_CONCAT(g.en ORDER BY g.en ASC SEPARATOR ' / ' ) AS genre FROM movie_rel mr INNER JOIN genre g ON (mr.genreid = g.id) INNER JOIN movie m ON (mr.movieid = m.id) INNER JOIN users_movie_rel u ON (mr.movieid = u.movieid) WHERE u.userid=2 AND m.id IN ( SELECT DISTINCT dm.id FROM movie dm JOIN movie_rel dmr ON dm.id = dmr.movieid WHERE dmr.genreid = 22 AND dmr.genreid = 1 ) GROUP BY m.id ORDER BY m.title ASC
SELECT m.id, m.title, GROUP_CONCAT(g.en ORDER BY g.en ASC SEPARATOR ' / ' ) AS genre FROM movie_rel mr INNER JOIN genre g ON (mr.genreid = g.id) INNER JOIN movie m ON (mr.movieid = m.id) INNER JOIN users_movie_rel u ON (mr.movieid = u.movieid) WHERE u.userid=2 AND m.id IN ( SELECT DISTINCT dm.id FROM movie dm JOIN movie_rel dmr ON dm.id = dmr.movieid WHERE dmr.genreid = 6 OR dmr.genreid = 1 GROUP BY dmr.movieid HAVING COUNT(*) > 1 ) GROUP BY m.id ORDER BY m.title ASC
Nej tak, ingen point til mig. Det er jo heller ikke super-service, der leveres. Hvis det tager længere tid for mig end 30 sekunder, at udtænke et svar, så bliver sådan et spørgsmål g(l)emt. ;(
okææ æv.. så må jeg vel tag dem selv.. :D men mange tak for en stor hjælp.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.