Anda di halaman 1dari 6

Una arquitectura de esquemas para

una aplicación Oracle


Introducción
Cada vez que iniciamos un proyecto de desarrollo de una aplicación centrada en una base de datos Oracle un
aspecto muy importante a considerar es la arquitectura de usuarios y esquemas que vamos a utilizar.
Necesitamos definir cómo vamos a organizar nuestros objetos dentro de la base de datos. Algunos de los
aspectos que tenemos que resolver son:

 ¿Cómo vamos a ordenar las tablas, vistas y secuencias?


 ¿Cómo vamos a organizar los procedimientos almacenados, funciones y paquetes?
 ¿Qué usuarios van a acceder a nuestra base y qué privilegios tendrán?

En este artículo quiero presentar un prototipo básico que atenderá a dar respuesta a todos estos aspectos. De
ninguna manera pretendo aquí plantear una solución definitiva. Por el contrario, mi objetivo es proponer un
punto de partida que podrá ser aumentado y enriquecido en cada situación y entorno particular.

¿Esquemas juntos o separados?


Una de las primeras disyuntivas que surge es: ¿Debemos tener tablas y programas en un mismo esquema? ¿O
nos conviene tenerlos separados?
¿Unimos o separamos objetos y programas? 1

A priori la respuesta parecería ser que debemos mantener todo en un mismo esquema; si los separamos
estaríamos contrariando los conceptos de encapsulamiento. Y además estaríamos agregando tareas
administrativas para el manejo de esquemas y privilegios.

Sin embargo, si analizamos un poco más, comenzaremos a encontrar varias ventajas de la opción de
separación de esquemas:

 Mayor seguridad: el acceso a los objetos deberá ser solicitado y justificado. Adicionalmente los privilegios
quedarán documentados automáticamente en el diccionario de datos.
 Separación de roles: los programas serán accedidos por los desarrolladores, los objetos serán administrados y
mantenidos por un “Administrador de datos” o por el DBA.
 Disminución de riesgos: los programas no podrán truncar, ni eliminar tablas, vistas, índices, etc. De ser
necesario hacer operaciones de este tipo, se podrá analizar el caso particular y asignar el privilegio necesario
pudiendo administrarlo con un alto nivel de granularidad.

Dicho esto, me inclino por la alternativa de esquemas separados.

A fin de ejemplificar, supongamos que empezamos un proyecto de desarrollo de un sistema de CRM


(Customer Relationship Management). Crearemos entonces una cuenta de usuario llamada CRMOBJ para los
objetos y una cuenta de usuario llamada CRMPRG para los programas.

Privilegios por defecto


Una vez que he optado por el uso de esquemas separados, necesito definir los privilegios a asignar por
defecto. Continuando con el ejemplo, cada vez que creo un objeto en el esquema CRMOBJ, deberé asignar
los siguientes privilegios al esquema CRMPRG:

 Consult
 Inserción
 Actualización
 Eliminación

Supongamos que acabamos de crear la tabla CASOS en el esquema CRMOBJ. Luego ejecutaremos el
siguiente código SQL:

GRANT SELECT, INSERT, UPDATE, DELETE ON CASOS TO CRMPRG;


A partir de allí, el usuario CRMPRG podrá acceder a la tabla de CASOS desde sus programas, pero estará
limitado a ejecutar solamente las operaciones DML básicas. Los objetos estarán protegidos y no podrán ser
eliminados ni truncados desde los programas.

Finalizados los programas que componen la aplicación. ¿Quién los ejecuta?

Uso de la aplicación
Dependiendo de la arquitectura de la aplicación habrá al menos dos posibles tipos de conexión a la base de
datos:

 Cuenta de usuario genérico en caso de aplicaciones web o de tres capas (crearíamos un usuario CRMAPP en
nuestro ejemplo)
 Cuentas personalizadas para el caso de aplicaciones cliente/servidor

