User Tools

Site Tools


es:web_development:databases:joins

Desarrollo Web Lección 7 - Bases de Datos

Uniones

Objetivo

En esta actividad, usará datos de dos tablas y aprenderá por qué es una buena idea separar los datos en varias tablas.

Preparación

  • Usaremos PHPMyAdmin nuevamente para ejecutar nuestras consultas, así que inicie sesión y abra la base de datos para su clase.

Valor Nulo

  • Imagina que queremos ampliar nuestra base de datos de héroes de Marvel para incluir las películas en las que aparecen.
  • Una forma de hacer esto sería agregar campos (columnas) para cada película como esta.
character_name hero_villain first_appeared power iron_man first_avenger thor avengers
Black Widow Hero 1964 Skill NULL NULL NULL True
Captain America Hero 1941 Biological NULL True NULL True
Hulk Hero 1962 Biological NULL NULL NULL True
Iron Man Hero 1963 Technology True NULL NULL True
Loki Villain 1949 Magic NULL NULL True True
Scarlet Witch Hero 1964 Magic NULL NULL NULL NULL
  • NULL significa 'sin información' y leeríamos esto como 'falso' cuando interpretamos los resultados.

Tablas Múltiples

  • Ahora considere si agregamos una columna para las 27 películas lanzadas hasta ahora en la MCU, sin mencionar las 4 series de televisión. Nuestra mesa sería enorme y la mayor parte estaría vacía (NULL).
  • Eso llevaría más tiempo de administrar, ralentizaría nuestras consultas y ocuparía más espacio en nuestro servidor. Ninguno de estos son buenos resultados, pero ¿qué podemos hacer al respecto?
  • Podríamos hacer que cada combinación de héroe y película tenga su propia fila de datos, como esta.
character_name hero_villain first_appeared power movie
Black Widow Hero 1964 Skill Iron Man
Black Widow Hero 1964 Skill Avengers
Captain America Hero 1941 Biological First Avenger
Captain America Hero 1941 Biological Avengers
Hulk Hero 1962 Bilogical Avengers
Iron Man Hero 1963 Technology Iron Man
Iron Man Hero 1963 Technology Avengers
Loki Villain 1949 Magic Avengers
  • Esto se ve mucho mejor. Ocupa menos espacio y sería más rápido, pero aún tiene problemas.
  • La primera es que se repiten muchos datos. Mira como tenemos la información de Black Widow (hero_villain, first_appeared y power) dos veces. Si queremos actualizar esos datos, tendríamos que actualizar cada fila con Black Widow. Eso ralentizará las cosas y podría conducir a errores.
  • La segunda es más sutil. ¿Notaste que nos falta la Bruja Escarlata? Podríamos incluir una fila para ella sin datos de la película, pero ¿cómo nos las arreglaríamos más tarde cuando agregáramos Age of Ultron? ¿Dejaríamos una fila NULL ocupando espacio en la base de datos sin ningún propósito? Podríamos buscar filas NULL y reemplazarlas cuando agreguemos la primera película, pero no es lo ideal.
  • La respuesta es separar los datos en dos tablas. Uno con información sobre el héroe y otro rastreando en qué películas han estado.
  • Ya has visto el primero.
  • Echemos un vistazo a la segunda. Haga clic en la tabla llamada 'apariencias' en el panel izquierdo de PHPMyAdmin.
  • Aquí vemos una tabla con una lista de pares héroe/película.

Índice único

  • Recuerde que cada tabla debe tener un índice único. Pero en esta lista, Iron Man y Loki aparecen más de una vez en 'character_name' y 'The Avengers' aparece cinco veces en 'movie', por lo que ninguno es apropiado para nuestro índice principal.
  • En su lugar, creamos un nuevo campo que será único. Por costumbre, lo llamamos 'id'.
  • Haga clic en la pestaña 'Estructura' para ver cómo se define.
  • Es un número entero con el atributo 'sin signo'. Esto significa que solo pueden ser números positivos. En computación, donde los números se almacenan como una colección de unos y ceros, cada uno llamado 'bit', generalmente se usa un bit para indicar si un número es positivo o negativo. Al hacer que nuestro índice no esté firmado, estamos duplicando el número de filas que podemos tener.
  • Observe también en 'Extra' que el campo 'id' está configurado en 'AUTO_INCREMENT', lo que significa que cuando agregamos filas, la nueva fila tendrá un número uno más alto que el número más alto utilizado anteriormente. Esto nos evita tener que encontrar un número no utilizado nosotros mismos.
  • Entonces, ¿cómo combinamos los datos de estas tablas?

Uniones

  • Haga clic en la pestaña 'SQL'.
  • Sobrescriba la consulta con esta. Puede mantenerlo todo en una sola línea, pero extenderlo hace que sea más fácil de leer.
SELECT *
FROM heroes
    LEFT JOIN appearances ON heroes.character_name=appearances.character_name
  • Los resultados ahora muestran toda la información que teníamos en nuestra tabla más reciente.
  • La ventaja aquí es que solo necesitamos actualizar una línea en nuestra tabla de héroes para cada héroe, por lo que hay mucho menos riesgo de error y ocupamos menos espacio de almacenamiento. También es más rápido de procesar, pero eso probablemente no se note para una base de datos tan pequeña.
  • Desglosemos la consulta.
  • SELECT * es el mismo que antes. Dice mostrar todos los campos. En este caso, muestre todos los campos de todas las tablas incluidas en la consulta.
  • FROM heroes es lo mismo que antes, aunque he omitido los acentos graves. Los acentos graves no son necesarios en la mayoría de los casos.
  • La última línea es nueva. LEFT JOIN significa que estamos conectando todas las filas de la segunda tabla que coinciden con la primera tabla, y estamos usando el campo 'character_name' de ambas tablas para identificar la coincidencia (heroes.character_name=appearances.character_name).
  • Observe que identificamos los campos a usar nombrando primero la base de datos y separándolos por un .. Esto asegura que la base de datos no se confunda porque los nombres de los campos son los mismos en ambas tablas.
  • Observe también que Scarlet Witch aparece en los resultados porque está en la primera tabla, aunque no aparece en la segunda tabla. La información que falta aparece como NULL. Veamos qué pasa si cambiamos las mesas.
  • Podríamos intercambiar los nombres de las tablas en la consulta FROM appearances LEFT JOIN heroes ON heroes.character_name=appearances.character_name, pero también podemos simplemente cambiar el tipo de unión de LEFT a RIGHT.
SELECT *
FROM heroes
	RIGHT JOIN appearances ON heroes.character_name=appearances.character_name
  • Cuando ejecuta esta consulta, Scarlet Witch desaparece porque la segunda tabla (apariencias) es nuestra base y ella no aparece en esa tabla.
  • Volvamos a la consulta original para que podamos ver a Scarlet Witch.
SELECT *
FROM heroes
	LEFT JOIN appearances ON heroes.character_name=appearances.character_name
  • Antes de continuar, observe que tenemos información innecesaria en nuestros resultados. La base de datos requiere 'id', pero por ahora no tiene ningún valor para nosotros. Tampoco tiene ningún valor repetir los datos de 'character_name'.
  • Tomemos solo los campos que realmente necesitamos.
SELECT character_name, hero_villain, first_appeared, power, movie
FROM heroes
	LEFT JOIN appearances ON heroes.character_name=appearances.character_name
  • Observe que hemos reemplazado * con la lista de campos específicos que queremos incluir.
  • Desafortunadamente, cuando ejecuta la consulta, verá un error que dice que la columna 'character_name' es ambigua. Aunque son exactamente iguales en ambas tablas, la base de datos necesita saber cuál elegir.
SELECT heroes.character_name, hero_villain, first_appeared, power, movie
FROM heroes
	LEFT JOIN appearances ON heroes.character_name=appearances.character_name
  • Esta consulta debería darnos exactamente lo que queremos.

Siguiente: Conexiones de Base de Datos PHP

es/web_development/databases/joins.txt · Last modified: 2023/08/16 09:33 (external edit)