Blog

SQL

SQL significa Structured Query Language, que puede ser traducido como lenguaje de consultas estructuradas. Luego se trata de un lenguaje de programación que emplearemos para hacer consultas. Y es el lenguaje de programación más ampliamente usado para trabajar con bases de datos relacionales.

¿Qué es SQL?

Por tanto, podemos definir SQL como un lenguaje de programación que emplearemos para gestionar las bases de datos relacionales.

Sigue leyendo SQL

De un fichero a una base de datos relacional

En este apartado, vamos a ver como pasar los datos de un fichero a una base de datos relacional, y de esta manera organizar nuestros datos de manera más eficiente y evitar errores. Para verlo en la práctica, trasladaremos los datos del fichero de proveedores de Antonio a una base de datos Access.

Paso 1: Creamos una base de datos

Creamos una base de datos nueva, le ponemos el nombre que queramos, por ejemplo: Proveedores

Paso 2: Creamos una tabla con todos los datos del fichero

Lo primero que haremos, será traernos todos los datos de nuestro fichero de proveedores a una única tabla. Lógicamente, en esta tabla vamos a tener mucha información redundante, ya que sencillamente vamos a copiar la estructura de nuestro fichero.

Para poder explicar adecuadamente el proceso, he generado algunos datos más, e introducido algunos errores que perfectamente podrían haberse cometido al registrar la información en un fichero y repetir ciertos datos varias veces. Nuestros datos de partida serían:

Tabla de datos
Tabla de datos

Paso 3: Definiendo las estructuras de las nuevas tablas

Estudiando la estructura de nuestros datos, vemos que hay cierta información, la relativa a los datos del proveedor, que se repite varias veces en varios registros. Por el contrario, la información de producto varia de un registro a otro, incluso cuando el producto es el mismo, pueden tener distinto precio.

En esta situación, lo que tiene sentido es crear una tabla para los datos de proveedores con los siguientes campos: NombreProveedor, ContactoProveedor y Telefono. Y una segunda tabla con los datos Producto y Precio.

Tabla1:

  • NombreProveedor.
  • ContactoProveedor.
  • Telefono

Tabla2:

  • Producto.
  • Precio.

Paso 4: Relación entre las tablas creadas

No obstante, si sencillamente separamos los datos, y los colocamos en tablas independientes, estaríamos perdiendo información muy valiosa, no sabríamos que producto con que precio corresponde a cada proveedor.

Tenemos que establecer una relación entre las dos tablas creadas, de forma que no se pierda información, que sepamos que producto corresponde a cada proveedor. Necesitamos por tanto un campo en la Tabla2 que identifique de forma univoca al proveedor. Este campo, lo tenemos que tener también en la Tabla1 para poder establecer la relación.

Escogemos NombreProveedor de Tabla1 como campo para la relación. Podríamos haber escogido cualquier otro, siempre que no tuviera valores repetidos, ya que si los tuviera, ese duplicado representaría a dos proveedores, y no tendríamos forma en Tabla2 de saber a cual de los dos nos referimos.

La estructura definida para nuestra BBDD tendría el siguiente aspecto:

Relaciones entre tablas
Relaciones entre tablas

Paso 5: Chequeando y mejorando la calidad de los datos

Antes de proceder a la creación de las nuevas tablas, debemos chequear la calidad de los datos. Para ello vamos a realizar diversas consultas sobre la tabla de partida que contiene todos los datos:

Consulta_1: Calidad_NombreProveedor

Para chequear los datos de los nombres de Proveedores. Agrupamos los nombres de los proveedores y contamos las veces que aparecen.

El código SQL de la consulta sería:

SELECT FicheroInicialProveedores.NombreProveedor, Count(FicheroInicialProveedores.NombreProveedor) AS CuentaDeNombreProveedor
FROM FicheroInicialProveedores
GROUP BY FicheroInicialProveedores.NombreProveedor
ORDER BY FicheroInicialProveedores.NombreProveedor;

Más adelante introduciremos el lenguaje SQL, de momento, para esta práctica, sencillamente crearemos una consulta en Access y, en la vistaSQL, copiaremos la sentencia SQL de la consulta.

Ejecutamos la consulta y obtenemos el siguiente resultado:

Resultado de la consulta cuenta de proveedores
Resultado de la consulta cuenta de proveedores

Podemos observar que hay dos registros “sospechosos”:

  • “Azucarera Sevilana” seguramente es erróneo y corresponde a “Azucarera Sevillana”, sencillamente nos comimos una “l” al introducir dicho registro.
  • De igual forma, “Frutas Gutierez” es erróneo, en realidad es “Frutas Gutierrez”, en este caso nos comimos una “r”.

Consulta_2: Corrección_NombreProveedor

Al manejar tan pocos datos en esta practica, podríamos estar tentados de actualizar los datos directamente en los registros afectados. Pero en una situación real, con muchísimos más registros, estas actualizaciones no podemos realizarlas de manera manual una a una, sino que las realizaríamos mediante consultas de actualización.

La primera de las consultas de actualización sería:

UPDATE FicheroInicialProveedores SET FicheroInicialProveedores.NombreProveedor = "Azucarera Sevillana"
WHERE (((FicheroInicialProveedores.NombreProveedor)="Azucarera Sevilana"));

Si ejecutamos la consulta, buscamos los registros que tengan nombre de proveedor:  “Azucarera Sevilana” y le cambiamos el valor a “Azucarera Sevillana”.

Lógicamente, la consulta para corregir el nombre de Frutas Gutierez sería la misma con otros literales:

UPDATE FicheroInicialProveedores SET FicheroInicialProveedores.NombreProveedor = "Frutas Gutierrez"
WHERE (((FicheroInicialProveedores.NombreProveedor)="Frutas Gutierez"));

Tras ejecutar estas dos consultas de actualización, ejecutamos la anterior consulta: Consulta_1: Calidad_NombreProveedor

El resultado que obtenemos ahora es el siguiente:

Consulta cuenta de proveedores
Consulta cuenta de proveedores

Donde ya no detectamos registros de NombreProveedor que sean erróneos.

Consulta_3:Calidad_ContactoProveedor:

Realizamos una operación similar para los datos del campo: ContactoProveedor y veremos que en este caso no detectamos errores.

Consulta_4: Calidad_Tabla1

Y finalmente, realizamos la consulta sobre todos los datos de la que sería nuestra Tabla1, con la información de proveedores.

En este caso si detectamos errores, hay algunos contactos que aparecen con más de un número de teléfono, lo que es erróneo, se produce porque nos hemos equivocado cuando introducimos los datos.

La sentencia SQL de esta consulta sería:

SELECT FicheroInicialProveedores.NombreProveedor, FicheroInicialProveedores.ContactoProveedor, FicheroInicialProveedores.Telefono, Count(FicheroInicialProveedores.NombreProveedor) AS CuentaDeNombreProveedor
FROM FicheroInicialProveedores
GROUP BY FicheroInicialProveedores.NombreProveedor, FicheroInicialProveedores.ContactoProveedor, FicheroInicialProveedores.Telefono;

Si la ejecutamos, obtendríamos el resultado:

Consulta que muestra los errores de introducción
Consulta que muestra los errores de introducción

Donde podemos ver dos resultados con cuenta 1, que probablemente sean erróneos. Para aquellos proveedores que tienen más de un número de teléfono, habría que asegurarse de cual de ellos es el correcto, y actualizar los datos en la tabla vía consultas de actualización.

Tras corregir estos errores, si ejecutamos de nuevo la Consulta_4: Calidad_Tabla1, obtendremos:

Consulta que muestra que se han corregido los errores
Consulta que muestra que se han corregido los errores

Donde ya no detectamos errores.

NOTA: La información de producto también convendría repasarla e intentar mejorar la calidad de los datos. No obstante, eso queda fuera del objetivo de esta práctica

Paso 6: Generando las nuevas tablas

Una vez hemos revisado la tabla con todos los datos de proveedores, y corregido los errores detectados, vamos a crear las nuevas tablas definidas en el Paso 4.

Consulta_5: Creación_Tabla1

Ejecutamos la siguiente consulta para generar la tabla de proveedores:

SELECT FicheroInicialProveedores.NombreProveedor, FicheroInicialProveedores.ContactoProveedor, FicheroInicialProveedores.Telefono INTO Proveedores
FROM FicheroInicialProveedores
GROUP BY FicheroInicialProveedores.NombreProveedor, FicheroInicialProveedores.ContactoProveedor, FicheroInicialProveedores.Telefono
ORDER BY FicheroInicialProveedores.NombreProveedor;

Tras su ejecución, veremos que hemos creado la Tabla Proveedores que corresponde a la Tabla1 de nuestra estructura.

A continuación, generaremos la otra tabla de nuestra estructura, la que contiene la información de Productos. Hay que recordar que en esta tabla necesitamos tener también el campo NombreProveedor, ya que será el que usemos para establecer la relación con la Tabla1.

Consulta_6: Creación_Tabla2

Ejecutamos la siguiente instrucción SQL para generar la Tabla2:

SELECT FicheroInicialProveedores.NombreProveedor, FicheroInicialProveedores.Producto, FicheroInicialProveedores.Precio INTO ProductosEnProveedores
FROM FicheroInicialProveedores
ORDER BY FicheroInicialProveedores.NombreProveedor;

Tras ejecutar ambas consultas, tendremos dos nuevas tablas: Proveedores y ProductosEnProveedores. Estas tablas se relacionarán por medio del campo NombreProveedor:

Nuevas relaciones
Nuevas relaciones

Paso 7: Accediendo a los datos

Mediante la relación definida entre los campos NombreProveedor de ambas tablas, podremos acceder a los datos de ambas tablas de manera combinada.

Imaginemos que queremos saber que proveedores nos pueden suministrar Naranjas. En este caso podríamos emplear únicamente la Tabla “ProductosEnProveedores” porque en ella tenemos toda la información que estamos buscando.

Pero si queremos que también nos aparezca en la consulta el contacto del proveedor y el teléfono, porque estamos buscando los proveedores que nos pueden suministrar Naranjas para realizar un pedido. En este caso, necesitamos recuperar datos de ambas tablas de manera coordinada.

Consulta_7: Naranjas

Ejecutamos la siguiente instrucción SQL para obtener la información de los proveedores que suministran Naranjas y poder hacerles un pedido.

SELECT Proveedores.NombreProveedor, Proveedores.ContactoProveedor, Proveedores.Telefono, ProductosEnProveedores.Producto, ProductosEnProveedores.Precio
FROM Proveedores INNER JOIN ProductosEnProveedores ON Proveedores.NombreProveedor = ProductosEnProveedores.NombreProveedor
WHERE (((ProductosEnProveedores.Producto)="Naranja"));

La instrucción INNER JOIN es la que define la relación entre ambas tablas, pero esto lo veremos más adelante cuando aprendamos SQL.

Si ejecutamos la consulta, obtendríamos el siguiente resultado:

Consulta relacionando datos de distintas tablas
Consulta relacionando datos de distintas tablas

Paso 8: Conclusiones

Repasemos lo que hemos hecho para entender el cambio de paradigma que supuso la irrupción de las bases de datos relacionales.

Previamente almacenábamos los datos en ficheros y registrábamos toda la información cada vez que insertábamos una nueva información. En nuestro ejemplo, teníamos que introducir de nuevo todos los datos del proveedor, aunque sólo quisiéramos registrar un nuevo producto para un proveedor ya conocido y registrado. Esto al final ocasionaba muchos errores y una perdida importante de calidad en los datos.

Con las bases de datos relacionales, estructuramos los datos en tablas y definíamos relaciones entre ellas que nos permitían recuperar todos los datos que necesitáramos. De esta forma evitábamos introducir la misma información muchas veces, minimizábamos errores y contribuíamos a mantener la calidad de nuestros datos.

Además, definíamos una estructura de datos que era independiente del soporte físico que almacenaba los datos, dejando a los gestores de BBDDs (software) gestionar la interacción de nuestra estructura con el soporte físico de los datos. Por supuesto, este nivel de abstracción facilita enormemente el trabajo con los datos y reduce el número de errores.

NOTA:

Este post es parte de la colección “Sistemas de acceso y almacenamiento de datos”. Puedes ver el índice de esta colección aquí.

Base de datos relacional

La base de datos relacional vino a dar respuesta a la necesidad de estructurar la información que se venía manejando en distintos ficheros. La creciente cantidad de datos con los que se trabajaba hacía que cada vez se crearan más ficheros con datos y forzó a encontrar una manera eficiente de estructurar toda esa información.

¿Qué es una base de datos relacional?

En realidad, una base de datos relacional no es otra cosa que un software que nos permite manejar estructuras de datos entre las que se crean relaciones. De esta forma, los datos no están aislados en las distintas estructuras, sino que están relacionados a través de las relaciones que se crean entre partes de estas estructuras.

Las estructuras en una base de datos relacional son las tablas, compuestas de varias columnas y filas. Las columnas representan los atributos de los datos que queremos almacenar, que normalmente denominaremos campos. Y en cada fila registramos un conjunto de valores para los distintos atributos, conformando lo que denominaremos un registro.

Sigue leyendo Base de datos relacional

Como funciona el escáner

Probablemente, todos sabemos lo que es un escáner y para qué sirve, aunque quizás no tengamos tan claro su funcionamiento. En este post, explico como funciona el escáner y espero aportar un poco luz sobre este tema.

Empleamos un escáner para digitalizar imágenes o textos que podemos tener en distintos soportes analógicos: fotografías, papeles, etc. Dicho así, puede sonar como una cámara digital, como la que tenemos en nuestro móvil, y ciertamente es muy parecido.

Ambos dispositivos, escáner y cámara, emplean un sensor CCD (Charge Coupled Device) que es un dispositivo capaz de transformar la luz que sobre él incide, en señales eléctricas. Posteriormente, otro elemento llamado DAC (Digital to Analogue converter) traduce dichas señales eléctricas a bits, conjuntos de unos y ceros.

El sensor CCD está compuesto por una matriz de puntos sensibles, cada uno de los cuales genera una señal eléctrica que depende de la intensidad y color de la luz que sobre él incida. De esta forma, podemos conocer el color y brillo de cada punto.

Empleando el DAC, convertimos las señales eléctricas generadas en cada punto en una señal digital, y juntando las lecturas de todos los puntos tenemos nuestra imagen digitalizada.

¿Cuáles son entonces las diferencias entre una cámara y un escáner? En la primera, el sensor CCD está fijo y mediante un juego de lentes hacemos que indica sobre él, la luz reflejada por los objetos, controlando la cantidad de luz y el tiempo de exposición. En el segundo, recorremos la imagen que queremos escanear, iluminándola y haciendo que la luz reflejada incida sobre el CCD. Lo más habitual es que el sensor este fijo y se desplace la fuente de iluminación y un juego de espejos que será el que conduzca la luz reflejada al sensor que permanecerá fijo. Podéis apreciarlo en la siguiente figura:

Dibujo de como funciona el escáner
Como funciona el escáner
Sigue leyendo Como funciona el escáner

Ejercicios con arrays en Java

En este post, os propongo algunos ejercicios con arrays en Java para practicar lo explicado en el post anterior en el que contaba como trabajar con los arrays. Como siempre digo, existen varias soluciones posibles para resolver un mismo problema, unas más eficientes que otras. Aquí podéis ver una solución posible para cada ejercicio propuesto.

Ejercicio 1

Escribe un programa que pida al usuario que introduzca un texto y una letra. Después el programa tiene que calcular y presentar por pantalla, cuantas veces aparece la letra en el texto.

Sigue leyendo Ejercicios con arrays en Java

Arrays en Java

Continuando con las notas de Java, voy a explicar cómo trabajar con los Arrays en Java. Un array o matriz es un grupo de varias variables del mismo tipo, que son referenciadas por el mismo nombre.

Los arrays son usados para almacenar multitud de variables en una única variable, en lugar de declarar separadamente cada una de ellas.

Las variables en un array están ordenadas. Cada una de ellas ocupa una posición indicada por el índice del array. El índice del array empieza con el valor 0 para la posición 1, el valor 1 para la posición 2 y así sucesivamente.

Accedemos a cada elemento del array utilizando el índice que indica la posición del elemento. Por ejemplo, si queremos acceder al elemento del array que ocupa la posición 5, tendríamos que referenciarlo usando el valor 4 para el índice.

Declarar un array

Cuando declaramos un array, definimos el tipo de las variables que almacenaremos en el array. Recordad que son todas del mismo tipo. A continuación, abrimos y cerramos corchetes, y después escribimos el nombre del array. La sintaxis sería la siguiente:

<type>[] variable_name    ->     int[ ] misNumeros

Para realmente crear el array y reservar memoria para el mismo, hay que usar la palabra clave new, siguiendo la siguiente sintaxis:

variable_name =  new type[size]    ->  misNumeros = new int[7]
Sigue leyendo Arrays en Java

Herencia en Java

La herencia es un proceso mediante el cual heredamos una serie de características de nuestros antecesores. La herencia en Java la podemos definir como un mecanismo para definir una clase nueva a partir de otra ya existente. La clase nueva hereda de la existente sus parámetros y métodos, que no hace falta definirlos de nuevo, sencillamente los hereda. Además, dicha clase nueva puede incluir nuevos parámetros y métodos propios, extendiendo la clase ya existente.

Se denomina clase padre o superclass a la clase existente de la que hereda la nueva clase que es conocida como clase hija.

Para entender y practicar con la herencia de clases, vamos a emplear el siguiente esquema:

Herencia en Java
Herencia en Java

En este esquema, la superclase es “Vehículo rodado”, de la que heredan dos clases: “Coche” y “Bicicleta”. Además, tenemos otras dos clases: “Descapotable” y “Sedan”, que heredan de la clase “Coche”, que para aquellas dos clases sería la superclase.

Sigue leyendo Herencia en Java

Sobrecarga de constructores en Java

Antes de explicar la sobrecarga de constructores en Java, voy a recordar brevemente que son los constructores y que es la sobrecarga.

Los constructores son métodos de la clase con el mismo nombre que esta, que se emplean para instanciar objetos de la misma.

La sobrecarga de métodos consiste en tener varios métodos distintos con el mismo nombre, siempre y cuando acepten distintos tipos de parámetros. De otra forma, Java no tendría posibilidad de distinguirlos y saber a que método nos referimos cuando lo llamáramos.

Sigue leyendo Sobrecarga de constructores en Java

Modificador static

El modificador static se emplea para hacer accesible una clase, parámetro, método o bloque, sin necesidad de instanciar un objeto de la clase en la que está definido.

Para el caso de una clase static, únicamente tiene sentido para las inner class. Es decir, para clases definidas dentro de otras clases. Al declarar una inner class como static, podríamos acceder a ella sin necesidad de instanciar la clase en la que está incluida.

Un método static sería directamente accesible invocándolo, sin necesidad de generar un objeto de la clase en la que está definido. El ejemplo más obvio es el método main, que es el que busca Java para empezar la ejecución de un programa, y tiene que estar accesible sin instanciar un objeto de la clase. Por ello es declarado como public static.

Sigue leyendo Modificador static

Métodos getter y setter

Los métodos getter y setter se emplean para acceder a los parámetros de una clase a través de funciones, lo que nos proporciona mayor seguridad y control sobre el acceso y modificación de los mismos.

Acceso a los parámetros

La manera de acceder a los parámetros que hemos visto hasta ahora, requiere que estos estén definidos como públicos, que es el valor que toma por defecto sino utilizamos ningún modificador.

En el caso de la clase Coche, si por ejemplo tomamos el parámetro añoFabricación, este está definido como:

int añoFabricacion

lo que es equivalente a:

public int añoFabricacion
Sigue leyendo Métodos getter y setter