Pregunta

Estoy tratando de entender estas cosas alucinantes que llaman Diseño de bases de datos sin mucho éxito, así que intentaré ilustrar mi problema con un ejemplo.

Estoy usando MySQL y aquí está mi pregunta:

Digamos que quiero crear una base de datos para guardar mi colección de DVD. Tengo la siguiente información que quiero incluir:

  1. Título de la película
  2. Actores
  3. Tiempo de ejecución
  4. Género
  5. Descripción
  6. Año
  7. Director

Me gustaría crear relaciones entre estos para hacerlo más eficiente, pero no sé cómo.

Esto es lo que estoy pensando para el diseño de la base de datos:

Tabla de películas = > filmid, filmtitle, runningtime, descripción

Tabla de años = > año

Tabla de géneros = > género

Director Table = > director

Tabla de actores = > actor_name

Pero, ¿cómo haría para crear relaciones entre estas tablas?

Además, he creado una ID única para la tabla de películas con una clave principal que se incrementa automáticamente, ¿necesito crear una ID única para cada tabla?

Y finalmente, si tuviera que actualizar una nueva película en la base de datos a través de un formulario PHP, ¿cómo insertaría todos estos datos en (con las relaciones y todo?)

gracias por cualquier ayuda que pueda dar, Keith

¿Fue útil?

Solución

Debe hacer una distinción entre atributos y entidades. Una entidad es una cosa, generalmente un sustantivo. Un atributo es más como una pieza de información descriptiva. En la jerga de la base de datos, entity = table, attribute = field / column.

Tener una tabla separada para ciertas cosas, usemos director, como ejemplo, se llama normalización. Si bien puede ser bueno en algunas circunstancias, puede ser innecesario en otras (ya que generalmente hace que las consultas sean más complicadas, debe unir todo, y es más lento).

En este caso, tener una tabla de años es innecesario, ya que no hay otros atributos sobre un año, además del año en sí, que almacenaría. Es mejor desnormalizar esto y almacenar el año en la tabla de películas.

Director, por otro lado, es diferente. Quizás desee almacenar el nombre, el apellido, la fecha de nacimiento, la fecha de fallecimiento (si corresponde) del director, etc. Obviamente no desea ingresar la fecha de nacimiento del director cada vez que ingresa una película que esta persona dirige, por lo que tiene sentido tener una entidad separada para un director.

Incluso si no quisieras almacenar toda esta información sobre el director (solo quieres su nombre), tener una tabla separada para él (y usar una clave sustituta, lo abordaré en un segundo) es útil porque evita errores tipográficos y duplicados: si tiene el nombre de alguien mal escrito o ingresado de manera diferente (primero, último vs último, primero), entonces si intenta encontrar otras películas que haya dirigido, fallará.

Usar una clave sustituta (clave primaria) para tablas es generalmente una buena idea. Hacer coincidir un número entero es mucho más rápido que hacer coincidir una cadena. También le permite cambiar libremente el nombre, sin preocuparse por las claves externas almacenadas en otras tablas (la ID permanece igual, por lo que no tiene que hacer nada).


Realmente puedes llevar este diseño bastante lejos, y todo es cuestión de averiguar qué quieres poder almacenar en él.

Por ejemplo, en lugar de tener un solo director por película, algunas películas tienen múltiples directores ... por lo que habría una relación de muchos a muchos entre películas y directores, por lo que necesitaría una tabla con, por ejemplo:

films_directors => **filmid, directorid**

Yendo un paso más allá, a veces los directores también son actores, y viceversa. Entonces, en lugar de tener tablas de director y actor, podría tener una tabla de una sola persona y unirse a esa tabla utilizando una tabla de roles. La tabla de roles ocuparía varios puestos, por ejemplo, director, productor, estrella, extra, grip, editor ... y se parecería más a:

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

También puede tener un campo role_details en la tabla film_people, que podría contener información adicional dependiendo del rol (por ejemplo, el nombre del papel que interpreta el actor).

También estoy mostrando el género como muchas < > muchas relaciones, porque es posible que una película esté en múltiples géneros. Si no quería esto, entonces, en lugar de la tabla film_genre, las películas solo contendrían un genreid.

Una vez configurado, es fácil consultar y encontrar todo lo que una persona ha hecho, o todo lo que una persona ha hecho como director, o todos los que alguna vez han dirigido una película, o todas las personas involucradas en una película .. Puede seguir y seguir.

Otros consejos

Lo que sigue no es el código MySQL real. Parece que lo que necesita es más un comienzo conceptual aquí. Así que aquí hay un modelo de cómo debería verse su base de datos.

Tabla de actores

  • id (clave principal)
  • nombre
  • apellido
  • etc. (cualquier columna adicional que desee almacenar en un actor)

Mesa del director

  • id
  • nombre
  • apellido
  • etc.

Tabla de género

  • id
  • nombre
  • etc.

Mesa de cine

  • id
  • título
  • descripción
  • tiempo de ejecución
  • fecha de lanzamiento
  • identificación del director: esta es una clave externa que se refiere a la identificación (la clave principal) del director que dirigió la película
  • identificación de género: como la identificación del director, se refiere a la identificación del género al que pertenece la película

