Entwickler-Ecke

Datenbanken (inkl. ADO.NET) - SQL Anweisung - Datenbank Filme --> Genre


ChrisHa - Di 07.01.14 12:03
Titel: SQL Anweisung - Datenbank Filme --> Genre
Hallo,

habe mir eine Datenbank wie folgt angelegt (vereinfacht dargestellt):

[Filme]
id
Name
Genre
...

[Genre]
Action
Drama
Adventure
...

(Die Punkte verweisen daraufhin, dass noch mehr Daten in der Tabelle enthalten sind. Die Begriffe in den eckigen Klammern sind die Tabellen Namen)

Nun kann es sein, dass ein Film nicht nur eine Genre besitzt. Nehmen wir hier mal den Film the Legend of Hercules (http://www.imdb.com/title/tt1043726/?ref_=hm_inth_t1). Dieser hat die Genre: Action und Adventure.

Wie verknüpfe ich die Tabellen miteinander, so dass der Film zwei Genre haben kann?
1:n oder wie ist das?
Und was steht dann in Genre in der Tabelle Filme? Welchen Datentyp muss ich Genre geben?

Der Aufruf sollte später einfach so erfolgen:

SQL-Anweisung
1:
SELECT [hier id] FROM Filme                    

Ich stehe glaube ich einfach nur etwas auf dem Schlauch und sehe den Wald vor lauter Bäumen nicht.

Vielen Dank für die Hilfe.

Moderiert von user profile iconTh69: SQL-Tags hinzugefügt


jasocul - Di 07.01.14 12:28

Du brauchst eine dritte Tabelle. Diese Enthält die Film-ID und die Genres zum Film.
das Genre wird also nicht mehr in der Film-Tabelle gespeichert, sondern in dieser dritten Tabelle.


ChrisHa - Di 07.01.14 12:29

Quasi dann eine m:n Beziehung oder?


Palladin007 - Di 07.01.14 12:30

Das, was du suchst, ist eine m:n-Beziehung und lässt sich nur mit einer dritten Tabelle lösen, die dann beide zu Film und Genre jeweils eine 1:n-Beziehung hat.
Also eine Tabelle mit den Schlüsseln FilmId und GenreId.

Der Aufruf wäre dann ungefähr so:


SQL-Anweisung
1:
2:
3:
4:
SELECT Filme.Name AS FilmName, Genre.Name AS GenreName
FROM Filme
    LEFT JOIN FilmGenres ON FilmGenres.FilmId = Filme.Id
    LEFT JOIN Genres ON FilmGenres.GenreId = Genres.Id


Ob das Statement so jetzt funktioniert, weiß ich nicht, habs nur grad ad hock hin geschrieben.

Außerdem, warum schreibst du in die Tabelle Genre als Spalten die Genres?
Ich würde dem Genre eher die Spalte 'Name' geben. Noch eine ID, wenn du den Aufruf über die ID machen willst, der Name würde aber auch als Primärschlüssel gehen, da der ja sowieso eindeutig sein muss.

Moderiert von user profile iconTh69: Code- durch SQL-Tags ersetzt


ChrisHa - Di 07.01.14 13:12

Dank an jasocul und an Palladin007 für eure Hilfe.

@Palladin007:
Da hast du Recht, das war gerade nur ein Denkfehler von mir.

[Genre]
Id
Name (Inhalt: Action, Adventure, etc.)



--------------
@all:
In der dritten Tabelle habe ich dann aber trotzdem eine Redundanz oder habe ich das falsch verstanden?


Ralf Jansen - Di 07.01.14 13:31

Zitat:
@all:
In der dritten Tabelle habe ich dann aber trotzdem eine Redundanz oder habe ich das falsch verstanden?


Ich glaube schon. Was sollte da redundant sein? Da stehen nur die Schlüsselpaare aus den beiden beteiligten Tabellen drin aber keine Daten. Wenn du dieser Tabelle einen eigenen eindeutigen Primärschlüssel gibst, denn man nicht zwingend brauch ich aber trotzdem empfehlen würde, könnte man behaupten das das mehr Speicher braucht aber redundant ist das dann noch lange nicht.


jasocul - Di 07.01.14 14:17

Zitat:
In der dritten Tabelle habe ich dann aber trotzdem eine Redundanz oder habe ich das falsch verstanden?

Wenn du die Genre-Tabelle mit einer ID-Spalte versiehst und in der m:n-Tabelle nur noch die Film-id und Genre-id speicherst, hast du keine Redundanz.


baumina - Di 07.01.14 14:19

Du wirst nur in dem select das Problem haben, dass ein und der selbe Film genau sooft erscheint in wieviel Genres er zu finden ist.


Th69 - Di 07.01.14 14:28

Hallo ChrisHa,

du kannst dir auch mal den Wikipedia-Artikel Normalisierung (Datenbank) [http://de.wikipedia.org/wiki/Normalisierung_%28Datenbank%29] durchlesen (insbesondere zur 2. und 3. Normalform - dies sind sogar ähnliche Beispiele passend zu deinen Tabellen).


ChrisHa - Di 07.01.14 14:30

@baumina:

Quelltext
1:
SELECT * FROM Filme                    

müsste mir doch alle meine Filme ausgeben. Oder kriege ich die Filme dann doppelt in diesem Fall?
In der Filme Tabelle an sich dürfte jeder doch nur einmal vorkommen oder nicht?



@all:
Zum Verständnis habe ich einen Screenshot angefügt. Die zweite Relation ist mit der ID der GenreID verbunden.


@Th69:
werde ich und danke hierfür :)


baumina - Di 07.01.14 14:42

Klar, ein select from Filme bringt dir jeden Film nur einmal, allerdings halt ohne Genre. Wenn du die Genres mit selektieren willst (siehe Vorschlag mit dem JOIN) dann kommen sie mehrfach.

Dein Modell schaut richtig aus.


ChrisHa - Di 07.01.14 15:03

@baumina:
Danke für dein Einsehen meines Screenshots.

Zitat:
Klar, ein select from Filme bringt dir jeden Film nur einmal, allerdings halt ohne Genre. Wenn du die Genres mit selektieren willst (siehe Vorschlag mit dem JOIN) dann kommen sie mehrfach.


Man muss sich das später so vorstellen, dass ich eine Auflistung meiner ganzen Filme in einer ListView oder ähnliches habe und diese durch anklicken quasi angezeigt werden. (siehe Screenshot)
Die Daten sollen bei Klick von der Datenbank geholt werden. Die Genres soll entweder in einem Feld erscheinen oder per Checkboxen ausgewählt werden oder eben in einer Listbox anwählbar bzw. schon angewählt sein.


ChrisHa - Di 07.01.14 16:39

Mein Themenproblem dürfte somit eigentlich gelöst sein.
Die Abfrage wird später über join bzw. left join funktionieren (hoffe ich zumindest :roll: )



Danke an alle die mir geholfen haben. Wenn sich das Problem später beim Programmieren nochmal aufweist werde ich in diesen Thread nochmal schreiben, ansonsten einen neuen eröffnen. :lol: