Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Tools & Tips

Bases de datos relacionales para principiantes

by
Read Time:16 minsLanguages:

Spanish (Español) translation by Ruben Solis (you can also view the original English article)

Las aplicaciones web se pueden dividir en dos componentes principales: un front-end que muestra y recopila información y un back-end para almacenar la información. En este artículo, voy a mostrar qué es una base de datos relacional, y cómo diseñar correctamente tu base de datos para almacenar la información de tu aplicación.

Una base de datos almacena datos de forma organizada para que se puedan buscar y recuperar más tarde. Debe contener una o más tablas. Una tabla se parece mucho a una hoja de cálculo, ya que está formada por filas y columnas. Todas las filas tienen las mismas columnas y cada columna contiene los datos en sí. Si te ayuda, piensa en tus tablas de la misma manera que lo harías con una tabla en Excel.

Fig. 1

Los datos pueden ser inserted (insertados), retrieved (recuperados), updated (actualizados) y deleted (eliminados) de una tabla. La palabra, created (creado), se usa generalmente en lugar de inserted (insertado), por lo que, colectivamente, estas cuatro funciones se abrevian cariñosamente como CRUD.

Una base de datos relacional es un tipo de base de datos que organiza los datos en tablas y los vincula según relaciones definidas. Estas relaciones te permiten recuperar y combinar datos de una o más tablas con una sola consulta.

Pero eso fue solo un montón de palabras. Para comprender realmente una base de datos relacional, debes crear una por ti mismo. Comencemos obteniendo algunos datos reales con los que podamos trabajar.


Paso 1: Obtener algunos datos

Siguiendo el espíritu de los artículos de Nettuts+ sobre un clon de Twitter (PHP, Ruby on Rails, Django), obtengamos algunos datos de Twitter. Busqué en Twitter "#databases" y tomé la siguiente muestra de diez tweets:

Tabla 1

full_name username text created_at following_username
"Boris Hadjur" "_DreamLead" "What do you think about #emailing #campaigns #traffic in #USA? Is it a good market nowadays? do you have #databases?" "Tue, 12 Feb 2013 08:43:09 +0000" "Scootmedia", "MetiersInternet"
"Gunnar Svalander" "GunnarSvalander" "Bill Gates Talks Databases, Free Software on Reddit https://t.co/ShX4hZlA #billgates #databases" "Tue, 12 Feb 2013 07:31:06 +0000" "klout", "zillow"
"GE Software" "GEsoftware" "RT @KirkDBorne: Readings in #Databases: excellent reading list, many categories: http://t.co/S6RBUNxq via @rxin Fascinating." "Tue, 12 Feb 2013 07:30:24 +0000" "DayJobDoc", "byosko"
"Adrian Burch" "adrianburch" "RT @tisakovich: @NimbusData at the @Barclays Big Data conference in San Francisco today, talking #virtualization, #databases, and #flash memory." "Tue, 12 Feb 2013 06:58:22 +0000" "CindyCrawford", "Arjantim"
"Andy Ryder" "AndyRyder5" "http://t.co/D3KOJIvF article about Madden 2013 using AI to prodict the super bowl #databases #bus311" "Tue, 12 Feb 2013 05:29:41 +0000" "MichaelDell", "Yahoo"
"Andy Ryder" "AndyRyder5" "http://t.co/rBhBXjma an article about privacy settings and facebook #databases #bus311" "Tue, 12 Feb 2013 05:24:17 +0000" "MichaelDell", "Yahoo"
"Brett Englebert" "Brett_Englebert" "#BUS311 University of Minnesota's NCFPD is creating #databases to prevent "food fraud." http://t.co/0LsAbKqJ" "Tue, 12 Feb 2013 01:49:19 +0000" "RealSkipBayless", "stephenasmith"
Brett Englebert "Brett_Englebert" "#BUS311 companies might be protecting their production #databases, but what about their backup files? http://t.co/okJjV3Bm" "Tue, 12 Feb 2013 01:31:52 +0000" "RealSkipBayless", "stephenasmith"
"Nimbus Data Systems" "NimbusData" "@NimbusData CEO @tisakovich @BarclaysOnline Big Data conference in San Francisco today, talking #virtualization, #databases,& #flash memory" "Mon, 11 Feb 2013 23:15:05 +0000" "dellock6", "rohitkilam"
"SSWUG.ORG" "SSWUGorg" "Don't forget to sign up for our FREE expo this Friday: #Databases, #BI, and #Sharepoint: What You Need to Know! http://t.co/Ijrqrz29" "Mon, 11 Feb 2013 22:15:37 +0000" "drsql", "steam_games"

Esto es lo que significa cada nombre de columna:

MySQL se utiliza en casi todas las empresas de internet de las que has oído hablar.

  • full_name: el nombre completo del usuario
  • username: el usuario de Twitter
  • text: el tweet en sí
  • created_at: el timestamp del tweet
  • following_username: una lista de personas que sigue este usuario, separadas por comas. Para ser breve, limité la longitud de la lista a dos

Todos estos son datos reales; puedes buscar en Twitter y encontrar estos tweets.

Esto es bueno. Todos los datos están en un solo lugar; así que son fáciles de encontrar, ¿verdad? No exactamente. Hay un par de problemas con esta tabla. Primero, hay datos repetitivos en las columnas. Las columnas "username" y "following_username" son repetitivas, porque ambas contienen el mismo tipo de datos — usuarios de Twitter. Hay otra forma de repetición dentro de la columna "following_username". Los campos solo deben contener un valor, pero cada uno de los campos "following_username" contiene dos.

En segundo lugar, hay datos repetitivos en las filas.

@ AndyRyder5 y @Brett_Englebert tuitearon dos veces cada uno, por lo que el resto de su información se ha duplicado.

Los duplicados son problemáticos porque dificultan las operaciones CRUD. Por ejemplo, tomaría más tiempo recuperar los datos porque se perdería tiempo revisando filas duplicadas. Además, la actualización de datos sería un problema; si un usuario cambia su nombre de usuario de Twitter, necesitaríamos encontrar todos los duplicados y actualizarlos.

Los datos repetitivos son un problema. Podemos solucionar este problema dividiendo la Tabla 1 en tablas separadas. Procedamos primero a resolver el problema de la repetición entre columnas.


Paso 2: Eliminar los datos repetitivos en las columnas

Como se indicó anteriormente, las columnas "username" y "following_username" en la Tabla 1 son repetitivas. Esta repetición ocurrió porque estaba tratando de expresar la relación de follow (seguimiento) entre usuarios. Mejoremos el diseño de la Tabla 1 dividiéndola en dos tablas: una solo para las relaciones de following (seguimiento) y otra para el resto de la información.

Fig. 2

Dado que @Brett_Englebert sigue a @RealSkipBayless, la tabla following expresará esa relación almacenando @Brett_Englebert como "from_user" y @RealSkipBayless como "to_user". Sigamos adelante y dividamos la Tabla 1 en estas dos tablas:

Tabla 2: La tabla following

from_user to_user
_DreamLead Scootmedia
_DreamLead MetiersInternet
GunnarSvalander klout
GunnarSvalander zillow
GEsoftware DayJobDoc
GEsoftware byosko
adrianburch CindyCrawford
adrianburch Arjantim
AndyRyder MichaelDell
AndyRyder Yahoo
Brett_Englebert RealSkipBayless
Brett_Englebert stephenasmith
NimbusData dellock6
NimbusData rohitkilam
SSWUGorg drsql
SSWUGorg steam_games

Tabla 3: La tabla users (usuarios)

full_name username text created_at
"Boris Hadjur" "_DreamLead" "What do you think about #emailing #campaigns #traffic in #USA? Is it a good market nowadays? do you have #databases?" "Tue, 12 Feb 2013 08:43:09 +0000"
"Gunnar Svalander" "GunnarSvalander" "Bill Gates Talks Databases, Free Software on Reddit http://t.co/ShX4hZlA #billgates #databases" "Tue, 12 Feb 2013 07:31:06 +0000"
"GE Software" "GEsoftware" "RT @KirkDBorne: Readings in #Databases: excellent reading list, many categories: http://t.co/S6RBUNxq via @rxin Fascinating." "Tue, 12 Feb 2013 07:30:24 +0000"
"Adrian Burch" "adrianburch" "RT @tisakovich: @NimbusData at the @Barclays Big Data conference in San Francisco today, talking #virtualization, #databases, and #flash memory." "Tue, 12 Feb 2013 06:58:22 +0000"
"Andy Ryder" "AndyRyder5" "http://t.co/D3KOJIvF article about Madden 2013 using AI to prodict the super bowl #databases #bus311" "Tue, 12 Feb 2013 05:29:41 +0000"
"Andy Ryder" "AndyRyder5" "http://t.co/rBhBXjma an article about privacy settings and facebook #databases #bus311" "Tue, 12 Feb 2013 05:24:17 +0000"
"Brett Englebert" "Brett_Englebert" "#BUS311 University of Minnesota's NCFPD is creating #databases to prevent "food fraud." http://t.co/0LsAbKqJ" "Tue, 12 Feb 2013 01:49:19 +0000"
Brett Englebert "Brett_Englebert" "#BUS311 companies might be protecting their production #databases, but what about their backup files? http://t.co/okJjV3Bm" "Tue, 12 Feb 2013 01:31:52 +0000"
"Nimbus Data Systems" "NimbusData" "@NimbusData CEO @tisakovich @BarclaysOnline Big Data conference in San Francisco today, talking #virtualization, #databases,& #flash memory" "Mon, 11 Feb 2013 23:15:05 +0000"
"SSWUG.ORG" "SSWUGorg" "Don't forget to sign up for our FREE expo this Friday: #Databases, #BI, and #Sharepoint: What You Need to Know! http://t.co/Ijrqrz29" "Mon, 11 Feb 2013 22:15:37 +0000"

Esto se ve mejor. Ahora, en la tabla users (Tabla 3), solo hay una columna con usuarios de Twitter. En la tabla following (Tabla 2), solo hay un usuario de Twitter por campo en la columna "to_user".

Edgar F. Codd, el científico de la computación que sentó las bases teóricas de las bases de datos relacionales, llamó a este paso de eliminar datos repetitivos en las columnas la primera forma normal (1FN).


Paso 3: Eliminar datos repetitivos en filas

Ahora que hemos arreglado las repeticiones en las columnas, necesitamos corregir las repeticiones en las filas. Dado que los usuarios @AndyRyder5 y @Brett_Englebert tuitearon dos veces cada uno, su información se duplica en la tabla users (Tabla 3). Esto indica que necesitamos sacar los tweets y colocarlos en su propia tabla.

Fig. 3

Como antes, "text" almacena el tweet en sí. Dado que la columna "created_at" almacena el timestamp del tweet, tiene sentido incluirlo también en esta tabla. También incluyo una referencia a la columna "username" para que sepamos quién publicó el tweet. Aquí está el resultado de colocar los tweets en su propia tabla:

Tabla 4: La tabla tweets

text created_at username
"What do you think about #emailing #campaigns #traffic in #USA? Is it a good market nowadays? do you have #databases?" "Tue, 12 Feb 2013 08:43:09 +0000" "_DreamLead"
"Bill Gates Talks Databases, Free Software on Reddit http://t.co/ShX4hZlA #billgates #databases" "Tue, 12 Feb 2013 07:31:06 +0000" "GunnarSvalander"
"RT @KirkDBorne: Readings in #Databases: excellent reading list, many categories: http://t.co/S6RBUNxq via @rxin Fascinating." "Tue, 12 Feb 2013 07:30:24 +0000" "GEsoftware"
"RT @tisakovich: @NimbusData at the @Barclays Big Data conference in San Francisco today, talking #virtualization, #databases, and #flash memory." "Tue, 12 Feb 2013 06:58:22 +0000" "adrianburch"
"http://t.co/D3KOJIvF article about Madden 2013 using AI to prodict the super bowl #databases #bus311" "Tue, 12 Feb 2013 05:29:41 +0000" "AndyRyder5"
"http://t.co/rBhBXjma an article about privacy settings and facebook #databases #bus311" "Tue, 12 Feb 2013 05:24:17 +0000" "AndyRyder5"
"#BUS311 University of Minnesota's NCFPD is creating #databases to prevent "food fraud." http://t.co/0LsAbKqJ" "Tue, 12 Feb 2013 01:49:19 +0000" "Brett_Englebert"
"#BUS311 companies might be protecting their production #databases, but what about their backup files? http://t.co/okJjV3Bm" "Tue, 12 Feb 2013 01:31:52 +0000" "Brett_Englebert"
"@NimbusData CEO @tisakovich @BarclaysOnline Big Data conference in San Francisco today, talking #virtualization, #databases,& #flash memory" "Mon, 11 Feb 2013 23:15:05 +0000" "NimbusData"
"Don't forget to sign up for our FREE expo this Friday: #Databases, #BI, and #Sharepoint: What You Need to Know! http://t.co/Ijrqrz29" "Mon, 11 Feb 2013 22:15:37 +0000" SSWUGorg

Tabla 5: La tabla users

full_name username
"Boris Hadjur" "_DreamLead"
"Gunnar Svalander" "GunnarSvalander"
"GE Software" "GEsoftware"
"GEsoftware" "adrianburch"
"Andy Ryder" "AndyRyder5"
"Brett Englebert" "Brett_Englebert"
"Nimbus Data Systems" "NimbusData"
"SSWUG.ORG" "SSWUGorg"

Después de la división, la tabla users (Tabla 5) tiene filas únicas para los usuarios y sus usuarios de Twitter.

Edgar F. Codd llamó a este paso de eliminar datos repetitivos en filas como la segunda forma normal (2FN).


Paso 4: Vincular tablas con llaves

Los datos pueden ser insertados, recuperados, actualizados y eliminados de una tabla.

Hasta ahora, la Tabla 1 se ha dividido en tres nuevas tablas: following (Tabla 2), tweets (Tabla 4) y users (Tabla 5). Pero ¿de qué sirve esto? Se eliminaron los datos repetitivos, pero ahora los datos se distribuyen en tres tablas independientes. Para recuperar los datos, necesitamos establecer vínculos significativos entre las tablas. De esta manera podemos expresar consultas como, "qué ha twitteado un usuario y a quién está siguiendo".

La forma de dibujar vínculos entre tablas es primero darle a cada fila de una tabla un identificador único, denominado llave primaria, y luego hacer referencia a esa llave primaria en la otra tabla a la que deseas vincular.

De hecho, ya lo hemos hecho en users (Tabla 5) y tweets (Tabla 4). En users, la llave primaria es la columna "username" porque no hay dos usuarios que tengan el mismo usuario de Twitter. En tweets, hacemos referencia a esta llave en la columna "username" para saber quién twitteó qué. Dado que es una referencia, la columna "username" en tweets se llama llave foránea. De esta forma, la llave "username" vincula las tablas de users y tweets.

¿Es la columna "username" la mejor idea para una llave primaria para la tabla de users?

Por un lado, es una llave natural - tiene sentido buscar usando un usuario de Twitter en lugar de asignar a cada usuario una identificación numérica y buscar eso. Por otro lado, ¿qué pasa si un usuario quiere cambiar su nombre de usuario de Twitter? Eso podría causar errores si la llave primaria y todas las llaves foráneas de referencia no se actualizan con precisión, errores que podrían evitarse si se utiliza un ID numérico constante. En última instancia, la elección depende de tu sistema. Si desea darles a sus usuarios la posibilidad de cambiar su username, es mejor agregar una columna de "id" numérica autoincremental a los usuarios y usarla como llave primaria. De lo contrario, "username" debería funcionar bien. Seguiré usando "username" como clave principal para users

Pasemos a tweets (Tabla 4). Una llave primaria debe identificar de forma única cada fila, entonces, ¿cuál debería estar aquí la llave primaria? El campo "created_at" no funcionará porque si dos usuarios tuitean al mismo tiempo, sus tuits tendrían un timestamp idéntico. El "texto" tiene el mismo problema, ya que si dos usuarios tuitean "Hello world", no podríamos distinguir entre las filas. La columna "username" es la llave foránea que define el enlace con los users, así que no nos metamos con eso. Dado que las otras columnas no son buenas candidatas, aquí tiene sentido agregar una columna "id" numérica autoincremental y usarla como llave primaria.

Tabla 6: La tabla de tweets con una columna "id"

id text created_at username
1 "What do you think about #emailing #campaigns #traffic in #USA? Is it a good market nowadays? do you have #databases?" "Tue, 12 Feb 2013 08:43:09 +0000" "_DreamLead"
2 "Bill Gates Talks Databases, Free Software on Reddit http://t.co/ShX4hZlA #billgates #databases" "Tue, 12 Feb 2013 07:31:06 +0000" "GunnarSvalander"
3 "RT @KirkDBorne: Readings in #Databases: excellent reading list, many categories: http://t.co/S6RBUNxq via @rxin Fascinating." "Tue, 12 Feb 2013 07:30:24 +0000" "GEsoftware"
4 "RT @tisakovich: @NimbusData at the @Barclays Big Data conference in San Francisco today, talking #virtualization, #databases, and #flash memory." "Tue, 12 Feb 2013 06:58:22 +0000" "adrianburch"
5 "http://t.co/D3KOJIvF article about Madden 2013 using AI to prodict the super bowl #databases #bus311" "Tue, 12 Feb 2013 05:29:41 +0000" "AndyRyder5"
6 "http://t.co/rBhBXjma an article about privacy settings and facebook #databases #bus311" "Tue, 12 Feb 2013 05:24:17 +0000" "AndyRyder5"
7 "#BUS311 University of Minnesota's NCFPD is creating #databases to prevent "food fraud." http://t.co/0LsAbKqJ" "Tue, 12 Feb 2013 01:49:19 +0000" "Brett_Englebert"
8 "#BUS311 companies might be protecting their production #databases, but what about their backup files? http://t.co/okJjV3Bm" "Tue, 12 Feb 2013 01:31:52 +0000" "Brett_Englebert"
9 "@NimbusData CEO @tisakovich @BarclaysOnline Big Data conference in San Francisco today, talking #virtualization, #databases,& #flash memory" "Mon, 11 Feb 2013 23:15:05 +0000" "NimbusData"
10 "Don't forget to sign up for our FREE expo this Friday: #Databases, #BI, and #Sharepoint: What You Need to Know! http://t.co/Ijrqrz29" "Mon, 11 Feb 2013 22:15:37 +0000" "SSWUGorg"

Finalmente, agreguemos una llave primaria a la tabla following. En esta tabla, ni la columna "from_user" ni la columna "to_user" identifican de forma única cada fila por sí sola. Sin embargo, "from_user" y "to_user" juntos lo hacen, ya que representan una sola relación. Una llave primaria se puede definir en más de una columna, por lo que usaremos ambas columnas como llave primaria para la tabla following.

En cuanto a la llave foránea, "from_user" y "to_user" son llaves foráneas, ya que pueden usarse para definir un enlace con la tabla users. Si buscamos un usuario de Twitter en la columna "from_user", obtendremos todos los usuarios que sigue. En consecuencia, si consultamos por un usuario de Twitter en la columna "to_user", todos los usuarios lo seguirán.

Hemos logrado mucho hasta ahora. Eliminamos las repeticiones en columnas y filas al separar los datos en tres tablas diferentes, y luego elegimos llaves primarias significativas para vincular las tablas. Todo este proceso se llama normalización y su salida son datos que se organizan limpiamente de acuerdo con el modelo relacional. La consecuencia de esta organización es que las filas aparecerán en la base de datos solo una vez que avancen, lo que a su vez facilitará las operaciones CRUD.

La Fig. 4 muestra un diagrama del esquema de base de datos finalizado. Las tres tablas están vinculadas entre sí y las llaves primarias están resaltadas.

Fig. 4


Sistemas de gestión de bases de datos relacionales

Existen pequeñas variaciones en SQL entre cada proveedor de RDBMS, denominadas dialectos SQL.

Ahora que sabemos cómo diseñar una base de datos relacional, ¿cómo implementamos una? Los sistemas de administración de bases de datos relacionales (RDBMS, Relational Database Management System) son software que te permiten crear y usar bases de datos relacionales. Hay varios proveedores comerciales y de código abierto para elegir. En el aspecto comercial, Oracle Database, IBM DB2 y Microsoft SQL Server son tres soluciones bien conocidas. En el lado del código abierto y gratuito, MySQL, SQLite y PostgreSQL son tres soluciones ampliamente utilizadas.

MySQL se utiliza en casi todas las empresas de Internet de las que haz oído hablar. En el contexto de este artículo, Twitter usa MySQL para almacenar los tweets de sus usuarios.

SQLite es común en los sistemas integrados. iOS y Android permiten a los desarrolladores usar SQLite para administrar la base de datos privada de tu aplicación. Google Chrome usa SQLite para almacenar tu historial de navegación, cookies y tus thumbnails en la página "Más visitados".

PostgreSQL también es un RDBMS ampliamente utilizado. Su extensión PostGIS complementa PostgreSQL con funciones geoespaciales que lo hacen útil para aplicaciones de mapeo. Un usuario notable de PostgreSQL es OpenStreetMap.


Structured Query Language (SQL)

Una vez que hayas descargado y configurado un RDBMS en su sistema, el siguiente paso es crear una base de datos y tablas dentro de él para insertar y administrar tus datos relacionales. La forma de hacer esto es con Structured Query Language (SQL, Lenguaje de consulta estructurado, en español), que es el lenguaje estándar para trabajar con RDBMS.

Aquí hay una breve descripción de las declaraciones SQL comunes que son relevantes para los datos de Twitter del ejemplo anterior. Te recomiendo que consultes el SQL Cookbook (Libro de recetas SQL, en español) para obtener una lista más completa de consultas SQL impulsadas por aplicaciones.

  • Crea una base de datos, llamada "development"
  • Crea una tabla llamada "users"

    Los RDBMS requieren que a cada columna de una tabla se le asigne un tipo de datos. Aquí le he asignado a las columnas "full_name" y "username" el tipo de datos VARCHAR, que es una cadena que puede variar en ancho. He establecido arbitrariamente una longitud máxima de 100. Aquí se puede encontrar una lista completa de tipos de datos.

  • Insertar un registro (la operación Create en CRUD)
  • Recuperar todos los tweets pertenecientes a @_DreamLead (la operación Retrieve en CRUD)
  • Actualizar el nombre de un usuario (la operación Update en CRUD)
  • Eliminar un usuario (la operación Delete en CRUD)

SQL es bastante similar a las oraciones regulares en inglés. Existen pequeñas variaciones en SQL entre cada proveedor de RDBMS, denominadas dialectos SQL, pero las diferencias no son lo suficientemente dramáticas como para que no puedas transferir fácilmente tu conocimiento de SQL de uno a otro.


Conclusión

En este artículo, aprendimos cómo diseñar una base de datos relacional. Tomamos una colección de datos y la organizamos en tablas relacionadas. También analizamos brevemente las soluciones RDBMS y SQL. Así que empieza descargando un RDBMS y normalizando algunos de sus datos en una base de datos relacional hoy.

Fuente de la imagen de vista previa: FindIcons.com/Barry Mieny

Advertisement
Did you find this post useful?
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.