Tabla de índice de actor-película

  • ID de película: esta es una clave externa que se refiere a la ID de la película
  • identificación del actor: esta es una clave externa que se refiere a la identificación de un actor en la película.

Para cada actor en la película, agregaría una fila al índice de actor-película. Entonces, si los actores 5 y 13 (las claves principales para esos actores) protagonizaron la película 4 (nuevamente, la clave principal para esa película), tendrías dos filas que reflejan ese hecho en tu índice: una con id de película = 4, y actor id = 5, y otro con film id = 4, y actor id = 13.

Espero que eso ayude.

Además, esto supone que cada película tiene exactamente un director. Si alguna película en su biblioteca tiene dos directores (como Slumdog Millionaire), desearía separar la identificación del director de la tabla de películas y crear un índice de Director-Película como el Índice de actor-película como se indicó anteriormente.

Estas son las tablas que usaría:

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

En lugar de tener una mesa de directores y actores, solo tenga una mesa de personas. Esto también puede incluir miembros de la tripulación (en caso de que desee rastrear quién fue la 2da. Asistente Junior Dolly Grip) Cada película puede tener cualquier cantidad de géneros (comedia y terror, por ejemplo). Además, la gente puede asumir cualquier número de papeles en cada película: hay una gran cantidad de actores / directores por ahí.

La tabla Roles no significa necesariamente el personaje que interpreta el actor, pero podría. Podría ser & "; Director &"; & "; Productor &"; & "; Actor &"; ... o incluso & "; Luke Skywalker " si quisieras obtener ese grano fino ... creo que IMDB hace eso.

Con suerte, los nombres de los campos anteriores deberían insinuar las claves foráneas, y puse _underscores_ alrededor de las claves principales que usaría.

Su tabla de películas también necesita enlaces a las tablas de género, director y actores. Como los actores, al menos serán muchos o muchos (una película incluirá más de un actor, un actor estará en más de una película), necesitará una tabla para vincularlos.

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)

Cualquier tabla que pueda ser de muchos a muchos necesita una tabla de enlace.

  

He creado una ID única para la tabla de películas con una clave principal que se incrementa automáticamente, ¿necesito crear una ID única para cada tabla?

Sí, cada tabla debe tener una identificación única. Pero, esa no es necesariamente la clave principal de incremento automático: es lo que hace que esa instancia en particular sea única. Por ejemplo, para las películas, creo que es común ser título + año de lanzamiento, aunque querrás consultar con un aficionado al cine (un experto en el dominio) para estar seguro de eso. El incremento automático es un retroceso, básicamente, cuando realmente no tienes nada más en lo que unificarte.

Puede usar una tecla de incremento automático para facilitar su uso en uniones y demás, pero de todos modos debe tener una restricción única en los campos de unicidad.

En cuanto al diseño real, sugeriría algo como:

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))

Para el inserto, bueno, francamente, es un PITA. Debe insertar en orden inverso (y aquí es donde las teclas de incremento automático pueden ser una PITA aún más grande; si puede agregar la fecha de nacimiento o algo así en la tabla de Actores y Directores, entonces una restricción única puede facilitarlo).

Entonces, insertarías Actor (es), Director, Película y luego Films_Actors. Idealmente, todo en una sola transacción. Además, supongo que Genre ya está completado y es una lista de selección, por lo que no es necesario insertarlo.

Puede descargar el esquema Imdb aquí .

Me doy cuenta de que su pregunta ya ha sido respondida, sin embargo, quería señalarle:
  http://www.imdb.com/interfaces

IMDB proporciona archivos de texto plano de su base de datos (menos claves principales). Puede encontrar esto útil para llenar su base de datos una vez que comience, o puede usarlo en su programa / sitio web para permitirle simplemente buscar un título de película para agregar a su & Quot; DVD Collection & Quot; y obtener el resto de la información de estos.

A veces los actores son directores y viceversa, tal vez quieras un " people " mesa?

Realmente no necesitas una YearTable, y todo lo que necesitas es una columna genre_id, director_id y actor_id en tu tabla de películas.

Además, las tablas de género, director y actor necesitan sus propios ID únicos.

Editar: Esto, por supuesto, supone que solo tendrá 1 género, director, y actor para cada película. Lo que probablemente no sea el caso.

Para tener muchos actores pertenecientes a muchas películas, necesitará una tabla de relaciones separada. Podrías llamarlo & Quot; moviesActors & Quot; (o actoresMovies) y cada fila tendrá un actor_id y un movie_id para decir que este actor estaba en esta película .

Cada tabla debe tener una clave primaria que sea única.

Debería leer en normalización de la base de datos .

Una tabla de años probablemente sea innecesaria.

Si es el año de lanzamiento, digamos, entonces el año se puede almacenar en la película.

Si hay varios directores en una película, entonces tendría una tabla separada que contendría la clave principal de la tabla de películas y la tabla de directores. De manera similar para cualquiera de las restricciones de clave externa que son muchos a uno o muchos a muchos. En particular, creo que esto se aplicaría al actor.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top