Archive for the ‘Base de Datos’ Category

El significado tras el 99.999% de uptime

jueves, octubre 14th, 2010

Por lo general es común ver que ciertos servicios de internet ofrecen el 99.999% de uptime, pero ¿que significa?

Si el servicio ofrece el 90% de uptime, implica que 35 días al año el servicio esta bajo, si ofrece el 99% implican más o menos 4 días sin servicio. Cuando llegamos a los decimales, o sea, el 99.9% de uptime, significa sólo 8horas de downtime, el 99.99% sólo 50 minutos, y el 99.999% significa que sólo 5 minutos al año estará sin servicio. En general esto es parte del contrato de servicios cuando se definen los SLA (Service Level Agreement).

Es importante saber que es imposible comenzar a ofrecer un 99.999% si es que asociado a ello no existe un cluster de servidores.

Oracle SQL Developer Data Modeler ahora es libre

miércoles, octubre 13th, 2010

SQL Developer Data Modeler ofrece una herramientas de modelado de bases de datos y de servicios, incluyendo el modelado de diagramas entidad-relación (ERD), modelo relacional (diseño de base de datos), el tipo de datos y modelado multidimensional, con «roundtrip engineering» y la generación de código de DDL . Las importaciones Data Modeler y exportaciones a una variedad de destinos, ofrece además una variedad de opciones de formato y valida los modelos a través de un conjunto predefinido de reglas de diseño.

Oracle SQL Developer Data Modeler puede conectarse a cualquier base de datos Oracle y es independiente de la plataforma. Además tiene una versión de sólo lectura SQL Developer Data Modeler Viewer y también está disponible para su descarga.

Encuentra más información en https://www.oracle.com/technetwork/developer-tools/datamodeler/overview/index.html

Uso de SQL_TRACE

martes, julio 20th, 2010

Primero hay que alterar la sesion

ALTER SESSION SET SQL_TRACE=TRUE

Luego de esto se generará un archivo extensión *.trc dentro de la carpeta de oracle, en mi caso

%ORACLE_HOME%\admin\%ORACLE_SID%\udump

Luego se debe utilizar la aplicación de oracle TKPROF, una ejecusion básica sería

TKPROF archivo_trc nombre_archivo_output SYS=NO EXPLAIN=USER/PASSWORD

Y luego de eso te genera un archivo (nombre_archivo_output) con las consultas analizadas, tiempo de CPU, cantidad de ejecuciones, lecturas a disco y otros. En mi caso por ejemplo

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute   9758      0.09       0.16          0          0          0           0
Fetch     9758      0.21       0.24          0      39032          0        9758
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    19517      0.31       0.41          0      39032          0        9758

Moviendo hacia otro tablespace tablas e índices en oracle

miércoles, julio 7th, 2010

Para mover una tabla y/o indice de un tablespace a otro se debe aplicar un ALTER como los siguientes

ALTER TABLE NOMBRE_ESQUEMA.NOMBRE_TABLA MOVE TABLESPACE NOMBRE_TABLESPACE;
ALTER INDEX NOMBRE_ESQUEMA.NOMBRE_INDICE REBUILD TABLESPACE NOMBRE_TABLESPACE;

Se puede utilizar un script (si tienes privilegios sobre las tablas) para poder armar este movimiento de tablas desde un esquema a otro. La primera selecciona toda la lista de tablas pertenecientes a un esquema y construye el SQL que ya fue mostrado. La seguna construye toda la tabla de indices.

select 'ALTER TABLE NOMBRE_ESQUEMA.' || table_name || ' MOVE TABLESPACE NOMBRE_TABLESPACE;' from all_tables where owner = 'NOMBRE_ESQUEMA'
select 'ALTER INDEX NOMBRE_ESQUEMA.' || index_name || ' REBUILD TABLESPACE NOMBRE_TABLESPACE;' from all_indexes where table_owner = 'NOMBRE_ESQUEMA'

Modelamiento de base de datos

sábado, junio 19th, 2010

Introducción

Siempre existen diferencias al momento de modelar bases de datos, ya sea por la forma en cómo se fue educado en esta área, como las costumbres que se fueron adoptando en la vida laboral. Es por eso que muchas veces se necesitan acuerdos y/o restricciones del como modelar ciertas características de las bases de datos, esto para que se logre una estandarización del trabajo.
La estandarización es compleja, lo más complicado es prever un estándar que apoye la velocidad de desarrollo, que de la posibilidad de encuentro rápido de errores y que pueda ser ‘leído’ de una forma similar por todos los que participan del desarrollo y mantención.
Se presenta un trabajo sobre el modelamiento de bases de datos y la aplicación de estándares dentro del modelamiento.

Nombramiento

Nombramiento de tablas

El nombre de la tabla debe ser representativo para la entidad en cuestión, tratando de evitar la ambigüedad. El nombre debe ser en singular si la clave primaria se conforma de un campo, se utilizará plural cuando exista una clave compuesta, ya que esto indica que existe un concepto que se repite más de una vez dentro de la tabla, ese concepto es el que debiese estar en plural.

En el ejemplo se representa lo descrito anteriormente, se puede discutir sobre el nombre de la tabla que relaciona a ambas, esto porque el nombre es CATEGORIAS_CLIENTES, esto implica a primera vista que un cliente puede estar en muchas categorías, y una categoría puede contener muchos clientes. Si el nombre fuese cambiado por ejemplo a CATEGORIA_CLIENTES, significaría que una categoría puede tener muchos clientes y un cliente solo podría estar en una categoría. Si se dan cuenta existe la sutileza que la tabla CATEGORIA_CLIENTES tendría la misma estructura de CATEGORIAS_CLIENTES, si la dibujásemos serían idénticas. Debido a que la estructura de la tabla lo permite, igualmente podríamos introducir varios clientes a varias categorías y cada categoría contener más de un cliente, por lo mismo, para lograr el uso correcto con el significado que se le está dando al nombramiento se debiese generar un trigger que hiciese respetar el significado que le deseamos dar al modelamiento.

Prefijo del nombre de la tabla

En general las tablas no debiesen tener ningún prefijo específico, sobre todo cuando existe un buen manejo de esquemas o bases de datos en general. Por ejemplo, cuando se crea un esquema por cada negocio o escenario que se atiende tendríamos separadas las tablas en su esquema o base de datos respectiva, por ejemplo: CONTABILIDAD, INVERSIONES, TESORERIA, etc.
La necesidad de prefijo surge cuando, por ejemplo, al desarrollar el sistema de inversiones, que ocupa el esquema o base de datos INVERSIONES te establecen la restricción de no escribir directamente al esquema CONTABILIDAD, por lo que debes generar tablas de paso en tu esquema de base de datos, para luego, por algún otro proceso enviar los datos hacia el esquema de CONTABILIDAD. Otro punto en donde se genera la necesidad de un prefijo es cuando por algún motivo tenemos solo una base de datos o esquema disponible, la mayoría de las veces por algún tipo de restricción del cliente, así la posibilidad de que el escenario que estamos evaluando tenga muchos subescenarios distintos dentro del mismo desarrollo surge la necesidad de dar un prefijo asociado en la tabla, para tener un mayor orden tanto en la lectura del modelo, así como en la utilización de este, ya que con lectores o administradores de bases de datos disponibles las tablas con el mismo prefijo te saldrán agrupadas por culpa de su ordenamiento alfabético. Por ejemplo:

Prefijo para las tablas del escenario contabilidad CNT_
Prefijo para las tablas del escenario inversiones INV_
Prefijo para las tablas del escenario facturación FCT_

En general es bueno utilizar de tres a cuatro letras para la identificación del escenario, para decidir que letras también hay que proveer una estructuración para que dos personas siempre lleguen a prefijos similares; por ejemplo la siguiente: mantener la primera letra con que se nombra al escenario, sea vocal o consonante, luego de eso sólo ocupo las consonantes, a menos que se diera el caso que el escenario este compuesto de dos palabras en donde trato de ocupar la primera letra de la primera palabra y luego las consonantes de la segunda palabra siguiendo las consideraciones ya explicadas. Ejemplos de utilización de la norma de nombramiento:

