Archief - SQL: Ontwerpvraagje

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

Cyberkef

Legacy Member
Hi,

Ik ben hier al een poosje bezig met het ontwerpen/scripten van een "multi-user film bibliotheekje", waar ik dus oa een tabel heb met alle films in en ook de bijbehorende genres (en nog veel meer natuurlijk, maar daar gaat de vraag niet over).

Nu, op dit moment steken al die genre_id's in een gewone imploded array (bvb "2/5/14") bij de bijbehorende film, maar als ik dan wil zoeken op één genre, moet ik al 4 WHERE checks insteken: "$genre_id", "%/$genre_id", "$genre_id/%" of "%/$genre_id/%".

Voor de mensen die afvragen wrom ik niet gewoon op %genre_id% zoek, als je op genre_id = 1 zou zoeken, zou em ook films met bvb genre_id = 16 als resultaat teruggeven, wat natuurlijk de bedoeling niet is ;) Of erger: eerst alle resultaten uithalen, die array's exploden en zo filteren...

Als je dan wilt zoeken op films met 2 bepaalde genres, zit je al met 8 zo'n where-checks in één query :unsure:

Nu dacht ik dat het mss gemakkelijker/netter/correcter zou zijn dat ik een aparte tabel maakte met als kolommen de genre_id's en als rij de movie_id's, en dan gewoon 0 of 1 in de cel zet als die bepaalde film dat genre heeft. Zo kan je dan heel snel en gemakkelijk op één of meerdere genres zoeken.

Zou het nu eigenlijk de moeite zijn om dat in die aparte tabel te steken? Of zou het geen verschil uitmaken qua snelheid/loads? En ook qua "correctheid/netheid" van het ontwerp, is die aparte tabel het beste?

Breen

Legacy Member
Wat je eigenlijk wil leggen is een many-to-many relatie, daarvoor heb je inderdaad extra tabellen voor nodig, om precies te zijn 2 extra tabellen.

- Een extra tabel (genres) waar je genreId en genre bijhoudt, PK = genreId
- Een extra tabel (movieGenres) waar je genreId en movieId insteekt, PK = genreId & movieId

Op deze manier kan je dan meerdere films, meerdere genre's geven, en moet je maar 1 enkele where opvragen in je tussentabel movieGenres

Als je nog vragen hebt stel ze gerust.

Boddah

Legacy Member
je kunt maar één PK per tabel hebben.
de tabel movieGenres zal PK = movieGenreID, en FK = genreId & movieId moeten hebben

Breen

Legacy Member
Boddah zei:
je kunt maar één PK per tabel hebben.
de tabel movieGenres zal PK = movieGenreID, en FK = genreId & movieId moeten hebben

Mijn verontschuldigingen, de juiste nomenclatuur ontgaat me nu, kweet enkel dat ik van deze 2 kolommen pk maak, in mijn software omgeving dan, waarna dat altijd inorde is, movieGenreId voeg ik eigenlijk nooit toe btw.

Kweet het, niet echt professioneel, maar jah, databases liggen dan ook niet echt binnen mijn interesse veld.

WHiSPy

Legacy Member
Boddah zei:
je kunt maar één PK per tabel hebben.
de tabel movieGenres zal PK = movieGenreID, en FK = genreId & movieId moeten hebben

Er bestaat ook iets als een geclusterde PK en dat is net hetgene dat ie bedoelt denk 'k. Enkel is zo'n geclusterde key ten zeerste af te raden, aangezien het enkel zorgt voor extra complexiteit.

Radiance

Legacy Member
Wat is er mis met een samengestelde sleutel? Dat is bij mijn weten een correcte manier van werken?
Je mag enkel niet vergeten van bij een eventuele delete ook in die koppeltabel alle verwijzingen naar die film of dat genre weg te doen.

Het is alvast een veel betere oplossing dan array's met genres in uw film tabel te steken :)

wonko

Legacy Member
Samengestelde keys zijn zeker geen slecht idee, en in dit geval is dit de enige oplossing, aangezien je anders meermaals een film aan een bepaald genre kan koppellen, wat niet de bedoeling is. Als je verder nog foreign keys instelt, kan je zelfs geen ongeldige entries in je many2many tabel hebben, afhankelijke van de mogelijkheden van je database (genre weg, ook alle entries in je m2m tabel automatisch weg).

WHiSPy

Legacy Member
wonko zei:
Samengestelde keys zijn zeker geen slecht idee, en in dit geval is dit de enige oplossing, aangezien je anders meermaals een film aan een bepaald genre kan koppellen, wat niet de bedoeling is. Als je verder nog foreign keys instelt, kan je zelfs geen ongeldige entries in je many2many tabel hebben, afhankelijke van de mogelijkheden van je database (genre weg, ook alle entries in je m2m tabel automatisch weg).

Hetgeen jij wil forceren is 'n constraint en dat is iets anders dan 'n primary key. En het 2e deel is 'n auto-cascade, wat je dus eigenlijk feitelijk ook niet kan bekomen met 'n key.

Een clustered primary key is vragen om problemen op het vlak van zowel de update als de delete-statement. Indien je in 1 van beiden 1 where-clause vergeet op te geven, dan breng je heel de integriteit van je data in gevaar.

Daarom prefereer ik nog altijd om een simpele primary key te kiezen voor 'n many-to-many tabel en de beide foreign keys apart te houden. Dat zorgt ook voor 'n betere opbouw van de index-tree binnen je database.

Cyberkef

Legacy Member
Ok, thx voor alle uitleg mannen :D

Direct es in elkaar boksen se :)

killgore

Legacy Member
als uw aantal genres zeer beperkt is kunde altijd met bitops gaan werken (#genres < 32 dan wel :p).

en over foreign keys: asset mysql is moogde hopen dat uw host dan al is overgeschakeld naar 5.0, kdenk nie da het daarvoor ondersteund is.

Cyberkef

Legacy Member
Het wordt atm gehost op mijn pc, dus np ;)
Zodra de nieuwe phpmyadmin uit beta is, update ik mysql naar 5.0. Ondertussen kan ik mij es beter verdiepen in die FK's want dat is relatief nieuw voor mij en klinkt wel intressant ;)

Ik heb al een gans deel herschreven ondertussen, en het werkt zalig goed :)

DJ_Trash

Legacy Member
many to many relatie, dus tussentabel maken is hier het standaard antwoord
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan