Bases de datos relacionales para Dummies

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, demostraré qué es una base de datos relacional y cómo diseñar adecuadamente su base de datos para almacenar la información de su aplicación..

Una base de datos almacena los datos de forma organizada para que se puedan buscar y recuperar más adelante. Debe contener una o más tablas. Una tabla es muy parecida 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 le ayuda, piense en sus tablas de la misma manera que lo haría con una tabla en Excel.

Figura 1

Los datos se pueden insertar, recuperar, actualizar y eliminar de una tabla. La palabra, creado, generalmente se usa en lugar de insertado, Entonces, 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 en función de las relaciones definidas. Estas relaciones le permiten recuperar y combinar datos de una o más tablas con una sola consulta.

Pero eso fue sólo un montón de palabras. Para comprender realmente una base de datos relacional, debe crearla usted mismo. Comencemos obteniendo datos reales con los que podemos trabajar..


Paso 1: Obtener algunos datos

En el espíritu de los artículos clonados de Nettuts + 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

nombre completo nombre de usuario texto Creado en nombre_de_usuario siguiente
"Boris hadjur" "_DreamLead" "¿Qué piensas acerca de # enviando # campañas # tráfico en #USA? ¿Es un buen mercado hoy en día? ¿Tienes # bases de datos?" "Mar, 12 de febrero 2013 08:43:09 +0000" "Scootmedia", "MetiersInternet"
"Gunnar Svalander" "GunnarSvalander" "Bill Gates habla sobre bases de datos, software libre en Reddit http://t.co/ShX4hZlA #billgates #databases" "Mar, 12 de febrero de 2013 07:31:06 +0000" "klout", "zillow"
"Software GE" "GEsoftware" "RT @KirkDBorne: Lecturas en #Databases: excelente lista de lectura, muchas categorías: http://t.co/S6RBUNxq a través de @rxin Fascinante". "Mar, 12 de febrero de 2013 07:30:24 +0000" "DayJobDoc", "byosko"
"Adrian Burch" adrianburch "RT @tisakovich: @NimbusData en la conferencia @Barclays Big Data en San Francisco hoy, hablando sobre #virtualización, #databases y # memoria flash". "Mar, 12 de febrero 2013 06:58:22 +0000" "CindyCrawford", "Arjantim"
"Andy Ryder" "AndyRyder5" "http://t.co/D3KOJIvF artículo sobre Madden 2013 usando AI para producir el super bowl #databases # bus311" "Mar, 12 de febrero 2013 05:29:41 +0000" "MichaelDell", "Yahoo"
"Andy Ryder" "AndyRyder5" "http://t.co/rBhBXjma un artículo sobre la configuración de privacidad y facebook #databases # bus311" "Mar, 12 de febrero 2013 05:24:17 +0000" "MichaelDell", "Yahoo"
"Brett Englebert" "Brett_Englebert" "# BUS311 El NCFPD de la Universidad de Minnesota está creando # bases de datos para prevenir el" fraude alimentario ". Http://t.co/0LsAbKqJ" "Mar, 12 de febrero 2013 01:49:19 +0000" "RealSkipBayless", "stephenasmith"
Brett Englebert "Brett_Englebert" "Las compañías # BUS311 podrían estar protegiendo sus # bases de datos de producción, pero ¿qué hay de sus archivos de respaldo? Http://t.co/okJjV3Bm" "Mar, 12 de febrero 2013 01:31:52 +0000" "RealSkipBayless", "stephenasmith"
"Sistemas de datos Nimbus" "NimbusData" "La conferencia de @NimbusData CEO @tisakovich @BarclaysOnline Big Data en San Francisco hoy, hablando #virtualización, # bases de datos, y # memoria flash" "Lunes, 11 de febrero de 2013 23:15:05 +0000" "dellock6", "rohitkilam"
"SSWUG.ORG" "SSWUGorg" "No se olvide de registrarse para nuestra exposición GRATUITA este viernes: #Databases, #BI, y #Sharepoint: ¡Lo que necesita saber! Http://t.co/Ijrqrz29" "Lunes, 11 de febrero de 2013 22:15:37 +0000" "drsql", "steam_games"

Esto es lo que significa el nombre de cada columna:

MySQL se usa en casi todas las compañías de Internet de las que ha oído hablar.

  • nombre completo: El nombre completo del usuario
  • nombre de usuario: El manejador de Twitter
  • texto: El propio tweet
  • Creado en: La marca de tiempo del tweet
  • nombre_de_usuario siguiente: Una lista de personas a las que sigue este usuario, separadas por comas. Para abreviar, limité la longitud de la lista a dos

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

Esto es bueno. Los datos están todos en un solo lugar; por lo que es fácil de encontrar, ¿verdad? No exactamente. Hay un par de problemas con esta mesa. Primero, hay datos repetitivos en las columnas. Las columnas "username" y "following_username" son repetitivas, ya que ambas contienen el mismo tipo de datos: los manejadores 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 a través de filas.

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

Los duplicados son problemáticos porque hacen que las operaciones de CRUD sean más desafiantes. Por ejemplo, tomaría más tiempo recuperar los datos porque se perdería el tiempo pasando por filas duplicadas. Además, actualizar los datos sería un problema; Si un usuario cambia su cuenta de Twitter, deberíamos encontrar cada duplicado y actualizarlo..

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


Paso 2: Eliminar datos repetitivos en columnas

Como se indicó anteriormente, las columnas "username" y "following_username" en tabla 1 son repetitivas Esta repetición ocurrió porque estaba tratando de expresar la relación de seguimiento entre usuarios. Vamos a mejorar tabla 1El diseño se divide en dos tablas: una solo para las siguientes relaciones y otra para el resto de la información.

Figura 2

Debido a que @Brett_Englebert sigue a @RealSkipBayless, el siguiendo table expresará esa relación almacenando @Brett_Englebert como "from_user" y @RealSkipBayless como "to_user". Sigamos adelante y partamos tabla 1 en estas dos tablas:

Tabla 2: El siguiendo mesa

Del usuario al usuario
_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 herrero
NimbusData dellock6
NimbusData Rohitkilam
SSWUGorg drsql
SSWUGorg juegos de vapor

Tabla 3: El usuarios mesa

nombre completo nombre de usuario texto Creado en
"Boris hadjur" "_DreamLead" "¿Qué piensas sobre # enviando # campañas # tráfico en #USA? ¿Es un buen mercado hoy en día? ¿Tienes # bases de datos?" "Mar, 12 de febrero 2013 08:43:09 +0000"
"Gunnar Svalander" "GunnarSvalander" "Bill Gates habla sobre bases de datos, software libre en Reddit http://t.co/ShX4hZlA #billgates #databases" "Mar, 12 de febrero de 2013 07:31:06 +0000"
"Software GE" "GEsoftware" "RT @KirkDBorne: Lecturas en #Databases: excelente lista de lectura, muchas categorías: http://t.co/S6RBUNxq a través de @rxin Fascinante". "Mar, 12 de febrero de 2013 07:30:24 +0000"
"Adrian Burch" adrianburch "RT @tisakovich: @NimbusData en la conferencia @Barclays Big Data en San Francisco hoy, hablando sobre #virtualización, #databases y # memoria flash". "Mar, 12 de febrero 2013 06:58:22 +0000"
"Andy Ryder" "AndyRyder5" "http://t.co/D3KOJIvF artículo sobre Madden 2013 usando AI para producir el super bowl #databases # bus311" "Mar, 12 de febrero 2013 05:29:41 +0000"
"Andy Ryder" "AndyRyder5" "http://t.co/rBhBXjma un artículo sobre la configuración de privacidad y facebook #databases # bus311" "Mar, 12 de febrero 2013 05:24:17 +0000"
"Brett Englebert" "Brett_Englebert" "# BUS311 El NCFPD de la Universidad de Minnesota está creando # bases de datos para prevenir el" fraude alimentario ". Http://t.co/0LsAbKqJ" "Mar, 12 de febrero 2013 01:49:19 +0000"
Brett Englebert "Brett_Englebert" "Las compañías # BUS311 podrían estar protegiendo sus # bases de datos de producción, pero ¿qué hay de sus archivos de respaldo? Http://t.co/okJjV3Bm" "Mar, 12 de febrero 2013 01:31:52 +0000"
"Sistemas de datos Nimbus" "NimbusData" "La conferencia de @NimbusData CEO @tisakovich @BarclaysOnline Big Data en San Francisco hoy, hablando #virtualización, # bases de datos, y # memoria flash" "Lunes, 11 de febrero de 2013 23:15:05 +0000"
"SSWUG.ORG" "SSWUGorg" "No se olvide de registrarse para nuestra exposición GRATUITA este viernes: #Databases, #BI, y #Sharepoint: ¡Lo que necesita saber! Http://t.co/Ijrqrz29" "Lunes, 11 de febrero de 2013 22:15:37 +0000"

Esto se ve mejor. Ahora en el usuarios mesa (Tabla 3), solo hay una columna con los identificadores de Twitter. En el siguiendo mesa (Tabla 2), es solo un manejador de Twitter por campo en la columna "to_user".

Edgar F. Codd, el científico informático que estableció las bases teóricas de las bases de datos relacionales, llamó a este paso de eliminar datos repetitivos en columnas la primera forma normal (1NF).


Paso 3: Eliminar datos repetitivos en filas

Ahora que hemos arreglado las repeticiones en las columnas, necesitamos arreglar las repeticiones en las filas. Dado que los usuarios @ AndyRyder5 y @Brett_Englebert twitearon cada uno dos veces, su información está duplicada en el usuarios mesa (Tabla 3). Esto indica que necesitamos sacar los tweets y colocarlos en su propia mesa..

Fig. 3

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

Tabla 4: El tweets mesa

texto Creado en nombre de usuario
"¿Qué piensas sobre # enviando # campañas # tráfico en #USA? ¿Es un buen mercado hoy en día? ¿Tienes # bases de datos?" "Mar, 12 de febrero 2013 08:43:09 +0000" "_DreamLead"
"Bill Gates habla sobre bases de datos, software libre en Reddit http://t.co/ShX4hZlA #billgates #databases" "Mar, 12 de febrero de 2013 07:31:06 +0000" "GunnarSvalander"
"RT @KirkDBorne: Lecturas en #Databases: excelente lista de lectura, muchas categorías: http://t.co/S6RBUNxq a través de @rxin Fascinante". "Mar, 12 de febrero de 2013 07:30:24 +0000" "GEsoftware"
"RT @tisakovich: @NimbusData en la conferencia @Barclays Big Data en San Francisco hoy, hablando sobre #virtualización, #databases y # memoria flash". "Mar, 12 de febrero 2013 06:58:22 +0000" adrianburch
"http://t.co/D3KOJIvF artículo sobre Madden 2013 usando AI para producir el super bowl #databases # bus311" "Mar, 12 de febrero 2013 05:29:41 +0000" "AndyRyder5"
"http://t.co/rBhBXjma un artículo sobre la configuración de privacidad y facebook #databases # bus311" "Mar, 12 de febrero 2013 05:24:17 +0000" "AndyRyder5"
"# BUS311 El NCFPD de la Universidad de Minnesota está creando # bases de datos para prevenir el" fraude alimentario ". Http://t.co/0LsAbKqJ" "Mar, 12 de febrero 2013 01:49:19 +0000" "Brett_Englebert"
"Las compañías # BUS311 podrían estar protegiendo sus # bases de datos de producción, pero ¿qué hay de sus archivos de respaldo? Http://t.co/okJjV3Bm" "Mar, 12 de febrero 2013 01:31:52 +0000" "Brett_Englebert"
"La conferencia de @NimbusData CEO @tisakovich @BarclaysOnline Big Data en San Francisco hoy, hablando #virtualización, # bases de datos, y # memoria flash" "Lunes, 11 de febrero de 2013 23:15:05 +0000" "NimbusData"
"No se olvide de registrarse para nuestra exposición GRATUITA este viernes: #Databases, #BI, y #Sharepoint: ¡Lo que necesita saber! Http://t.co/Ijrqrz29" "Lunes, 11 de febrero de 2013 22:15:37 +0000" "SSWUGorg"

Tabla 5: La usuarios mesa

nombre completo nombre de usuario
"Boris hadjur" "_DreamLead"
"Gunnar Svalander" "GunnarSvalander"
"Software GE" "GEsoftware"
"Adrian Burch" adrianburch
"Andy Ryder" "AndyRyder5"
"Brett Englebert" "Brett_Englebert"
"Sistemas de datos Nimbus" "NimbusData"
"SSWUG.ORG" "SSWUGorg"

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

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


Paso 4: vinculando tablas con llaves

Los datos se pueden insertar, recuperar, actualizar y eliminar de una tabla.

Hasta aquí, tabla 1 Se ha dividido en tres nuevas tablas: siguiendo (Tabla 2), tweets (Tabla 4), y usuarios (Tabla 5). Pero, ¿cómo es esto útil? Los datos repetitivos se han eliminado, pero ahora los datos se distribuyen en tres tablas independientes. Para recuperar los datos, necesitamos dibujar enlaces significativos entre las tablas. De esta manera podemos expresar consultas como "lo que un usuario ha twitteado y a quién sigue".

La forma de dibujar enlaces entre tablas es dar primero a cada fila de una tabla un identificador único, denominado clave principal, y luego hacer referencia a esa clave primaria en la otra tabla a la que desea vincular.

De hecho, ya hemos hecho esto en usuarios (Tabla 5) y tweets (Tabla 4). En usuarios, la clave principal es la columna "nombre de usuario" porque no hay dos usuarios que tengan el mismo identificador de Twitter. En tweets, Hacemos referencia a esta clave en la columna "nombre de usuario" para que sepamos quién tuiteó qué. Ya que es una referencia, la columna "nombre de usuario" en tweets Se llama una clave foránea. De esta manera, la tecla "nombre de usuario" enlaza el usuarios y tweets mesas juntas.

¿Es la columna "nombre de usuario" la mejor idea para una clave principal para el usuarios mesa?

Por un lado, es una clave natural: tiene sentido buscar con una cuenta de Twitter en lugar de asignar a cada usuario una identificación numérica y buscarla. Por otro lado, ¿qué pasa si un usuario quiere cambiar su cuenta de Twitter? Eso podría causar errores si la clave principal y todas las claves externas de referencia no se actualizan con precisión, errores que podrían evitarse si se utilizara una identificación numérica constante. En última instancia, la elección depende de su sistema. Si desea dar a sus usuarios la posibilidad de cambiar su nombre de usuario, es mejor agregar una columna numérica de "id" de incremento automático a usuarios y usar eso como la clave principal. De lo contrario, "nombre de usuario" debería funcionar bien. Seguiré usando "nombre de usuario" como clave principal para usuarios

Movámonos a tweets (Tabla 4). Una clave principal debe identificar de forma única cada fila, entonces, ¿cuál debería ser la clave principal aquí? El campo "created_at" no funcionará porque si dos usuarios twittean al mismo tiempo, sus tweets tendrían una marca de tiempo idéntica. El "texto" tiene el mismo problema, ya que si dos usuarios tuitean "Hola mundo", no pudimos distinguir entre las filas. La columna "nombre de usuario" es la clave externa que define el enlace con el usuarios así que no nos metamos con eso. Ya que las otras columnas no son buenos candidatos, tiene sentido aquí agregar una columna numérica de "id" de incremento automático y usarla como la clave principal.

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

carné de identidad texto Creado en nombre de usuario
1 "¿Qué piensas sobre # enviando # campañas # tráfico en #USA? ¿Es un buen mercado hoy en día? ¿Tienes # bases de datos?" "Mar, 12 de febrero 2013 08:43:09 +0000" "_DreamLead"
2 "Bill Gates habla sobre bases de datos, software libre en Reddit http://t.co/ShX4hZlA #billgates #databases" "Mar, 12 de febrero de 2013 07:31:06 +0000" "GunnarSvalander"
3 "RT @KirkDBorne: Lecturas en #Databases: excelente lista de lectura, muchas categorías: http://t.co/S6RBUNxq a través de @rxin Fascinante". "Mar, 12 de febrero de 2013 07:30:24 +0000" "GEsoftware"
4 "RT @tisakovich: @NimbusData en la conferencia @Barclays Big Data en San Francisco hoy, hablando sobre #virtualización, #databases y # memoria flash". "Mar, 12 de febrero 2013 06:58:22 +0000" adrianburch
5 "http://t.co/D3KOJIvF artículo sobre Madden 2013 usando AI para producir el super bowl #databases # bus311" "Mar, 12 de febrero 2013 05:29:41 +0000" "AndyRyder5"
6 "http://t.co/rBhBXjma un artículo sobre la configuración de privacidad y facebook #databases # bus311" "Mar, 12 de febrero 2013 05:24:17 +0000" "AndyRyder5"
7 "# BUS311 El NCFPD de la Universidad de Minnesota está creando # bases de datos para prevenir el" fraude alimentario ". Http://t.co/0LsAbKqJ" "Mar, 12 de febrero 2013 01:49:19 +0000" "Brett_Englebert"
8 "Las compañías # BUS311 podrían estar protegiendo sus # bases de datos de producción, pero ¿qué hay de sus archivos de respaldo? Http://t.co/okJjV3Bm" "Mar, 12 de febrero 2013 01:31:52 +0000" "Brett_Englebert"
9 "La conferencia de @NimbusData CEO @tisakovich @BarclaysOnline Big Data en San Francisco hoy, hablando #virtualización, # bases de datos, y # memoria flash" "Lunes, 11 de febrero de 2013 23:15:05 +0000" "NimbusData"
10 "No se olvide de registrarse para nuestra exposición GRATUITA este viernes: #Databases, #BI, y #Sharepoint: ¡Lo que necesita saber! Http://t.co/Ijrqrz29" "Lunes, 11 de febrero de 2013 22:15:37 +0000" "SSWUGorg"

Por último, vamos a añadir una clave primaria a la siguiendo mesa. En esta tabla, ni la columna "from_user" ni la columna "to_user" identifican cada fila por sí sola. Sin embargo, "from_user" y "to_user" lo hacen juntos, ya que representan una relación única. Una clave principal se puede definir en más de una columna, por lo que usaremos ambas columnas como la clave principal para siguiendo mesa.

En cuanto a la clave foránea, "from_user" y "to_user" son claves foráneas, ya que pueden usarse para definir un enlace con el usuarios mesa. Si buscamos un identificador de Twitter en la columna "from_user", obtendremos todos los usuarios que sigue. En consecuencia, si buscamos un identificador de Twitter en la columna "to_user", haremos que todos los usuarios lo sigan.

Hemos logrado mucho hasta ahora. Eliminamos las repeticiones en columnas y filas al separar los datos en tres tablas diferentes, y luego elegimos claves primarias significativas para vincular las tablas. Todo este proceso se denomina normalización y su salida son datos que están organizados de forma limpia según el modelo relacional. La consecuencia de esta organización es que las filas aparecerán en la base de datos solo una vez hacia adelante, lo que a su vez hace que las operaciones CRUD sean más fáciles.

Fig. 4 diagramas el esquema de base de datos finalizado. Las tres tablas están vinculadas entre sí y las claves principales están resaltadas.

Fig. 4


Sistemas de gestión de bases de datos relacionales

Hay pequeñas variaciones en SQL entre cada proveedor de RDBMS, denominadas dialectos de 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) son software que le permiten crear y utilizar bases de datos relacionales. Hay varios proveedores comerciales y de código abierto para elegir. En el lado comercial, Oracle Database, IBM DB2 y Microsoft SQL Server son tres soluciones bien conocidas. En el lado libre y de código abierto, MySQL, SQLite y PostgreSQL son tres soluciones ampliamente utilizadas.

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

SQLite es común en sistemas embebidos. iOS y Android permiten a los desarrolladores usar SQLite para administrar la base de datos privada de su aplicación. Google Chrome utiliza SQLite para almacenar su historial de navegación, cookies y sus miniaturas en la página "Más visitadas".

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


Lenguaje de consulta estructurado (SQL)

Una vez que haya 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 sus datos relacionales. La forma de hacerlo es con el lenguaje de consulta estructurado (SQL), 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 el ejemplo de datos de Twitter anterior. Le recomiendo que consulte el libro de cocina de SQL para obtener una lista más completa de consultas de SQL basadas en aplicaciones..

  • Crear una base de datos, llamada "desarrollo"
     CREAR BASE DE DATOS de desarrollo;
  • Crear una tabla llamada "usuarios"
     CREAR TABLA usuarios (nombre completo VARCHAR (100), nombre de usuario VARCHAR (100));

    Los RDBMS requieren que cada columna de una tabla tenga un tipo de datos. Aquí he asignado las columnas "nombre completo" y "nombre de usuario" al tipo de datos VARCHAR que es una cadena que puede variar en anchura. He establecido arbitrariamente una longitud máxima de 100. Aquí puede encontrar una lista completa de tipos de datos.

  • Insertar un registro (la operación Crear en CRUD)
     INSERTAR EN LOS usuarios (nombre completo, nombre de usuario) VALUES ("Boris Hadjur", "_DreamLead");
  • Recupere todos los tweets que pertenecen a @_DreamLead (la operación de recuperación en CRUD)
     SELECCIONE texto, created_at DE tweets WHERE username = "_ DreamLead";
  • Actualizar el nombre de un usuario (la operación de actualización en CRUD)
     ACTUALIZAR usuarios SET nombre completo = "Boris H" DONDE nombre de usuario = "_ DreamLead";
  • Eliminar un usuario (la operación Eliminar en CRUD)
 ELIMINAR DE LOS usuarios DONDE nombre de usuario = "_ DreamLead";

SQL es bastante similar a las oraciones regulares en inglés. Hay pequeñas variaciones en SQL entre cada proveedor de RDBMS, denominadas dialectos de SQL, pero las diferencias no son tan dramáticas como para que no pueda transferir fácilmente su 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 recopilación de datos y la organizamos en tablas relacionadas. También examinamos brevemente las soluciones RDBMS y SQL. Así que comience descargando un RDBMS y normalizando algunos de sus datos en una base de datos relacional hoy.

Vista previa de la fuente de la imagen: FindIcons.com/Barry Mieny