Domanda

Sto cercando di farmi girare la testa in questa roba da capogiro che chiamano Database Design senza molto successo, quindi cercherò di illustrare il mio problema con un esempio.

Sto usando MySQL ed ecco la mia domanda:

Dire che voglio creare un database per contenere la mia raccolta di DVD. Ho le seguenti informazioni che voglio includere:

  1. Titolo del film
  2. Attori
  3. Tempo di esecuzione
  4. genere
  5. Descrizione
  6. Anno
  7. Direttore

Vorrei creare relazioni tra questi per renderlo più efficiente ma non so come.

Ecco cosa sto pensando per la progettazione del database:

Tabella dei film = > filmid, filmtitle, tempo di esecuzione, descrizione

Tabella annuale = > anno

Tabella dei generi = > genere

Tavolo Director = > direttore

Tabella attori = > ACTOR_NAME

Ma come farei per creare relazioni tra queste tabelle?

Inoltre, ho creato un ID univoco per la tabella dei film con una chiave primaria che si incrementa automaticamente, devo creare un ID univoco per ogni tabella?

E infine, se dovessi aggiornare un nuovo film nel database tramite un modulo PHP, come inserirò tutti questi dati (con le relazioni e tutti?)

grazie per l'aiuto che puoi dare, Keith

È stato utile?

Soluzione

Devi fare una distinzione tra attributi ed entità. Un'entità è una cosa - di solito un sostantivo. Un attributo è più simile a una descrizione delle informazioni. Nel gergo del database, entità = tabella, attributo = campo / colonna.

Avere una tabella separata per certe cose, usiamo director, come esempio, si chiama normalizzazione. Anche se può essere buono in alcune circostanze, può essere inutile in altre (poiché in genere rende le query più complicate - devi unirti a tutto - ed è più lento).

In questo caso, avere una tabella degli anni non è necessario, dal momento che non ci sono altri attributi circa un anno, oltre l'anno stesso, che si desidera memorizzare. È meglio denormalizzare questo e archiviare l'anno sul tavolo del film stesso.

Director, d'altra parte, è diverso. Forse ti consigliamo di memorizzare il nome del regista, il cognome, la data di nascita, la data di morte (se applicabile), ecc. Ovviamente non vuoi inserire la data di nascita del regista ogni volta che entri in un film che questa persona dirige, quindi ha senso avere un'entità separata per un regista.

Anche se non volessi conservare tutte queste informazioni sul regista (vuoi solo il loro nome), avere una tabella separata (e usare una chiave surrogata - ci arriverò tra un secondo) è utile perché impedisce errori tipografici e duplicati: se il nome di qualcuno è stato digitato in modo errato o inserito in modo diverso (primo, ultimo vs ultimo, primo), quindi se provi a trovare altri film che hanno diretto, fallirai.

L'uso di una chiave surrogata (chiave primaria) per le tabelle è generalmente una buona idea. La corrispondenza di un numero intero è molto più rapida della corrispondenza di una stringa. Ti consente anche di cambiare liberamente il nome, senza preoccuparti delle chiavi esterne memorizzate in altre tabelle (l'ID rimane lo stesso, quindi non devi fare nulla).


Puoi davvero portare questo design abbastanza lontano, ed è tutta una questione di capire cosa vuoi essere in grado di archiviarvi.

Ad esempio, anziché avere un solo regista per film, alcuni film hanno più registi ... quindi ci sarebbe una relazione molti-a-molti tra film e registi, quindi avresti bisogno di un tavolo con ad esempio:

films_directors => **filmid, directorid**

Facendo un passo avanti, a volte i registi sono anche attori e viceversa. Quindi, piuttosto che avere anche tabelle regista e attore, potresti avere una tabella per una sola persona e unirti a quella tabella usando una tabella dei ruoli. La tabella dei ruoli avrebbe varie posizioni - ad es. Regista, produttore, star, extra, grip, editore .. e sarebbe più simile a:

films => **filmid**, title, otherstuff...
people => **personid**, name, ....
roles => **roleid**, role name, ....
film_people => **filmid, personid, roleid**
genre => **genreid**, name, ...
film_genre => **genreid, filmid**

Potresti anche avere un campo role_details nella tabella film_people, che potrebbe contenere informazioni aggiuntive a seconda del ruolo (ad esempio, il nome della parte che l'attore interpreta).

Sto anche mostrando il genere come molti < > molte relazioni, perché forse un film è in più generi. Se non lo volevi, allora invece della tabella film_genre, i film conterrebbero solo un genere.

Una volta impostato, è facile interrogare e trovare tutto ciò che una determinata persona ha fatto, o tutto ciò che una persona ha fatto come regista, o chiunque abbia mai diretto un film o tutte le persone coinvolte in uno specifico film .. Può andare avanti all'infinito.

Altri suggerimenti

Quello che segue non è il vero codice MySQL. Sembra che ciò di cui hai bisogno sia più di un inizio concettuale qui. Quindi ecco un modello di come dovrebbe essere il tuo database.

Tabella degli attori

  • id (chiave primaria)
  • nome
  • cognome
  • ecc. (eventuali colonne aggiuntive che desideri memorizzare su un attore)

Tabella Director

  • id
  • nome
  • cognome
  • ecc.

Tabella dei generi

  • id
  • nome
  • ecc.

Tavolo da film

  • id
  • titolo
  • Descrizione
  • tempo di esecuzione
  • data di uscita
  • ID regista: questa è una chiave esterna che fa riferimento all'ID (la chiave primaria) del regista che ha diretto il film
  • ID genere - come l'id regista, si riferisce all'ID del genere a cui appartiene il film

Tabella indice attori-film

  • ID film - questa è una chiave esterna che si riferisce all'ID del film
  • ID attore: questa è una chiave esterna che fa riferimento all'ID di un attore nel film.

Per ogni attore del film, aggiungi una riga all'indice attore-film. Quindi, se gli attori 5 e 13 (le chiavi primarie per quegli attori) recitassero nel film 4 (di nuovo, la chiave primaria per quel film), avresti due file che riflettono quel fatto nel tuo indice: Uno con id film = 4, e attore id = 5 e un altro con id film = 4 e attore id = 13.

Spero che sia d'aiuto.

Inoltre, questo presuppone che ogni film abbia esattamente un regista. Se un film della tua biblioteca ha due registi (come Slumdog Millionaire), vorresti separare l'ID regista dal tavolo del film e creare un indice del regista-film come l'Actor-Film Index come sopra.

Queste sono le tabelle che userei:

films (_id_, title, runningtime, description)
genres (_id_, name)
people (_id_, name, birthdate, etc...)
roles (_roleid_, rolename)
filmgenres (_filmid_, _genreid_)
castandcrew (_filmid_, _roleid_, _personid_)

Invece di avere un tavolo di registi e attori, basta avere un tavolo di persone. Questo può includere anche membri dell'equipaggio (nel caso in cui si desideri tenere traccia di chi fosse il 2 ° Assistente Junior Dolly Grip). Ogni film può essere un numero qualsiasi di generi (commedia e horror, per esempio). Inoltre, le persone possono assumere qualsiasi numero di ruoli in ogni film - ci sono un certo numero di attori / registi là fuori.

La tabella dei ruoli non significa necessariamente il personaggio che interpreta l'attore, ma potrebbe. Potrebbe essere & Quot; Director & Quot ;, & Quot; Produttore & Quot ;, & Quot; Attore & Quot; ... o anche & Quot; Luke Skywalker " se volessi ottenere quel grana fine ... credo che IMDB lo faccia.

Si spera che i nomi dei campi sopra dovrebbero suggerire le chiavi esterne e ho messo _underscores_ attorno alle chiavi primarie che userei.

La tua tabella Films necessita anche di collegamenti alle tabelle di genere, regista e attori. Dato che gli attori, almeno saranno molti a molti (un film elencherà più di un attore, un attore sarà in più di un film), avrai bisogno di un tavolo per collegarli.

Films Table => filmid, filmtitle, runningtime, description, genreid, directorid
Genre Table => genreid, genre
Director Table => directorid, director
Actors Table => actorid,actor_name
FilmActor link table => actorid, filmid (with a record linking each actor to each film)

Qualsiasi tabella che potrebbe essere da molte a molte ha bisogno di una tabella di collegamento.

  

Ho creato un ID univoco per la tabella dei film con una chiave primaria che si incrementa automaticamente, devo creare un ID univoco per ogni tabella?

Sì, ogni tabella deve avere un ID univoco. Ma questa non è necessariamente la chiave di incremento automatico principale: è ciò che rende unica quella particolare istanza. Ad esempio, per i film, penso che sia comune essere il titolo + anno di uscita, anche se si dovrebbe verificare con un appassionato di film (un esperto di dominio) per esserne certi. L'incremento automatico è un fallback - fondamentalmente, quando davvero non hai nient'altro su cui unirti.

È possibile utilizzare un tasto di incremento automatico per facilitare l'utilizzo nei join e simili, ma si dovrebbe comunque avere un vincolo univoco sui campi di unicità.

Per quanto riguarda il design attuale, suggerirei qualcosa del tipo:

Films => Primary Key(filmid), Unique Constraint(filmtitle, year), 
         runningtime, description, 
         Foreign Key(Genre), Foreign Key(DirectorId)

Genre Table => Primary Key(Genre)

Director Table => Primary Key(DirectorId), DirectorName

Actors Table => Primary Key(ActorId), ActorName

Films_Actors => Primary Key(Foreign Key(ActorId), Foreign Key(FilmId))

Per l'inserto, beh - francamente, è un PITA. Devi inserire in ordine inverso (ed è qui che le chiavi di incremento automatico possono essere una PITA ancora più grande - se puoi aggiungere la data di nascita o qualcosa nella tabella degli attori e dei registi, allora un vincolo unico può renderlo più semplice).

Quindi, inseriresti gli attori, i registi, i film e poi gli attori cinematografici. Idealmente, tutto in un'unica transazione. Inoltre, suppongo che il genere sia già compilato ed sia un elenco selezionato, quindi non è necessario inserirlo.

Puoi scaricare lo schema Imdb qui .

Mi rendo conto che la tua domanda ha già ricevuto risposta, tuttavia volevo indicarti:
  http://www.imdb.com/interfaces

IMDB fornisce file di testo semplice del loro database (meno le chiavi primarie). Potresti trovare questo utile per popolare il tuo database una volta iniziato, oppure potresti usarlo nel tuo programma / sito web per permetterti semplicemente di cercare un titolo di film da aggiungere al tuo & Quot; Collezione di DVD & Quot; e ottenere il resto delle informazioni da questi.

A volte gli attori sono registi e viceversa, forse vuoi un " people " tavolo?

Non hai davvero bisogno di una YearTable e tutto ciò di cui hai bisogno sono le colonne genre_id, director_id e actor_id nella tabella dei film.

Inoltre, le tabelle di genere, regista e attore necessitano di ID univoci.

Modifica: Questo, ovviamente, presuppone che avrai solo 1 genere, regista, e attore per ogni film. Il che probabilmente non è il caso.

Per avere molti attori appartenenti a molti film, avrai bisogno di una tabella delle relazioni separata. Potresti chiamarlo & Quot; moviesActors & Quot; (o attoriMovies) e ogni riga avrà un attore_id e un movie_id per dire questo attore era in questo film .

Ogni tabella dovrebbe avere una chiave primaria unica.

Dovresti leggere su normalizzazione del database .

Probabilmente una tabella annuale non è necessaria.

Se è l'anno di uscita, diciamo, allora l'anno può essere memorizzato nel film.

Se ci sono più registi in un film, allora avresti un tavolo separato che conterrebbe la chiave primaria del tavolo del film e del tavolo del regista. Allo stesso modo per uno qualsiasi dei vincoli di chiave esterna che sono molti-a-uno o molti-a-molti. In particolare, credo che ciò si applicherebbe all'Attore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top