Autor Beitrag
ChrisHa
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 30

Win 7 x64
VS 2010, 2008
BeitragVerfasst: Di 07.01.14 12:03 
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 (www.imdb.com/title/t...26/?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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: 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.

Für diesen Beitrag haben gedankt: ChrisHa
ChrisHa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 30

Win 7 x64
VS 2010, 2008
BeitragVerfasst: Di 07.01.14 12:29 
Quasi dann eine m:n Beziehung oder?
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: 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:

ausblenden 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

Für diesen Beitrag haben gedankt: ChrisHa
ChrisHa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 30

Win 7 x64
VS 2010, 2008
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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.

Für diesen Beitrag haben gedankt: ChrisHa
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: 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.

Für diesen Beitrag haben gedankt: ChrisHa
baumina
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 305
Erhaltene Danke: 61

Win 7
Delphi 10.2 Tokyo Enterprise
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 07.01.14 14:28 
Hallo ChrisHa,

du kannst dir auch mal den Wikipedia-Artikel Normalisierung (Datenbank) durchlesen (insbesondere zur 2. und 3. Normalform - dies sind sogar ähnliche Beispiele passend zu deinen Tabellen).

Für diesen Beitrag haben gedankt: ChrisHa
ChrisHa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 30

Win 7 x64
VS 2010, 2008
BeitragVerfasst: Di 07.01.14 14:30 
@baumina:
ausblenden 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 :)
Einloggen, um Attachments anzusehen!
baumina
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 305
Erhaltene Danke: 61

Win 7
Delphi 10.2 Tokyo Enterprise
BeitragVerfasst: 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.

Für diesen Beitrag haben gedankt: ChrisHa
ChrisHa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 30

Win 7 x64
VS 2010, 2008
BeitragVerfasst: 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.
Einloggen, um Attachments anzusehen!
ChrisHa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 30

Win 7 x64
VS 2010, 2008
BeitragVerfasst: 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: