Prácticas del Curso BDII Carlos Alberto Olarte (carlosolarte@puj.edu.co) Julio 2003 Índice general 1. Introducción 4 2. Bases de Datos Distribuidas 2.1. Prerequisitos . . . . . . . . . . . . . . . . . . . 2.2. Descripción del problema . . . . . . . . . . . . . 2.3. Metodologı́a . . . . . . . . . . . . . . . . . . . . 2.4. Sintaxis . . . . . . . . . . . . . . . . . . . . . . 2.4.1. Creación de DB Links . . . . . . . . . . 2.4.2. Creación de los M aterialized V iew Log 2.4.3. Creación de las M aterialized V iew . . . 2.4.4. Refresco de las Vistas Materializadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 5 5 5 6 6 6 7 7 3. CORBA 3.1. Prerequisitos . . . . . . 3.2. Descripción . . . . . . . 3.3. Diseño (IDL) . . . . . . 3.4. Implementación . . . . . 3.4.1. ReceptorServant . 3.4.2. EmisorServant . . 3.4.3. AppServidor . . . 3.4.4. AppReceptor . . 3.4.5. AppEmisor . . . 3.5. Puesta en Marcha . . . . 3.6. Algunas Modificaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 8 8 8 10 10 10 10 10 10 10 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4. Optimización de Consultas 12 5. Tipos de Dato Multimedia 5.1. Prerequisitos . . . . . . . . . . . . . 5.2. Metodologı́a . . . . . . . . . . . . . . 5.3. Aspectos Importantes en el código . . 5.3.1. Escritura de la imagen . . . . 5.3.2. Recuperación de la Imagen . . 5.4. BLOB en Postgresql . . . . . . . . . 5.4.1. Inserción de un objeto binario 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 14 14 15 15 15 15 16 ÍNDICE GENERAL 5.4.2. Recuperación de los objetos . . . . . . . . . . . . . . . . . . . . 5.5. Ejercicio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6. OLAP 2 16 16 17 Índice de figuras 6.1. E/R Banco ABC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 18 Capı́tulo 1 Introducción El siguiente documento presenta una serie de prácticas que se deben realizar durante el curso de Bases de Datos II, con el fin de fortalecer la teorı́a vista en clase y adquirir habilidades en la implementación de Bases de Datos distribuidas y Sistemas distribuidos con ayuda del estándard CORBA. Adicionalmente, se pretende que es estudiante interactue con un SGBD por medio de un lenguaje de programación como Java, PHP, Python, etc. 4 Capı́tulo 2 Bases de Datos Distribuidas El siguiente taller pretende que el estudiante diseñe e implemente un sistema distribuido de bases de datos 2.1. Prerequisitos 1. Cliente SSH (http://escher.puj.edu.co/ colarte/Utils/ssh-win.exe) 2. Instancias lab, lab2 y lab3 de Oracle 3. $ORACLE HOME/network/admin/tnsnames.ora configurado correctamente 2.2. Descripción del problema La compañı́a de televisión por cable ”Mundo TV” cuenta con oficinas en las ciudades de Bogotá, Lima y Caracas. Ellos mantienen información de los planes de televisión que venden (Plan Básico, Plan Premium, etc) que son los mismos para todas las sucursales y los clientes son locales para cada ciudad. Sin embargo, en la sucursal de Bogotá normalmente llegan llamadas a la lı́nea 9800 atendiendo reclamos, cambios de planes, etc para todos los usuarios. Se debe diseñar e implementar el sistema distribuido, de tal manera que la mayorı́a de consultas puedas ser ”locales”mejorando el desempeño del sistema. 2.3. Metodologı́a 1. Diseñe el esquema lógico global de la aplicación, es decir, el diagrama ER que integre todas las relaciones a construir como si fuera una base de datos centralizada 2. Construya los esquemas lógicos locales, es decir seleccione qué relaciones va a replicar, cuales va a fragmentar y en que nodo van a residir cada una de ellas. Tenga presente que solo cuenta con tres posibles emplazamientos para la práctica 5 CAPÍTULO 2. BASES DE DATOS DISTRIBUIDAS 6 3. Cree las tablas maestras en cada uno de los emplazamientos que corresponda 4. Implemente su sistema distribuido. Recuerde que debe: a) Crear los Data Base Link b) Crear los materialized view log sobre las tablas maestras c) Crear las réplicas o fragmentos (materialized view ) en los emplazamientos remotos 5. Adicione algunos datos de prueba sobre su sistema. Compruebe que todos los nodos sean capaces de ver los mismos planes y que la ciudad de Bogotá tenga acceso a todos los clientes de la compañı́a. Modifique los planes en la tabla maestra y verifique su actualización en las réplicas. 2.4. 2.4.1. Sintaxis Creación de DB Links CREATE DATABASE LINK DBLINK1 CONNECT TO CC10001 IDENTIFIED USING ’CHIEF2’; BY CC10001 En este caso, DBLIN K1 es el nombre del Database link, CC10001 es el login y password (identified by) del usuario de la instancia de la base de datos a la que se conectará y CHIEF 2 es el string de conexión utilizado en el archivo tnsnames.ora para rederirse en la base de datos. En este caso, CHIEF2.PUJ.EDU.CO= (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.6.3)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = lab2) ) ) Para probar el Database link, se puede ejecurtar: SELECT * 2.4.2. FROM CAT@DBLINK1; Creación de los M aterialized V iew Log CREATE MATERIALIZED VIEW LOG ON EMP WITH PRIMARY KEY; En este caso, se crea un Log de Vista Materializada sobre la tabla EM P . CAPÍTULO 2. BASES DE DATOS DISTRIBUIDAS 2.4.3. 7 Creación de las M aterialized V iew Las vistas materializadas son creadas en el emplazamiento remoto en dónde se creó el Database Link. Por ejemplo: CREATE MATERIALIZED VIEW EMPREPLICA REFRESH FAST START WITH SYSDATE NEXT SYSDATE + 1/60 WITH PRIMARY KEY AS SELECT * FROM EMP@DBLINK1; 2.4.4. Refresco de las Vistas Materializadas Para refrescar las vistas materializadas manualmente, se puede hacer uso del paquete dbms ref resh de la siguiente forma: BEGIN DBMS_REFRESH.REFRESH(’EMPREPLICA’); END; / Capı́tulo 3 CORBA El siguiente taller pretende que el estudiante implemente un pequeño sistema distribuido con ayuda del estándar CORBA y su implementación en el JSDK2 3.1. Prerequisitos 1. JDK1.3 o superior. (Puede ser en el servidor) 2. Cliente SSH 3. Make 4. TGZ con los archivos de la práctica 3.2. Descripción Se desea implementar un sistema de mensajerı́a en el que se crea un emisor desde el cual se pueden enviar mensajes a una serie de receptores conectados al mismo. Los mensajes pueden ser cadenas de caracteres, enteros o el envı́o de un archivo (arreglo de bytes). 3.3. Diseño (IDL) Con el enunciado anterior, se puede construir el siguiente IDL: module Mensajerı́a { /** * Definicion de una excepcion */ exception MensajeriaException {}; 8 CAPÍTULO 3. CORBA 9 /** * Definición de un arreglo de bytes */ typedef sequence<octet> ByteArray ; /** * Objeto encargado de recibir mensajes */ interface Receptor { // Recepción void recibirLong(in long Mensaje) raises (MensajeriaException); void recibirString(in string Mensaje) raises (MensajeriaException); void recibirArchivo(in ByteArray Mensaje) raises (MensajeriaException); }; /** * Objeto encargado de enviar mensajes */ interface Emisor { readonly attribute long NumMensajesEnviados; readonly attribute long NumReceptores; // Emision long enviarLong(in long Mensaje) raises (MensajeriaException); long enviarString(in string Mensaje) raises (MensajeriaException); long enviarArchivo(in ByteArray Mensaje) raises (MensajeriaException); // Cierre de un receptor void close (in Receptor R) raises (MensajeriaException); // Adicion de un receptor void add(in Receptor R) raises (MensajeriaException); }; }; Como se puede observar, se cuenta con un objeto receptor con sus métodos para recibir cada uno de los tres tipos de mensajes y un objeto emisor con métodos para enviar los mensajes y adicionar/eliminar receptores. CAPÍTULO 3. CORBA 3.4. 3.4.1. 10 Implementación ReceptorServant Implementación de los métodos del Receptor descrito en el IDL. En este caso, cuando se recibe un entero o una cadena, simplemente se imprime su valor en pantalla y en el caso de archivos, se almacena localmente con el nombre MensajeX donde X se incrementa con cada nuevo archivo que llega. 3.4.2. EmisorServant Implementa los métodos del objeto Emisor. Mantienen un vector de receptores para enviar los mensajes. Observe que cuando se envı́an mensajes hay la posibilidad de que el cliente se haya desconectado, por tanto, se encierra dentro de un try − catch. 3.4.3. AppServidor Se encarga de instanciar un objeto tipo Emisor con ayuda de la clase EmisorServant para posteriormente registrarlo en el servicio de nombre 3.4.4. AppReceptor Por medio del servicio de nombre obtiene una referencia del objeto Emisor creado (si existe) y luego crea un objeto Receptor por medio de ReceptorServant. Luego adiciona al emisor el nuevo receptor y queda a la espera de los mensajes. 3.4.5. AppEmisor Se encarga de obtener una referencia del objeto emisor con ayuda del servicio de nombres, y dependiendo de los argumentos de la lı́nea de comandos, se envı́a un mensaje por medio del emisor. 3.5. Puesta en Marcha 1. Correr el servicio de nombre $>tnameserv -ORBInitialPort 2020 2. Correr AppServidor para instanciar un Emisor: $>java AppServidor -ORBInitialPort 2020 -PRBInirialHost X En esta caso X debe ser la dirección IP dónde se está corriendo el servicio de nombres (si se omite se asume localhost) CAPÍTULO 3. CORBA 11 3. Correr uno o dos Receptores por medio de : $>java AppReceptor -ORBInitialPort 2020 -PRBInirialHost X Nuevamente X es el servidor donde corre el servicio de nombres. 4. Finalmente ejecutar AppEmisor y enviar diferentes mensajes de la siguiente forma: $>java AppEmisor -ORBInitialPort 2020 -PRBInirialHost X STRING "HOLA" $>java AppEmisor -ORBInitialPort 2020 -PRBInirialHost X INT 3 $>java AppEmisor -ORBInitialPort 2020 -PRBInirialHost X FILE Arch.txt Los mensajes enviados deben ser escuchados por los receptores creados. Trate de que los receptores se ejecuten en máquinas diferentes a dónde se ejecuto AppServidor. 3.6. Algunas Modificaciones Modifique el ejemplo anterior de tal forma que el emisor implemente un método que retorne la lista (arreglo) de receptores conectados al mismo. Luego implemente los métodos de envio de mensajes pero brindánde la posibilidad de seleccionar (en un arreglo) los receptores a los cuales les debe llegar el mensaje (mensajes en privado) Capı́tulo 4 Optimización de Consultas El siguiente taller pretende que el estudiante verifique los métodos de evaluación de consultas vistos en clase y compruebe cómo se pueden optimizar las consultas en una base de datos relacional. Para cada una de las consultas que se presentan a continuación, se debe escribir el plan de ejecución esperado para la misma, para posteriormente verificarlo con la herramienta tkprof de Oracle. 1. Crear las siguientes Tablas sin crear las restricciones de llaves primarias y foráneas: Universidad (#Codigo,Nombre), Facultad (#Codigo, Nombre, Uni_Codigo) Estudiante (#Codigo, Nombre, Fac_Codigo) Y las siguientes secuencias: SEC_UNIVERSIDAD SEC_FACULTAD SEC_ESTUDIANTE 2. Adicione 3 Universidades, 5 Facultades por universidad y 100 estudiantes por cada facultad de cada carrera. Puede utilizar el siguiente script en PL/SQL DECLARE I NUMBER; Begin FOR I IN 1..10 LOOP INSERT INTO ESTUDIANTE....; END LOOP; END; . / 12 CAPÍTULO 4. OPTIMIZACIÓN DE CONSULTAS 13 3. Ejecute ALTER SESSION SET SQL TRACE=TRUE; y luego SELECT ’MI NOMBRE’ from DUAL; para saber cual es el archivo TRC generado por su sesión 4. Realice una consulta de igualdad sobre el código y luego sobre el nombre de las facultades. 5. Cree todas las llaves primarias y las foráneas ası́ como un ı́ndice sobre el nombre de la facultad y ejecute nuevamente las consultas del numeral anterior . Sugerencia: La creación de ı́ndices y de las llaves realı́celas en otra terminal para no contaminar el archivo trace. 6. Ejecute una reunión natural entre las 3 relaciones, proyectando el nombre del estudiante, su facultad y la universidad. 7. Adicione a su consulta anterior, un criterio de selección sobre el nombre del estudiante 8. Ejecute una consulta conjuntiva entre el código del estudiante y su nombre 9. Ejecute una consulta disyuntiva entre el código del estudiante y su nombre 10. Escriba un ı́ndice que mejore el desempeño de la consulta del numeral anterior y vuelva a ejecutar su consulta. 11. Cierre la sesión SQL. Entre al directorio $ORACLE BASE/admin/lab/udump y ejecute grep -i ”MI NOMBRE”*.trc para encontrar el archivo correspondiente a su sesión 12. Ejecute tkprof miarchivo.trc /tmp/minombre.output para generar el archivo explicado y compruebe sus suposiciones acerca del plan de ejecución de las consultas Vs los utilizados por el gestor de transacciones de la base de datos. Capı́tulo 5 Tipos de Dato Multimedia El siguiente taller pretende que el estudiante practique la utilización de tipos BLOB dentro de la base de datos para almacenar contenido multimedia 5.1. Prerequisitos 1. Cliente SSH instalado (http://escher.puj.edu.co/ colarte/Utils/ssh-win.exe) 2. Instancia Lab de Oracle 3. JDK1.3 o superior instalado (puede ser en el servidor) 4. JAR o ZIP con las clases del JDBC para Oracle 9i 5. 2 o 3 archivos JPG 6. Archivos (.java) de la práctica (http://escher.puj.edu.co/ colarte/bdatos2/... 7. Instancia de Postgresql 8. JAR o ZIP con las clases del JDBC para Postgresql 5.2. Metodologı́a 1. Cree la siguiente tabla en la base de datos: CREATE TABLE ANIMALES ( CODIGO NUMBER PRIMARY KEY, NOMBRE VARCHAR2(50) NOT NULL, FOTO BLOB); 2. Cree la secuencia para el código del Animal: CREATE SEQUENCE SEC_ANIMALES; 14 CAPÍTULO 5. TIPOS DE DATO MULTIMEDIA 15 3. Compile las clases de java de la práctica y utilice el main de la clase Animal para adicionar algunos animales y luego visualı́celos con la clase AnimalViewer 5.3. 5.3.1. Aspectos Importantes en el código Escritura de la imagen La escritura de la imagen se realiza obteniendo una referencia del BLOB almacenando, y escribiendo en su flujo de salida. Observe que para realizar la inserción se hace uso del procedimiento empty blob() de Oracle para especificar un BLOB vacı́o y luego se hace un Select for update para modificar el BLOB almacenado como se muestra a continuación: // Inserción del Registro St.executeUpdate("INSERT INTO ANIMALES(CODIGO,NOMBRE,FOTO) " + "VALUES (" + Codigo + ",’" + Nombre + "’,empty_blob())"); // ... // Recuperar el registro Rs = St.executeQuery("Select foto from ANIMALES " + " where codigo = " + Codigo + " FOR UPDATE"); // ... // Obtener la referencia al BLOB // y escritura del arreglo de bytes B = ((OracleResultSet)Rs).getBLOB(1); B.getBinaryOutputStream().write(Foto); 5.3.2. Recuperación de la Imagen La recuperación se realiza obteniendo una referencia al BLOB y luego extrayendo su arreglo de bytes de la siguiente forma: ResultSet Rs = St.executeQuery("Select Nombre, Foto from Animales " + " where Codigo = " + Codigo); // ... // Recuperación del BLOB Blob b = Rs.getBlob(2); this.Foto = b.getBytes((long)1,(int)b.length()); 5.4. BLOB en Postgresql Postgresql también ofrece tipos de datos para almacenar datos binarios. Uno de ellos es el tipo OID que permite almacenar una referencia a un objeto binario almacenado. CAPÍTULO 5. TIPOS DE DATO MULTIMEDIA 5.4.1. 16 Inserción de un objeto binario Haciendo uso de la clase PreparedStatement es posible realizar dicha inserción de la siguiente forma: PreparedStatement St = Con.prepareStatement( "INSERT INTO PALABRAS (PALABRA, IMAGEN) VALUES (?,?)"); org.postgresql.largeobject.LargeObjectManager lobj = ((org.postgresql.Connection)Con).getLargeObjectAPI(); int oid = lobj.create(LargeObjectManager.READ | LargeObjectManager.WRITE); LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE); // Escritura en el blob de un arreglo de bytes obj.write(Imagen); obj.close(); // Modificación del parámetro 2 de la consulta St.setInt(2, oid); //... St.executeUpdate(); Como se puede ver, se crea una instancia de un Manejador de OIDs, luego se crea un OID (que es el id del objeto binario) y luego se crea el objeto binario para escribir en el mismo. Finalmente se modifica el Statement en su segundo atributo y se ejecuta la sentencia. 5.4.2. Recuperación de los objetos ResultSet rs = Sr.executeQuery("Select Imagen from Palabras where codigo=4); int oid = rs.getInt(1); LargeObject obj = lobj.open(oid, LargeObjectManager.READ); byte buf[] = new byte[obj.size()]; obj.read(buf, 0, obj.size()); obj.close(); En este caso se recupera el OID y luego se construye un Objeto Binario con el mismo. Finalmente se obtiene el contenido del objeto con el método read. 5.5. Ejercicio Implementar la aplicación de Animales escrita para Oracle para que funcione en Postgresql. Capı́tulo 6 OLAP Este taller pretende que el estudiante práctique el uso de instrucciones OLAP, para implementar consultas análiticas sobre una base de datos relacional El banco ABC cuenta con un sistema de base de datos con el siguiente modelos E/R: Genere el script de instalación de tablas y de datos básicos para el MER y luego construya las consultas SQL para extraer la información que se solicita a continuación: 1. El total de las cuentas bancarias por ciudad , sucursal y región 2. El total de las cuentas creadas en el mes anterior por dı́a y por semana 3. Clasificar las cuentas de mayor a menor según el número de transacciones que han efectuado en el último mes 4. Clasificar de mayor a menor según el monto, las transacciones de una cuenta X de acuerdo si son retiros o depósitos 5. Construir un histograma que clasifique todas las cuentas según el monto en 10 partes iguales 6. Construir una curva que muestre el monto acumulado durante un periodo de tiempo X para una cuenta Y 7. Construir una tabla dinámica en dónde se pueda seleccionar la ciudad y que muestre el número de cuentas creadas por cada sucursal en cada mes del año en curso 8. Construir un cubo en el que se muestre por mes del año, sucursal y tipo (D/R) el monto de las transacciones efectuadas por las cuentas 17 CAPÍTULO 6. OLAP 18 Figura 6.1: E/R Banco ABC Cod _ Region Nom Cod Departamento Nom _ Cod Ciudad Nom Sucursal _ Cod Nom _ _ Id Cliente cc Nom Cuenta Num C/D Id _ Fecha Fecha Transacción C/R $ Saldo