DB Aufbau und Auswahl - Was nicht ganz verstanden.
Stefan
- datenbank
0 Klaus Mock0 Stefan
Hallo,
habe da was nicht ganz verstanden und hoffe auf Klärung.
Habe z.B. eine Filmdatenbank, in der u.a. die Tabellen Film (T_Film) und Schauspieler (T_Artist)enthalten sind. Jetzt kann ja jeder Film mehrere Schauspieler haben und jeder Schauspieler kann in mehreren Filmen mitspielen. Also brauche ich eine Zwischentabelle um die Besetzung eines Filmes eindeutig zu bestimmen (T_Cast).
Soweit so gut, nun aber die Frage muß ich in der Tabelle (T_Cast) für jeden Schauspieler eine eigene Spalte anlegen (Artist_1, Artist_2, ....) oder kann ich einfach eine Spalte anlegen und dort
die ID Nummern aller im Film mitspielenden Schauspieler angeben (Spalte: Cast, Werte: (1,4,7,25,etc.)?
Falls ersters der Fall ist, müßte ich ja beliebig viele Spalten anlegen um die Vollständigkeit zu gewähren - das kann aber nicht die Lösung sein oder? (falls doch wie finde ich heraus wieviele Spalten eine Zeile hat? Kann ja ein Kammerspiel mit 2 Schauspielern sein oder ein Monumentalfilm mit 100 Schauspielern)
Falls zweites der Fall ist wie müßte dann die Abfrage in z.B. MySql aussehen?
In etwa so?
Tabelle Film enthält:
Film_ID (primary key)
Cast_ID (foreign key auf Tabelle Cast)
Film_Titel
etc ...
Tabelle Cast enthält:
Cast_ID (primary key)
Film_ID (foreign key auf Tabelle Film)
Artist_ID (foreign key auf Tabelle Artist)
etc ...
Tabelle Artist enthält:
Artist_ID (primary key)
Artist_Name
etc ...
(Ausgabe erfolgt über PHP)
$sql= "select T_Film.Film_ID, T_Film.Film_Titel, T_Cast.Cast_ID, T_Artist.Artis_ID, T_Artist.Artist_Name from T_Film, T_Cast, T_Artist where T_Film.Cast_ID=T_Cast.Cast_ID && T_Artist.Artist_ID Like %T_Cast.Artist_ID% Group By T_Film.Film_ID Order By T_Artist.Artist_Name";
$erg = mysql_query($sql)
while ($Aus = mysql_fetch_array($erg))
{
echo $Aus["Film_Titel"];
echo $Aus["Artist_Name"] ."<br>";
}
Ist das so richtig?
Falls nicht, was habe ich falsch gemacht?
Hoffe auf Hilfe, danke!
Grüße,
Stefan
Hallo,
Soweit so gut, nun aber die Frage muß ich in der Tabelle (T_Cast) für jeden Schauspieler eine eigene Spalte anlegen (Artist_1, Artist_2, ....) oder kann ich einfach eine Spalte anlegen und dort
die ID Nummern aller im Film mitspielenden Schauspieler angeben (Spalte: Cast, Werte: (1,4,7,25,etc.)?
Eigentlich ist es besser, wedr das eine noch das andere zu machen.
Tabelle Cast enthält:
Cast_ID (primary key)
Film_ID (foreign key auf Tabelle Film)
Artist_ID (foreign key auf Tabelle Artist)
Cast_ID ist im Printip überflüssig, besser wäre es Film_ID und Artist_ID gemeinsam als Primärschlüssel zu definieren (oder zumindest einen Unique Index zu verwenden).
Dann legst Du für jede Schauspielerin, die in einem bestimmten Film mitspielt, einen Datensatz in dieser Tabelle an. Es können also entweder zwei Datensätze für ein Kammerspiel, und >1000 Datensätze für einen Monumentalschinken werden
Deine Abfrage könnte dann so aussehen:
SELECT T_Film.Film_ID, T_Film.Film_Titel,
T_Artist.Artis_ID, T_Artist.Artist_Name
FROM T_Film
JOIN T_Cast ON T_Film.Film_ID = T_Cast.Film_ID
JOIN T_Artist ON TCast.Artist_ID = T_Artist.Artist_ID
ORDER BY T_Artist.Artist_Name
Oder auch nur
SELECT T_Film.Film_ID, T_Film.Film_Titel,
FROM T_Film
JOIN T_Cast ON T_Film.Film_ID = T_Cast.Film_ID
WHERE T_Cast.Artist_ID = 123
ORDER BY T_Film.Film_Titel
wenn DU z.B. die Filme wissen willst, bei denen die Schauspielerin mit der ID 123 mitmirkte.
Du könntest dann die Tabelle noch um weitere Attribute wie z.B. ob sie eine Hauptrolle oder Komparsin in den Film war. Eventuell willst DU auch einmal die anderen Mitwirkenden, wie Regiesseur usw. mit erfassen, was dann recht einfach geht.
Merke: Wenn Du versucht bist, in einer relationalen Datenbank in einer mit Feld1..Feldx zu arbeiten, dann sollten die Alarmglocken angehen. Im überwiegenden Fall verstößt Du damit gegen die Grundprinzipien eines solchen Systems. Wiederholfelder sollten in der Regel mehrere Datensätze werden.
Suche nach "Normalisieren von Datenbanken" im Netz, um mehr darüber zu lernen, ich habe auf die Schnelle keinen brauchbaren Link zur Hand.
Grüße
Klaus
Hallo,
danke für die schnelle Antwort - habe allerdings noch ein paar Verständnisfragen.
Eigentlich ist es besser, wedr das eine noch das andere zu machen.
Tabelle Cast enthält:
Cast_ID (primary key)
Film_ID (foreign key auf Tabelle Film)
Artist_ID (foreign key auf Tabelle Artist)
Cast_ID ist im Printip überflüssig, besser wäre es Film_ID und Artist_ID gemeinsam als Primärschlüssel zu definieren (oder zumindest einen Unique Index zu verwenden).
Also habe ich nun in der Tabelle Cast nur Primary Keys?
Film_ID (primary key)
Artist_ID(primary key)
Regie_ID (primary key) (falls ich die Tabelle erweitern will)
etc.
Dann legst Du für jede Schauspielerin, die in einem bestimmten Film mitspielt, einen Datensatz in dieser Tabelle an. Es können also entweder zwei Datensätze für ein Kammerspiel, und >1000 Datensätze für einen Monumentalschinken werden
Sprich ich habe dann Datensätze ala (||| hier als optische Trenunng zwicshen den beiden Spalten;-)
Film_ID ||| Artist_ID
1 ||| 25
1 ||| 26
1 ||| 235
1 ||| 655
2 ||| 3
2 ||| 45
2 ||| 33
etc.
Ist das richtig oder kann ich Datensätze haben ala
1 ||| 25, 26, 235, 655
2 ||| 3, 45, 33
Deine Abfrage könnte dann so aussehen:
SELECT T_Film.Film_ID, T_Film.Film_Titel,
T_Artist.Artis_ID, T_Artist.Artist_Name
FROM T_Film
JOIN T_Cast ON T_Film.Film_ID = T_Cast.Film_ID
JOIN T_Artist ON TCast.Artist_ID = T_Artist.Artist_ID
ORDER BY T_Artist.Artist_Name
wenn ich hier nun noch eine dritte (vierte, etc.) Tabelle verbinden will kann ich das einfach so machen? - Sprich kann ich beliebig viele Joins machen?
JOIN T_Regie ON T_Cast.Regie_ID = T_Regie.Regie_ID
etc.
Oder auch nur
SELECT T_Film.Film_ID, T_Film.Film_Titel,
FROM T_Film
JOIN T_Cast ON T_Film.Film_ID = T_Cast.Film_ID
WHERE T_Cast.Artist_ID = 123
ORDER BY T_Film.Film_Titel
wenn DU z.B. die Filme wissen willst, bei denen die Schauspielerin mit der ID 123 mitmirkte.
Merke: Wenn Du versucht bist, in einer relationalen Datenbank in einer mit Feld1..Feldx zu arbeiten, dann sollten die Alarmglocken angehen. Im überwiegenden Fall verstößt Du damit gegen die Grundprinzipien eines solchen Systems. Wiederholfelder sollten in der Regel mehrere Datensätze werden.
Suche nach "Normalisieren von Datenbanken" im Netz, um mehr darüber zu lernen, ich habe auf die Schnelle keinen brauchbaren Link zur Hand.
Danke werde ich machen.
Grüße,
Stefan
In Deinem Fall wäre folgende Anordnung ideal und wird auch in der Praxis so gehandhabt.
Film Tabelle
FilmID (Primary)
Filmtitel
Jahrgang
...
Actor Tabelle
ActorID (Primary)
Vorname
Nachname
...
Cast Tabelle
FilmID
ActorID
Eine mögliche Abfrage wäre z.B.
SELECT
*
FROM
Actor,Cast
WHERE
Cast.FilmID = 1
AND
Cast.ActorID = Actor.ActorID
Cheers
Sascha
Hallo,
en).
Also habe ich nun in der Tabelle Cast nur Primary Keys?
Film_ID (primary key)
Artist_ID(primary key)
Regie_ID (primary key) (falls ich die Tabelle erweitern will)
etc.
Nein, Eigentlich eher:
Film_ID(primary key)
Artist_ID(primary key)
ArtistRole_ID
(wobei ArtistRoleID festlegt, was der Artist genau gemacht hat, eventuell müsste es sogar eine zusätzliche Tabelle werden, wenn jemand mehreres in Personalunion gemacht hat, aber das ist ja etwas für den nächsten Schritt).
Sprich ich habe dann Datensätze ala (||| hier als optische Trenunng zwicshen den beiden Spalten;-)
Film_ID ||| Artist_ID
1 ||| 25
1 ||| 26
1 ||| 235
1 ||| 655
2 ||| 3
2 ||| 45
2 ||| 33
etc.
Ist das richtig
Ja.
oder kann ich Datensätze haben ala
1 ||| 25, 26, 235, 655
2 ||| 3, 45, 33
nein, so etwas gibt es in relationalen Datenabnken nicht.
Deine Abfrage könnte dann so aussehen:
wenn ich hier nun noch eine dritte (vierte, etc.) Tabelle verbinden will kann ich das einfach so machen? - Sprich kann ich beliebig viele Joins machen?
JOIN T_Regie ON T_Cast.Regie_ID = T_Regie.Regie_ID
You've got it;-)
Grüße
Klaus
Hallo Stefan
Also habe ich nun in der Tabelle Cast nur Primary Keys?
Film_ID (primary key)
Artist_ID(primary key)
Regie_ID (primary key) (falls ich die Tabelle erweitern will)
etc.
In Deinem Fall ist die Tabelle "Cast" eine Beziehungsentität zwischen den Hauptentitäten "Film" und "Artist", die in einer n:m-Beziehung stehen.
In einer Beziehungsentität sollten nur Informationen verwaltet werden, die im direkten Zusammenhang mit der Beziehung(!) stehen. Falls Du z.B. die Zeit des Schauspielers in allen von ihm in diesem Film gespielten Szenen (17'35") speichern willst oder die Rolle die er in diesem Film gespielt hat (Weibliche Hauptrolle, etc). So könntest Du z.B. die Tabelle um das Attribut "Rolle" erweitern:
Film_ID
Artikel_ID
Rolle
Für die weiteren n:m-Beziehungen zu anderen Entitäten wie "Regie" benötigst Du eine separate Beziehungsentität, z.B. "Filmregie" (oder sonst was) die etwa so aussehen müsste:
Film_ID (kombinierter Primary Key)
Regie_ID (kombinierter Primary Key)
Du solltest nicht Beziehungsentitäten unterschiedlicher Beziehungen in einer Tabelle mischen.
Besser ist es, für jede zum Film in einer n:m-Beziehung stehende Entität (Regie, Produzent, etc) eine eigene Tabelle und zugehörige Beziehungstabelle zu schaffen.
Weiter Abstrahiert könnte man aber den Begriff "Artist" nicht nur auf die Schauspieler beschränken, sondern ihn auf alle am Film Mitwirkenden (Regisseur, Produzent, Kamera, Ton, Schnitt, Maske, etc.) erweitern. Diese hätten dann in einem Film eine Ihnen zugeordnete Rolle.
In diesem Fall würde die Beziehungsentität "Cast" ein weiteres Attribut "Rolle" erhalten:
Film_ID (Foreignkey aus Tabelle "Film")
Artist_ID (Foreignkey aus Tabelle "Film")
Rolle (z.B. "männlicher Hauptdarsteller", "Regisseur", ...)
Noch weiter Normalisiert (und dies ist bei vielen unterschiedlichen Rollen durchaus sinnvoll) müsste man für die Rollen eine eigene Entität "Rollen" definieren. Diese enthält alle möglichen Rollen der Filmmitwirkung und weist etwa folgende Struktur auf:
Rolle_ID
Rolle_Titel
...
Die Beziehungsentität "Cast" müsste dann so angepasst werden:
Film_ID (Foreignkey aus Tabelle "Film")
Artist_ID (Foreignkey aus Tabelle "Artist")
Rolle_ID (Foreignkey aus Tabelle "Rolle")
Die Datensätze in der Tabelle "Cast" sehen dann etwa so aus:
Film_ID Artist_ID Rolle_ID
1 23 3 (männlicher Hauptdarsteller)
1 278 2 (weiblicher Hauptdarsteller)
1 5 1 (Regisseur)
2 47 2 (weiblicher Hauptdarsteller)
2 5 3 (männlicher Hauptdarsteller)
2 53 1 (Regisseur)
Hinweis: Der Artist mit der ID=5 kann sowohl in einem Film der Regisseur, im anderen Film der männliche Hauptdarsteller sein.
Diese zweite Modellierung ist zugegebenermassen etwas abstrakter und komplizierter, sie ist aber flexibler, falls Du alle bei einem Film Mitwirkenden (Schnitt, Ton, Make-Up, Beleuchtung, Polizist Nr. 7, etc.) verwalten möchtest.
Sind Dir aber nur einige wenige Rollen wichtig (z.B. die Hauptdarster und der Regisseur), so ist es einfacher und übersichtlicher für jede Rolle eine eigene Tabelle mit der n:m-Beziehung zum Film anzulegen.
Ich hoffe, das hilft ewas weiter.
Grüsse
Eisbär
Hallo,
danke für die ausführlichen Antworten - ich glaube jetzt habe ich es endlich kapiert (wenn doch nicht, hoffe ich, daß ich mich nochmal melden darf).
Auf alle Fälle nochmals tausend Dank Ihr habt mir wirklich super weitergeholfen!
Grüße,
Stefan