EJERCICIOS SQL (SISTEMAS DISTRIBUIDOS 2013)

Anuncio
EJERCICIOS SQL (SISTEMAS DISTRIBUIDOS 2013)
Estos ejercicios si se hacen antes de la publicación
del fichero completo con las respuestas se evalúan
como deberes.
Por que aprender SQL: SQL es una manera universal de acceso a bases de
datos relacionales (todos los BD en el mundo en este momento) y por eso
es algo necesario en el uso profesional de ordenadores. Por eso vale la
pena de invertir unas horas para aprender la base de SQL.
Estos ejercicios se componen de dos partes -- una de problemas y pistas y
otra de soluciones. Para ayuda general hay que referirse a
www.w3schools.com (la parte SQL) o a las páginas
www.firstsql.com/tutor.htm. Es my recomendable leer el material del
último enlace. También se pueden utilizar las páginas
www.airfareoffice.com/multimedia/edat.
En todos los ejercicios hay que conectarse con un servidor SQL y una base
de datos. Debido a que hay solo una base de datos para todos, a cada uno
se pide que utiliza nombres de los recursos, por ejemplo tablas con
nombres que empiezan con su login, por ejemplo si el logins es e999999
las tablas serán e999999_persona o parecidos. Vamos a sustituir esta
cadena con e*_ los ejemplos.
Como aprender: Con estos 20 ejercicios podéis aprender la ideología de
SQL. Los detalles podrán venir practicando. La metodología correcta es:
1. Leer el problema que propone cada ejercicio.
2. Intentar de imaginar que tiene de hacer la máquina de la base de datos
para resolverlo.
3. Leer el material de W3School u otro sitio e intentar de resolverlo si
no sabemos lo necesario de SQL. Utilizar las palabras claves (en
mayúscula azul) para buscar el asunto correspondiente.
4. Intentar de escribir la query. NO COPIAR Y PEGAR EN NINGUN CASO.
Podéis gastar unos 2-3 minutos en cada ejercicio intentando.
5. Ver y analizar la respuesta del fichero con respuestas. Si no hemos
resuelto el problema, ejecutar la query (NO COPIAR Y PEGAR).
6. Apuntar en un cuaderno la sintaxis de cada sentencia SQL que habéis
utilizado. Esto puede servirles como chuleta.
Estimación del tiempo -- 3 horas. Por favor, hacer un fichero log de lo
que ejecutáis. Esto en mysql se hace con
\T <nombre de fichero>
Vamos a crear 3 tablas con relaciones y los índices necesarios entre
ellas. Una para personas, otra para artículos y tercera para pedidos.
Para cada persona guardamos los siguientes datos (el nombre del campo
está subrayado):
*
*
*
*
*
id -- un identificador -- un número entero único para cada persona,
nombre -- hasta 40 caracteres,
apellidos -- hasta 50 caracteres,
direccion -- hasta 100 caracteres,
el dinero que tiene como credito en esta tienda.
Para cada artículo guardamos
* id -- identificador del articulo -- número entero único para cada
artículo.
* nombre de articulo hasta 80 caracteres,
* el precio del artículo
* cantidad disponible.
Para cada pedido vamos a guardar
* a que persona corresponde (id_persona),
* de que artículo se trata (id_articulo),
* qué cantidad del artículo refiere
Ejercicio 0: Conectar con el servidor.
De casa se recomienda de entrar en el servidor instalando un cliente
mysql en su ordenador (existen para linux y windows). PARA ESTOS
EJERCICIOS se recomienda NO UTILIZAR interfaz gráfico con el cliente
instalado. Alternativamente podéis conectar con ssh al servidor de
prácticas y con un browser con la BD que utilizamos.
En el servidor se entra con:
mysql -h mysql8.websitesource.net -u qetu159_student -p qetu159_pruebas
También podeos ver vuestras tablas con interfaz gráfica en el servidor:
http://mysql8.websitesource.net/phpMyAdmin/index.php
(usuario y contraseña como de arriba)
Ejercicio 1: Crear una tabla e*_articulo con la información para los
artículos.
Los campos para cada artículo deberían de llamarse
ID, nombre, precio, cantidad.
CREATE TABLE
Ejercicio 2: Insertar en la tabla artículo que se llama lapiz, con
cantidad 200 y precio de 1,5.
INSERT INTO
Ejercicio 2.1: Insertar otro artículo: boli, con precio 2 euros y
cantidad 300.
INSERT INTO
Ejercicio 3: Ver los registros que acabamos de insertar.
SELECT ... FROM ...
Ejercicio 4: Ver la suma de la cantidad de bolis y lápices con una sola
query:
SELECT agregate_function
Se hace con la función sum(expression), donde expression es efectivamente
en este caso el nombre del campo. La función SUM es una de las muchas
funciones que agregan, es decir a partir de los valores de muchos campos
calculan un valor.
Ejercicio 4.1: Calcular el total de dinero que tenemos como artículos.
SELECT agregate_function
Solo hay que introducir una modificación en la query anterior.
Ejercicio 5: Cambiar el ID de Lapiz a 1 y el ID de Boli a 2.
UPDATE ... SET ID=.... WHERE ....
En este caso necesitamos de buscar y cambiar solo el (los) registros que
tienen nombre Lapiz y los que tienen nombre Boli. El resultado debería de
estar
+------+--------+--------+----------+
| ID
| nombre | precio | cantidad |
+------+--------+--------+----------+
|
1 | Lapiz |
1.5 |
200 |
|
2 | Boli
|
2 |
300 |
+------+--------+--------+----------+
Ejercicio 6: El resultado de una query (SELECT) es muy parecido a una
tabla. Crear una tabla e*_articulo_ext con un campo más que vamos a
llamar valor, que simplemente es precio*cantidad. Los tipos de los datos
no hay que darles expresamente porque estos se derivan de la query.
CREATE TABLE ... SELECT ....
Ver el resultado:
SELECT * from e*articulo_ext;
Ejercicio 7. Al no dar nombre explícito a la columna valor, la tabla
resulta con nombre de la columna que contiene el carácter * que no es
cómodo.
Borramos la tabla que hemos creado.
DROP TABLE e*_articulo_ext;
La operación será denegada -- el usuario alumno no puede quitar tablas
(por ejemplo las tablas del vecino :)
Ejercicio 8. Crear una nueva tabla llamada e*_art_ext con el nombre
correcto de la columna
CREATE TABLE ... SELECT ... exp AS alias ....
OJO: Tener tablas con columnas que simplemente son funciones de otras
columnas es contra productivo. Se da solo como ejemplo de CREATE TABLE.
El nombre de la columna no es valor. Para que sea valor tenemos que dar
un alias a precio
Ejercicio 9. Rellenamos los datos en varias tablas. Crear las tablas
e*_person y e*_pedido a partir de las tablas e99_person y e99_pedido.
Ver las primeras 10 líneas de cada tabla:
SELECT ... LIMIT ....
Ejercicio 10. Buscar todos los clientes que se llaman Jose... y tienen
apellidos que empiezan con ‘Jimenez’
Se utiliza el operador like:
nombre like 'Jose%'
El % sirve de la misma forma como * en expresiones
regulares de linux (ls Jose*).
Ejercicio 11. Encontrar los pedidos correspondientes a las personas que
empiezan con Maria y apellido Jimenez… . Imprimir la cantidad de cada
artículo que iban a comprar y el identificador del artículo. LEER EL
APARTADO DE WHERE EN W3SCHOOL. Apuntar el tiempo que tarda la query.
Para esto necesitamos dos tablas -- de pedido y de cliente. Dar alias de
pedido a y alias de person b.
select
... from
...,... WHERE
.... AND b.ID=a.ID_person ....;
Ejercicio 12. Encontrar la cantidad del dinero y el nombre el artículo
para cada cliente que empieza con 'Maria' y el apellido empieza con
‘Jimenez’. Para esto tenemos que unir tres tablas con la query. Una
persona puede ocurrir varias veces para diferentes artículos.
Efectivamente vamos a ver que el tiempo de ejecución es muy elevado.
Parar la query (ctrl-C) si no podeis esperar.
Ejercicio 13. AÑADIR INDICES:
Podéis ver que el rendimiento del sistema es muy bajo. Por eso hay que
añadir índices a las tablas y relaciones entre las tablas.
13.1. Añadir índices por cada uno de los campos de todas las tablas.
CREATE INDEX index_name ON table_name (column_name)
Ejecutar la misma query del ejercicio 12. Cuál es el impacto sobre el
rendimiento.
Ejercicio 14. Añadir restricciones:
El identificador de la persona y del artículo debería de estar únicos.
Por eso hay que añadir restricción de este campo:
Ejercicio 14.1.
ALTER TABLE e*_articulo ADD CONSTRAINT uc_article UNIQUE (ID);
Ejercicio 14.2.
El comando dará errores. Borrar el registro que sobra (son las entradas
con número 1 y 2:
DELETE FROM e*_articulo WHERE ID=.... AND .....;
Ejercicio 14.3. Añadir también la restricción de unicidad del campo ID de
la tabla 'person'.
Ejercicio 14.4. Añadir otra restricción que es sobre los campos
ID_persona y ID_articulo conjuntos en la tabla pedidos.
ALTER TABLE e*_pedido ADD CONSTRAINT uc_pedido UNIQUE (ID_...,ID_....);
Ejercicio 14.5. Añadir la restricción que el nombre del cliente no puede
estar vacio.
ALTER TABLE … MODIFY COLUMN columna tipo_de_datos NOT NULL.
Ejercicio 14.6. Añadir columna que representa la fecha de nacimiento de
la persona y tiene tipo de fecha.
ALTER TABLE ... ADD COLUMN ...
También añadir un campo observación para cada persona con una capacidad
de 2000 caracteres.
Ejercicio 15. Ejecutar las queries del punto 12 y medir el tiempo.
Ejercicio 16. Efectivamente en la tabla pedido ID_person del pedido
refiere una persona y por eso hay que decir que ID_person efectivamente
refiere el campo ID de la tabla person. Esto crea una estructura mas
eficiente si conectamos las dos tablas en una query.
Ejercicio 16.1. Añadir la referencia entre pedido y person.
ALTER TABLE ... ADD FOREIGN KEY ... REFERENCES ...
Ejercicio 16.2. Añadir la referencia entre artículo y pedido.
Ejercicio 16.3. Ejecutar la query del ejercicio 12. ¿Cuál es el
rendimiento?
Ejercicio 17. GROUP BY
Si queremos para cada cliente solo la suma de los artículos que hemos
comprado, esto estaría difícil de conseguirlo con lo que hemos hecho
hasta al momento.
Tenemos que hacer la query que combina los artículos y hacer la suma del
articulo.precio*pedido.cantidad pero agrupando los resultados por
cliente. Para este propósito se utiliza la construcción GRUOP BY conjunto
con una función de agregación (en este caso SUM()).
Construir una query que da el importe en pedidos para cada cliente que
tiene pedidos.
Ejercicio 18. Una lista ordenada por algún criterio se lee mejor.
ORDER BY
Ejercicio 18.2. Ordenar los resultados de la query del ejercicio 17 por
el nombre el cliente.
Ejercicio 18.3. Ordenar los resultados de la query por el nombre en orden
reverso y solo para los clientes cuyo nombre empieza con 'Jose'.
Salir del mysql GUARDANDI EL LOG.
Los siguientes dos ejercicios se ejecutan contra la base de datos
qetu159_ds y sirven para hacer la práctica. Si les interesan los ficheros
fuentes de la tabla Word_text podeis encontrarles en
150.244.59.74/~kostadin/20_newsgroup/<nombre de fichero>.
Por ejemplo:
http://150.244.59.74/~kostadin/20_newsgroup/sci.space/59848
Ejercicio 19. En la tabla word_text:
19.1 Contar cuantas entradas hay
COUNT.
19.2. Contar cuantas palabras se refieren.
19.3. Dar la lista de los ficheros distintos.
19.4. Contar cuantos ficheros distintos hay
SELECT DISTINCT
19.5. Contar en cuantos ficheros aparece la palabra 'mars'.
19.5.1. Contar en cuantos ficheros aparece cada palabra.
19.6. Contar cuantas veces aparece la palabra mars en todos los ficheros.
19.7. Contar cuantas palabras hay en cada fichero.
19.8. Contar cuantas palabras promedio hay en cada fichero.
Ejercicio 20. Hacer tablas auxiliares para queries frecuentes. Estas
tablas habitualmente se hacen temporales (CREATE TEMPORARY TABLE …).
Esto está en contradicción con el modelo normalizado de datos, pero si
sirve para tener un rendimiento razonable.
20.1. Hacer una tabla e*_word_cnt donde están todas las características
para cada palabra que se necesitan para calcular la formula BM25.
20.2. Hacer una tabla e*_file_cnt donde están todas las características
para cada fichero que se menciona en la formula BM25.
20.3. Hacer las relaciones entre e*file_cnt y e*word_cnt y e*word_text.
20.3. Hacer una tabla e*_otros para todas las características globales
que necesitamos para la formula BM25 (número ficheros, etc.).
20.4. Documentar las queries y hacer un PHP que las ejecuta.
20.5. Utilizar estas queries para calcular BM25 Okapi sobre 4 palabras
que buscamos y que el resultado de la formula sea un campo de la query.
20.6. Ordenar los resultados de 20.5 por el valor de la formula.
ATENCION: El punto 6 de la práctica 1 se hace más fácil utilizando varias
queries y programando en PHP. Si utilizamos tablas hay que utilizar
tablas temporales.
Descargar