CONTABILIDAD prefijo CNT
CONTABILIDAD_TESORERIA prefijo CTS
INVERSIONES prefijo INV
INVERSIONES_RESUMIDAS prefijo IRS

Siguiendo esta fórmula es fácil hacer que un grupo de diseñadores llegue siempre a nombres similares.

Tablas temporales

En más de una oportunidad existe la necesidad de generar tablas temporales, para datos que son de paso, nótese que es temporal para el caso de los datos, no para el caso de la estructura, o sea, no es que se elimine la tabla para luego construir la misma pero con otra estructura (créanme que ese tipo de solicitudes existen de parte de clientes y de hecho muchos utilizan este tipo de tablas). Aun cuando las ocupo, las evito completamente, pero cuando el cliente o el modelo realmente lo exige sugiero adicionar luego del prefijo TMP si pertenece al esquema o _TMP_ si pertenece al subescenario. Esto nos ayuda a tener agrupadas todas las tablas temporales. Debe quedar claro que en las tablas temporales se borrarán los datos, o sea, son solo para guardado de resultados parciales que por motivos de velocidad o estructuración, pero no se debe esperar que en la tabla permanezcan los datos.
Asociados a tablas temporales también debe existir un Jobs o proceso batch posterior que limpie la información con n tiempo de antigüedad. Puede ser que el mismo proceso que genera la información borre las tablas, pero el borrado igual requiere tiempo, por lo que para hacer más veloz el proceso que utiliza los datos temporales en general el borrado debe hacerse después.

Nombramiento de claves primarias

El nombre de una clave primaria debe ser PKY_ seguido del nombre de la tabla, de esta forma se podrá identificar la tabla o el problema de inserción cuando suceda, ya que el error saldrá relacionado con el nombre del constraint. Es habitual encontrar en modelamientos que las claves primarias comiencen con el prefijo PK_, el problema es que en algunos motores de base de datos podemos encontrar paquetes (packages) que mas adelante se definirán con prefijo PKG_, entonces utilizo PKY_ para un orden más especifico.
Si creásemos la tabla CLIENTE en un motor de bases de datos Oracle en un esquema ARO pero sin dar nombre a la clave primaria, tendríamos:

CREATE TABLE CLIENTE  (
RUT       NUMBER NOT NULL PRIMARY KEY,
DV        VARCHAR2(1),
NOMBRE    VARCHAR2(50),
A_PATERNO VARCHAR2(50),
A_MATERNO VARCHAR2(50)
);

Esto crea la tabla con RUT como clave primaria pero no existe un nombre asociado a la clave primaria de la tabla por lo tanto al intentar insertar dos veces el mismo registro se tiene:

INSERT INTO CLIENTE (RUT, DV, NOMBRE, A_PATERNO, A_MATERNO) VALUES (1,9,'Nombre', 'Paterno','Materno');

Error que empieza en la línea 9 del comando:
INSERT INTO CLIENTE (RUT, DV, NOMBRE, A_PATERNO, A_MATERNO) VALUES (1,9,'Nombre', 'Paterno','Materno')
Informe de error:
Error SQL: ORA-00001: unique constraint (ARO.SYS_C0079521) violated
00001. 00000 -  "unique constraint (%s.%s) violated"
*Cause:    An UPDATE or INSERT statement attempted to insert a duplicate key.
For Trusted Oracle configured in DBMS MAC mode, you may see
this message if a duplicate entry exists at a different level.
*Action:   Either remove the unique restriction or do not insert the key.

Aparece un nombre que fue asignado por el motor de base de datos ARO.SYS_C0079521 lo que no nos dice nada. En contraposición, la forma correcta sería:

CREATE TABLE CLIENTE  (
RUT       NUMBER NOT NULL,
DV        VARCHAR2(1),
NOMBRE    VARCHAR2(50),
A_PATERNO VARCHAR2(50),
A_MATERNO VARCHAR2(50),
CONSTRAINT PKY_CLIENTE PRIMARY KEY (RUT)
);

Con esto el error anterior sería más localizado:

Error que empieza en la línea 11 del comando:
INSERT INTO CLIENTE (RUT, DV, NOMBRE, A_PATERNO, A_MATERNO) VALUES (1,9,'Nombre', 'Paterno','Materno')
Informe de error:
Error SQL: ORA-00001: unique constraint (ARO.PKY_CLIENTE) violated
00001. 00000 -  "unique constraint (%s.%s) violated"
*Cause:    An UPDATE or INSERT statement attempted to insert a duplicate key.
For Trusted Oracle configured in DBMS MAC mode, you may see
this message if a duplicate entry exists at a different level.
*Action:   Either remove the unique restriction or do not insert the key.

Ahora se tiene que el error es en una PKY_CLIENTE, que nos lleva inmediatamente a la tabla CLIENTE, por lo que el log se hace muchísimo más entendible.

Referencias

El nombre de una referencia esta dada por las tablas que participan. Utilizo el prefijo REF_ más el nombre de la tabla origen de la referencia y el nombre de la tabla destino. En el ejemplo se tiene que existen dos referencias:

REF_CATEGORIAS_CLIENTES_CLIENTE, que es la referencia desde la tabla CATEGORIAS_CLIENTES hacia la tabla CLIENTE, lo que significa que en la tabla origen CATEGORIAS_CLIENTES existe la clave primaria de la tabla CLIENTE.
REF_CATEGORIAS_CLIENTES_CATEGORIA que es la referencia desde la tabla CATEGORIAS_CLIENTES hacia la tabla CATEGORIA, lo que significa que en la tabla origen CATEGORIAS_CLIENTES existe la clave primaria de la tabla CATEGORIA.

No es necesario que en la tabla origen las referencias sean parte de las claves primarias, obviamente es un caso puntual. Por ejemplo, aquí no se tiene a sexo como parte de la clave primaria.

Una acotación, en el motor Oracle los nombres de los objetos no deben superar los 30 caracteres, por lo mismo en la imagen del modelo los nombres de las referencias aparecen cortados a ese largo.
Existen ocasiones en donde las tablas de origen y destino son las mismas para dos o mas referencias pero tienen un significado distinto, por lo que al finalizar establezco el diferenciador a las referencias. Por ejemplo, asumamos que deseamos modelar que nuestro cliente puede invitar a otros clientes, y deseamos guardan quien recomendó a quien, son dos relaciones desde la misma tabla origen a la misma tabla destino, por lo que bajo la normativa de nombramiento debiese tener el mismo nombre, es por eso que debemos agregarle un diferenciador. Ejemplo:

Por lo tanto si nos da un error en REF_INVITADO_CLIENTE_INVITADO sabemos que el error es que nos falto el RUT_INVITADO, si es en REF_INVITADO_CLIENTE_INVITADOR, sabemos que el error esta en el RUT_CLIENTE.

Nombramiento de índices

Se utiliza el prefijo IDX_ adicionalmente se establece un sufijo con los caracteres C o N para indicar clusterizado o no y U o N para indicar si es único o no único. Finalmente pongo algún nombre representativo para el índice. Aquí se puede además utilizar un acrónimo de tres letras para la tabla, para utilizarlo después del prefijo, esto también es útil para la ordenación de los índices. Ejemplo:
IDX_CLI_ID_SEXO_NN indicaría un índice en la tabla cliente (asumiendo que CLI es el acrónimo de esta tabla) es sobre el campo ID_SEXO, no clusterizado y no único.
Para algunos puede ser paranoico el tema de nombramiento de índices, pero se transforma en una buena herramienta cuando se utiliza explain plain o herramientas similares, estas herramientas nos permiten saber si una consulta ‘se va’ por un índice o no, y nos otorgan la posibilidad de dudar del diseño que existe detrás del índice, ya que existen algunos índices que no son adecuados para las tablas, porque en muchos casos empeora el rendimiento de las consultas asociadas.