Estas cuentas sólo pueden modificar datos a través de la ejecución de los programas creados por la cuenta de
programas, asegurando las reglas de negocio definidas en los procedimientos almacenados, funciones y
paquetes. Para las ejecución de consultas SQL, estás cuentas disponen de privilegios de SELECT sobre los
objetos pertenecientes al esquema de objetos. Para facilitar la administración, los privilegios de ejecución y de
consulta se asignan a través de roles.

El usuario de aplicación no dispone de objetos propios. Cuenta pura y exclusivamente con privilegios de
ejecución y consulta.

La arquitectura global de cuentas de aplicación, programas y objetos queda de la siguiente manera:

 La aplicación accede a la base con una cuenta de usuario que será genérica (web) o personalizada
(cliente/servidor)
 La cuenta de usuario para la aplicación solamente puede:
o Ejecutar los procedimientos, funciones y paquetes creados con la cuenta de programas
o Consultar los objetos de la cuenta de objetos
 La cuenta de usuario para los programas solamente puede:
o Crear procedimientos, funciones y paquetes
o Modificar los datos pertenecientes a la cuenta de objetos
 La cuenta de usuario creada para objetos:
o Es dueña de las tablas, vistas, secuencias, índices, etc.
Sinónimos
Al separar los esquemas se plantea la necesidad de definir como referenciar a los objetos. ¿Los referenciamos
anteponiendo el esquema? ¿Utilizamos sinónimos privados? ¿Utilizamos sinónimos públicos? Cada elección
tiene sus ventajas y desventajas, en cada situación particular habrá que ponerlas en la balanza y elegir la mejor
opción:

 Los sinónimos públicos pueden ser problemáticos si tenemos varias aplicaciones en la misma base y se
repiten los nombres de objeto.
 Anteponer el nombre del owner de los objetos dentro de los programas puede resultar complicado en
situaciones en que utilicemos una misma base de datos para varias versiones de la misma aplicación (por
ejemplo desarrollo y test)
 Los sinónimos privados podrían no ser deseables en aplicaciones cliente servidor donde es necesario crear
muchas cuentas de usuario de aplicación.

Vistas
En este artículo hemos optado por considerar las vistas como objetos similares a las tablas y, por lo tanto, las
hemos incluido en el esquema de objetos. También es cierto que las vistas, en definitiva, son código SQL y
por lo tanto también es válido incluirlas en el esquema de programas. Y, en el último de los casos, tampoco
sería incorrecto optar por un esquema híbrido con vistas en ambos esquemas.

Ejemplo
Creación del usuario de objetos
create user CRMOBJ identified by PWDCRMOBJ
default tablespace CRMOBJ_DATA
temporary tablespace TEMP
/
Creación de usuario de programas

create user CRMPRG identified by PWDCRMPRG


temporary tablespace TEMP
/
Creación del usuario de aplicación

create user CRMCAPP identified by PWDCRMAPP


temporary tablespace TEMP
/
Asignación de privilegios para creación de objetos

grant create session to CRMOBJ


/
grant create session to CRMPRG
/
grant create session to CRMAPP
/
grant create table to CRMOBJ
/
grant create view to CRMOBJ
/
grant create index to CRMOBJ
/
grant create sequence to CRMOBJ
/
grant create public synonym to CRMOBJ
/
grant create trigger to CRMOBJ
/
grant create procedure to CRMPRG
/
grant create public synonym to CRMPRG
/
Creación y asignación de roles

create role ROLE_CRM_READ


/
create role ROLE_CRM_EXECUTE
/
grant ROLE_CRM_EXECUTE to CRMAPP
/
grant ROLE_CRM_READ to CRMAPP
/
Cada vez que se crea una tabla con el usuario CRMOBJ

grant select on [tabla] to ROLE_CRM_READ


/
grant select, insert, update, delete on [tabla] to CRMPRG
/
create public synonym [tabla] for CRMOBJ.[tabla]
/
Cada vez que se crea una vista o secuencia
grant select on XXX to ROLE_CRM_READ
/
grant select on XXX to CRMPRG
/
create public synonym XXX for CRM.XXX
/
Cada vez que se crea un programa

grant execute on ZZZ to ROLE_CRM_EXECUTE


/
create public synonym ZZZ for CRMPRG.ZZZ
/