Nombramientos de chequeos (o reglas)

Cuando existe la posibilidad de nombrar los chequeos utilizo el prefijo CHK_ y luego el nombre representativo para el chequeo. El acrónimo creado para la tabla también es útil acá.

Nombramiento de campos

En general el nombre del campo es representativo al atributo que se desea modelar, por lo tanto RUT será un Rol Único Tributario, NOMBRE será el nombre, y así, no hay necesidad de complejizarlo a menos que sea absolutamente necesario.

¿Cuándo es necesario?

Existen usuarios que conocen la base de datos, esos usuarios tienen cargos de importancia, y en algunos casos modifican directamente los datos que un proceso hizo, luego del tiempo aparecen los escándalos por fraude, o en otros casos, aparecen datos anómalos. Por lo tanto aparecen necesidades que no son de los modeladores de base de datos, sino que son de negocio, y que busca evitar que los usuarios modifiquen directamente datos que son realmente campos de cuidado, por ejemplo consolidaciones de balance, valorizaciones de cartera, etc.
Entonces, para las empresas que quieran modelos de datos sean más difíciles de entender a esos usuarios, o que por ventas de bases de datos quieren complicar alguna ingeniería reversa es bueno llegar a un consenso de nombramiento de campos de forma que tenga grados de dificultad para su traducción o verbalización pero que sean entendibles para el desarrollador. Realmente este punto es más útil para las empresas paranoicas con su seguridad sobre sus bases de datos.
Lo siguiente es una propuesta para ello.

Prefijo

Comencemos por un prefijo que corresponde a tres caracteres que sirven de acrónimo para la tabla.

INSTRUMENTOS todos los campos comenzaran con INS_
PERSONA todos los campos comenzaran con PRS_

También es útil para disminuir un error muy común, el de las columnas ambiguas, que ocurre cuando haces un select a dos tablas que contienen un campo del mismo nombre, si bien es cierto un desarrollador ordenado evitaría que le ocurriera, muchas veces pasa, incluso en proyectos en funcionamiento. Puede pasar que la segunda tabla hoy no tenga el campo, pero mañana con algún nuevo desarrollo ese campo se incluya dentro de esta y algunas consultas ya hechas acusen el error.

Sufijo

En algunos casos dependiendo como sea la forma de trabajo del equipo de desarrollo es útil considerar un sufijo asociado al tipo de dato o al rol que juega el campo dentro de la tabla, pera este cado se tiene

_PK para todas las que participan en la clave primaria
_FK para representar todas las que provienen de otra tabla
_NI para especificar números enteros
_ND para especificar números decimales
_CR para especificar caracteres
_RE para especificar campos si/no o campos de un solo carácter que indiquen una regla
_FC para campos fecha
_TM para campos timestamp, que incluyen fecha y hora

Mayor seguridad en el nombre

Como se vió si se utiliza prefijo y sufijo se tiene un campo más o menos así
XXX_nombreDescriptivo_XX
En el caso de asegurar el desarrollo de un producto y hacer más difícil la comprensión del campo el nombre descriptivo se escribirá como un par de conjunto de tres letras, de forma de nombrar el campo, quedando de la forma
XXX_XXX_XXX_XX

Dando permiso a una secuencia en Oracle

lunes, mayo 31st, 2010

En algunos casos muy especificos debemos dar permiso a que otro usuario, por motivos de proceso deba incrementar una secuencia de otro esquema, para ello se debe dar el permiso de SELECT sobre la secuencia, debido a que obviamente se ocupa generalmente de la forma SELECT NOMBRE_DE_LA_SECUANCIA.NEXTVAL FROM DUAL, para ello se tiene:

GRANT SELECT ON NOMBRE_SECUENCIA TO USUARIO;