taller_bd_ISC - Servidor de Apoyo al Sistema Escolarizado

Anuncio
Taller de Base de Datos
Unidad
Temas
1
Introducción al Sistema 1.1
Manejador de Base de
1.2
Datos (DBMS)
2
Lenguaje de Definición
2.1
de Datos (DDL)
2.2
Subtemas
Conceptos.
Características del DBMS
Creación de base de datos.
Creación de tablas.
2.2.1 Integridad.
2.2.2 Integridad referencial
declarativa.
2.3 Creación de índices
3
Consultas y Lenguaje
de Manipulación de
Datos (DML)
3.1 Instrucciones INSERT, UPDATE,
DELETE.
3.2 Consultas Básicas SELECT,
WHERE y funciones a nivel de
registro.
3.3 Consultas sobre múltiples tablas.
3.3.1 Subconsultas.
3.3.2 Operadores JOIN.
3.4 Agregación GROUP BY, HAVING.
3.5 Funciones de conjunto de
registros COUNT, SUM, AVG,
MAX, MIN
4
Control de
Transacciones.
4.1
4.2
4.3
4.4
5
Vistas
5.1 Definición y objetivo de las vistas.
5.2 Instrucciones para la administración
de vistas.
6
Seguridad.
6.1 Esquemas de autorización.
6.2 Instrucciones GRANT y REVOKE.
7
Introducción al SQL
Procedural.
7.1 Procedimientos almacenados.
7.2 Disparadores (Triggers).
Propiedades de la transacción.
Grados de consistencia.
Niveles de aislamiento.
Instrucciones COMMIT y
ROLLBACK .
Unidad 1. Introducción al Sistema
Manejador de Base de Datos (DBMS)
1.1 Conceptos.
Sistema Manejador de Base de Datos. (DBMS)
Un DBMS es una colección de numerosas rutinas de software
interrelacionadas, cada una de las cuales es responsable de una tarea
específica.
El objetivo primordial de un sistema manejador base de datos es
proporcionar un contorno que sea a la vez conveniente y eficiente para
ser utilizado al extraer, almacenar y manipular información de la base
de datos. Todas las peticiones de acceso a la base, se manejan
centralizadamente por medio del DBMS, por lo que este paquete
funciona como interfase entre los usuarios y la base de datos.
http://www.itlp.edu.mx/publica/tutoriales/basedat1/tema1_1.htm
Evolución
Inicialmente, en los años 40s, los Sistemas de Archivos generados a través de lenguajes
de programación no propietarios como Cobol y Fortran (vigentes en la actualidad),
permiten almacenar los datos a través de archivos planos con funciones básicas de
lectura y escritura sobre ellos. En 1964, se conciben los primeros Gestores de Base de
Datos (DBMS: Database Management System), por medio de los cuales se pretende dar
un viraje a los Sistemas de Archivos, los cuales se limitan a la estructuración del
almacenamiento físico de los datos. Con los DBMS se crea el concepto de
Administración de los datos, por medio de actividades integradas que permiten verlos
físicamente en un solo almacenamiento pero lógicamente se manipulan a través de
esquemas compuesto por estructuras donde se establecen vínculos de integridad,
métodos de acceso y organización física sobre los datos, permitiendo así obtener valores
agregados de utilización tales como: manejo de usuarios, seguridad, atomicidad e
independencia física y lógica de los datos, entre otros.
El primer gestor de bases de datos (DBMS) comercial, IDS: Integrated Data Store , se
crea bajo el concepto del Modelo de Datos de Red (Bachgman, 1965); luego se
desarrolla el IMS: Information Management System , sobre el concepto del Modelo de
Datos Jerárquico. Estos DBMSs eran accesados normalmente por lenguajes de
programación como Cobol usando interfases de bajo nivel haciendo que las tareas de
creación de aplicaciones y mantenimiento de los datos fuesen controlables, pero aún
complejas.
A medida que evolucionaban los DBMS, los lenguajes de programación también lo
hacían. En 1967 surge el primer lenguaje de programación orientado a objetos, Simula,
el cual fue propuesto para simulación de actividades. En este los procedimientos
podían ser asociados a un tipo para representar el comportamiento de una instancia,
introduciendo así el concepto de Clase. Simula, soporta paralelismo permitiendo
muchas entidades interactivas en una simulación. Además comparte objetos acoplando
datos y procedimientos.
Luego se genera una nueva noción, donde las bases de datos deben almacenar por
medio de una estructura tabular llamada relación o tabla (Codd,1970), compuesta por
filas y columnas, accesando dichas relaciones a través de un lenguaje de alto nivel no
procedural (declarativo). De esta forma en los años 80s surgen varios productores de
DBMS Relacionales (RDBMS) como Oracle, Informix, Ingres y DB2, además de otros
lenguajes orientados a objetos como el C++, Java (antes el Oak), Eiffel, y Smalltalk
adoptando y mejorando el concepto de clase pero su desarrollo se hace independiente de
los DBMSs.
Comenzando los años 80’s ya se siente la necesidad de que los DBMS actuales
manipulen objetos complejos y estructuras como las usadas en sistemas CAD y CASE,
entre otras. A partir de esto se da inicio a dos grandes tendencias: los ORDBMS
(Object Relational Database Management System) los cuales se proyectan como una
extensión de los RDBMS hacia el paradigma OO, y los OODBMS (Object Oriented
Database Management System) estarían disponibles para almacenar y manipular las
clases, los objetos, la asociación entre ellos y sus métodos. Así, finalizando los años
80s se crean los OODBMSs por medio de productores como O2, ObjectDesign y
Objectivity, entre otros. Pero realmente se puede decir que estos no se hicieron tan
comerciales como los existentes RDBMS ya que el concepto de Orientación a Objetos
se seguía manejando muy a nivel del lenguaje de programación, sin que se trabajaran
estructuras de almacenamiento Orientadas a Objetos dependientes de estos . Así, en
1991 surge la ODMG (Object Database Management Group) el cual estandariza los
OODBMSs a partir del ODMG-93 y luego en 1992 el comité ANSI X3H2 inicia un
trabajo en SQL3, del cual surgen los DBMS objeto relacional ORDBMS. Este trabajo
fue programado para finalizarse en 1995, pero aún se sigue trabajando en este con un
tiempo límite de terminación, en el año 1999.
Por medio de la tabla 1 se puede observar la clasificación que se ha hecho de las
versiones que han generado los diferentes vendedores de acuerdo a la evolución de los
modelos:
Tabla 1. Productos DBMS por Vendedor, 1997.
ProductosVendedor RDBMS
ORDBMS
Oracle
Oracle 7.x
Oracle 8.x
Sybase
System
10/11
Informix
Dynamic
Server
Universal Server
(Ilustra)
IBM
DB/2
Universal Database
(DB/2 Extenders)
UniSQL
UniSQL/X
Unisys
OSMOS
OODBMS
Computer
Associates
OpenIngres
Jasmine
Gemstone
Gemstone
O2
O2
Object Design
Object Store
Objectivity
Objectivity/DB
Versant
Versant
ODBMS
Esquema de un DBMS
Lenguajes del DBMS
En la estructura básica de un Sistema Manejador de Base de Datos se enuncian dos
lenguajes que permiten trabajar sobre la base de datos. Estos lenguajes estandar son:

DDL (Data Definition language): Lenguaje de Definición de Datos. Por
medio de este el DBMS identifica las descripciones de los elementos de los
esquemas y almacena la descripción del esquema en el catálogo del DBMS.
Por medio de este el DBMS especifica el esquma conceptual e interno (Base de
datos Almacenada).

SDL (Store Definition language): Lenguaje de definición de almacenamiento.
Es utilizado por el DBMS para especificar el esquema interno que corresponde a
la Base de Datos Almacenada.

VDL (View Definition language): Lenguaje de Definición de Vistas. Es
utilizado por el DBMS para especificar las vistas del usuario y sus
correspondiencias con el esquema conceptual.
En las Bases de Datos Relacionales, el SQL, representa una combinación de los
anteriores.

DML (Data Manipulation language): Lenguaje de Manipulación de Datos.
Permite la manipulación de las operaciones de Inserción, Eliminación y
Modificación.
o Tipos de DML's:
 De alto Nivel o No por procedimientos: SQL.
 De bajo Nivel o por procedimientos.
Usuarios de un Sistema Manejador de Base de Datos




Personal del DBA
Usuarios Exporádicos
Programadores de Aplicaciones
Usuarios paramétricos
http://www.unalmed.edu.co/~mstabare/Dbms.htm
Introducción
Las bases de datos están omnipresentes en nuestra vida diaria, desde el hecho de utilizar
un cajero automático hasta utilizar los servicios de un ISP, pasando por realizar la
compra en el supermercado; en todas estas actividades está implícito el uso de bases de
datos. Mientras más automatizada sea nuestra sociedad más hará uso de las bases de
datos, es comprensible entonces que sea un tópico de mucho interés entre los que
aspiramos a dominar un poco esta avalancha de aplicaciones de tecnología.
Con las bases de datos se encuentran allegados muchos términos que estaremos
analizando más adelante. Básicamente los Sistemas de Bases de Datos pretenden reducir
los errores que por mal implementación o uso pudieran sucederse en una base de datos.
Estas posibilidades de error se trataran de minimizar con el uso de herramientas y
conceptos analizados a continuación.
1. Términos Básicos.
Administración
El término esta necesariamente ligado a la vigilancia en la utilización de los recursos
disponibles, también pudiera apuntar a la observación de los mismos con el fin de
optimizar la manera en que son empleados.
Base de Datos
Es una colección de datos, que por lo general están relacionados con un tópico
determinado como podría ser una empresa.
Administración de Bases de Datos
La administración de datos implica la definición de estructuras apropiadas para
almacenar la información, así como también el empleo de mecanismos que permitan la
manipulación de la información. Además de estas funciones hay que garantizar la
disponibilidad de la información de manera que a pesar de la ocurrencia de imprevistos,
la misma, esté siempre disponible y tampoco se puede dejar a un lado el tema de la
seguridad que es una parte importante dentro de la administración de bases de datos.
Sistema de Bases de Datos
Es básicamente un conjunto de programas que permiten a los usuarios acceder y
modificar una serie de archivos interrelacionados (base de datos). El fin principal del
Sistema Manejador de Base de Datos SMBD es proporcionar un visión abstracta de los
datos de manera que el usuario no se entere de los detalles de cómo se administran los
archivos.
Vista de Datos
Son abstracciones de datos que permiten ocultar ciertos datos a determinados usuarios,
de manera que solamente se muestra la información necesaria. Esto es muy útil en
sistemas que poseen una estructura jerárquica de acceso a la información. Las vistas de
datos son muy prácticas para ofrecer resultados inteligibles por parte de los usuarios que
no conocen como esta estructurada la información en detalle.
Estructura de un Sistemas de Bases de Datos
Un SMBD (Sistema Manejador de Bases de Datos) se compone de un conjunto de datos
interrelacionados y un conjunto de programas que permiten el acceso a dichos datos. La
colección de datos se conoce como Base de Datos y uno de los objetivos principales de
un SMBD es el proporcionar un entorno práctico y eficiente para el almacenamiento y
recuperación de la información almacenada en la Base de Datos.
Un SMBD se diferencia de un sistema manejador de Archivos, SMA, en que el primero
es capaz de describir los datos de manera separa a su utilización, asegura la
independencia de datos que se analizará posteriormente.
Figura 1. Estructura General de un SMBD
Como se puede observar en la figura 1, podemos definir una estructura general de la
siguiente manera:
Almacenaje en disco: proporcionado por el sistema operativo, realiza las labores de más
bajo nivel de lectura escritura en disco.
Gestión de Almacenamiento: Esta es la capa más básica en si del SMDB, allí se trata lo
relativo a la memoria intermedia, se generan las ordenes de gestión de archivos y se
administra la memoria intermedia (extensión de la memoria principal del sistema).
Procesador de Consultas: En la siguiente capa tenemos a los interpretes y compiladores
de los Lenguajes de Modelado de Datos y de Definición de Datos. También se evalúan
las consultas hechas al sistema por medio del motor de consultas.
Usuarios: aunque algunos autores le dan más importancia a esta capa que otros, es allí
donde se formulan las peticiones por parte de los usuarios y de las aplicaciones que
estos utilizan para accesar a la data. Dentro de los usuarios encontramos a su vez varios
tipos:

Los usuarios normales o finales como los cajeros de un banco que
simplemente utilizan el sistema a través de una aplicación.
 Después tenemos a los programadores que realizan los programas
apropiados para manipular los datos, utilizando un lenguaje de
programación para ello.
 En un tercer término tenemos a los usuarios sofisticados que realizan
consultas directas sobre el SMBD utilizando un compilador de
Lenguaje de Modelado de Datos.
 Por último pero quizás el más importante el Administrador de la Base de
Datos que coordina todas las operaciones que serán efectuadas sobre la
Base de Datos.
El Administrador de la Base de Datos
Podemos decir que un Administrador de Base de Base de Datos tiene como objetivo
principal el mantener la base de datos activa y proporcionarle acceso a los usuarios a la
información cuando ellos lo requieran. Se asegura que la base de datos esté protegida y
de que cualquier pérdida de información sea minimizada.
Algunas características que debe poseer un Administrador de base de datos son:
a. Un buen entendimiento del sistema operativo sobre el cual funciona la
base de datos.
b. Conocimiento de un Lenguaje de consulta como el SQL.
c. Habilidades para el Diseño de Bases de Datos.
d. Comprensión general de la arquitectura de las redes (por ejemplo
Cliente/Servidor, Intranet/Internet, Servidores Empresariales, de
desarrollo, etc.)
e. Conocer un Servidor de Bases de Datos como el Microsoft SQL o el
MySQL.
Entre las Responsabilidades de un Administrador de Bases de Datos tenemos:
1. Instalar y mantener actualizado el Servidor de Bases de Datos.
2. Monitorear el estado del Servidor y mantenerlo funcionando en optimas
condiciones.
3. Revisar el archivo de registro de eventos a la caza de posibles errores.
4. Realizar rutinas de mantenimiento a los datos, con el fin de ejecutarlas
periódicamente.
5. Hacer uso del espacio de almacenamiento de manera apropiada.
6. Realizar rutinas de respaldo y recuperación en caso de incidentes.
7. Establecer medidas de seguridad para permitir el acceso a los usuarios
autorizados en los horarios permitidos.
8. Velar por la integridad de los datos.
Modelo de Datos
Modelo de Datos
El Modelo de Datos es una colección de herramientas que permiten describir los datos,
también aplica a las relaciones que se establecen entre los datos y a las reglas de
consistencia necesarias para que se mantenga integra la Base de Datos. En otras
palabras un Modelo de Datos es una representación de los mismos que permite manejar
de forma organizada la información que en el mundo real se relaciona con objetos y/o
procesos.
Esquema de Base de Datos
Se refiere al diseño completo de la base de datos. Se dice que los esquemas rara vez son
modificados, porque ellos se conciben mediante un proceso de análisis bastante
exhaustivo.
Estado de la Base de datos
La Base de Datos va creciendo en la medida en que se le agregan datos, también puede
disminuir por la eliminación de los mismos, es decir, se transforma en un elemento
dinámico en función de las actividades que efectúen sus usuarios, a la instantánea de un
momento determinado le podemos dar el nombre de Estado de la Base de Datos.
Modelo Conceptual de Datos
Se refiere al modelo más entendible para el usuario en el cual se ha hecho abstracción
con el fin de comprender la estructura de los mismos y como se puede interactuar con
ellos.
Modelo Entidad Relación
Este modelo es ampliamente usado y permite la representación de los objetos mediante
el concepto de entidades y relaciones a las que se dan entre estos. Una entidad es una
cosa u objeto distinguible de otros, por lo general las distinciones se basan en las
características que los objetos poseen, estas características se conocen con el nombre de
atributos. Una relación puede asociar a varias entidades, por ejemplo; en una escuela un
Profesor puede enseñar en varias aulas, tanto el profesor como las aulas son entidades y
la relación se pudiera llamar enseñanza.
Para comprender mejor el modelo se recurre a un proceso de diagramación, donde cada
elemento es identificado a continuación:
Figura 2. Elementos de un Diagrama Entidad – Relación




Los rectángulos representan las Entidades.
Las elipses los atributos de las entidades.
Los rombos representan relaciones entre entidades.
Las líneas sirven para unir los atributos con las entidades y las entidades
con las relaciones.
Figura 3. Ejemplo de Diagrama Entidad - Relación
Diccionario de Datos
Un Diccionario de Datos almacena información conocida como Metadatos que no es
otra cosa que la manera como están estructurados los datos en la BD. El diccionario de
Datos es muy usado y por ello debería estar muy bien diseñado ya que una vez definido
no sufre alteraciones. Se usa ampliamente antes de modificar o leer los datos reales del
sistema de Bases de Datos.
DDL (Lenguaje de Definición de Datos)
Este tipo de lenguaje permite especificar un conjunto de definiciones para establecer el
esquema de la bases de datos. El resultado de la compilación del LDD son las tablas del
diccionario de datos que posee la manera como están conformados los datos.
Adicionalmente se puede utilizar un subconjunto del LDD o DDL para definir los
métodos de acceso a los datos y de almacenamiento de los mismos.
DML (Lenguaje de Modelado de Datos)
El LMD permite a los usuarios acceder o manipular los datos que han sido organizados
con anterioridad y definidos a través del LDD. Existen dos tipos básicamente:
LMD procedimentales: El usuario especifica qué datos y cómo se obtienen.
LMD no procedimentales: El usuario especifica qué datos quiere más no cómo los
obtendrá.
Los LMD no procedimentales son los más fáciles de aprender, sin embargo pudieran
generar código no deseado o poco eficiente. En cambio los procedimentales generan
código más exacto. Entendiendo que existen distintas versiones de SQL, podemos
afirmar que casi todas se pueden comparar con un LMD porque permiten no sólo
obtener datos sino también realizar operaciones de modificación y mantenimiento de los
datos.
SDL (Lenguaje de Definición de Almacenamiento)
Define las estructuras o esquema como se guardará la información, los detalles se
esconden a los usuarios finales.
VDL (Lenguaje de Definición de Vistas)
Según algunos autores se define como un conjunto del LMD encargado de especificar
las vistas de datos requeridas por los usuarios. En la mayoría de los casos esta vinculado
directamente al LMD.
Aunque no es una norma todos estos lenguajes pueden estar incorporados en un solo
paquete o aplicación de software para el manejo de bases de datos.
Entre los modelos de datos encontramos que las principales categorías en que se
agrupan son:
Modelos lógicos basados en objetos
Se caracterizan por tener la capacidad de estructurar los datos de manera muy flexible y
permiten que las reglas de integridad sean especificadas directamente. Entre los
modelos de este tipo encontramos:
El modelo entidad – relación.
El modelo orientado a objetos
El modelo semántico de datos
El modelo de datos funcional.
Modelos lógicos basados en registros
Estos modelos se diferencian de los basados en objetos ya que especifican la estructura
lógica de la base de datos y a la vez proporcionan una descripción de alto nivel de la
base de datos.
Los modelos basados en registros poseen estructuras de datos con registros de formato
fijo y de diferentes tipos, en contraste, están los modelos basados en objetos que
pudieran presentar a registros de longitud variable apreciables en el nivel físico de la
base de datos (tablas).
Independencia de los datos
La Independencia Física de los datos se refiere a la capacidad de modificar el esquema
físico de los datos sin que traiga como consecuencia cambios en los programas de
aplicación. Mientras que la Independencia Lógica de los Datos es la capacidad de
modificar la estructura lógica de los datos sin causar una alteración en los programas de
aplicación.
La Estructura Lógica es más difícil de lograr que la física ya que los programas por lo
general se escriben en función de ésta última. Es decir, es posible modificar las tablas
sin tener que reescribir el programa, pero lo que seguro no es posible es modificar las
relaciones y vistas de datos y no tener que alterar el código para adaptarlo a la nueva
estructura lógica.
http://dmedina_ve.tripod.com/homework/basesdedatos_1.html
1.2 Características del DBMS
La aplicación principal de un sistema manejador de base de datos (DBMS) es permitir el
almacenamiento masivo de información lógicamente relacionada y su rápida recuperación.
Esta información así almacenada, que se controla inteligentemente y acorde a los
requerimientos de una empresa, es de enorme valor, independientemente de la naturaleza de
la gestión de esta, ya que permite a los ejecutivos de todo nivel el control y la toma de
decisiones oportunas y adecuadas.
Esta es una de las características de un DBMS, ya que puede modificar substancialmente los
principios y normas establecidas y practicadas para administrar la información. Los sistemas
manipuladores de bases de datos relacionales (RDBMS) han adquirido una posición relevante
en la planeación estratégica de las empresas.
http://usuarios.lycos.es/planetearthchat/Introduccion_Bases.html
Un Sistema Gestor de base de datos (SGBD) es un conjunto de programas que permiten
crear y mantener una Base de datos, asegurando su integridad, confidencialidad y
seguridad. Por tanto debe permitir:
- Definir una base de datos: especificar tipos, estructuras y restricciones de datos..
- Construir la base de datos: guardar los datos en algún medio controlado por el mismo
SGBD
- Manipular la base de datos: realizar consultas, actualizarla, generar informes.
Así se trata de un software de propósito general. Ejemplo de SGBD son Oracle y SQL
Server de Microsoft .
Algunas de las características deseables en un Sistema Gestor de base de datos SGBD
son:
- Control de la redundancia: La redundancia de datos tiene varios efectos negativos
(duplicar el trabajo al actualizar, deperdicia espacio en disco, puede provocar
inconsistencia de datos) aunque a veces es deseable por cuestiones de rendimiento.
- Restricción de los accesos no autorizados: cada usuario ha de tener unos permisos de
acceso y autorización.
- Cumplimiento de las restricciones de integridad: el SGBD ha de ofrecer recursos para
definir y garantizar el cumplimiento de las restricciones de integridad.
http://www.error500.net/garbagecollector/archives/categorias/bases_de_datos/s
istema_gestor_de_base_de_datos_sgbd.php
Describir Las Caracteristicas De Al Menos 3 DBMS
Bases de datos jerárquicos: los datos se organizan en grupos unidos entre
ellos por relaciones de "posesión", en las que un conjunto de datos puede tener
otros conjuntos de datos, pero un conjunto puede pertenecer sólo a otro
conjunto. La estructura resultante es un árbol de conjuntos de datos.
Bases de datos reticulares: el modelo reticular es muy parecido al jerárquico, y
de hecho nace como una extensión de este último. También en este modelo
conjuntos de datos están unidos por relaciones de posesión, pero cada
conjunto de datos puede pertenecer a uno o más conjuntos.
Bases de datos relacionales: las bases de datos que pertenecen a esta
categoría se basan en el modelo relaciones, cuya estructura principal es la
relación, es decir una tabla bidimensional compuesta por líneas y columnas.
Cada línea, que en terminología relacional se llama tupla, representa una
entidad que nosotros queremos memorizar en la base de datos. las
características de cada entidad están definidas por las columnas de las
relaciones, que se llaman atributos. Entidades con características comunes, es
decir descritas por el mismo conjunto de atributos, formarán parte de la misma
relación.
Base de datos por objetos (object-oriented): el esquema de una base de datos
por objetos está representado por un conjunto de clases que definen las
características y el comportamiento de los objetos que poblarán la base de
datos. La diferencia principal respecto a los modelos examinados hasta ahora
es la no positividad de los datos. En efecto, con una base de datos tradicional
(entendiendo con este término cualquier base de datos no por objetos), las
operaciones que se tienen que efectuar en los datos se les piden a las
aplicaciones que los usan. Con una base de datos object-oriented, al contrario,
los objetos memorizados en la base de datos contienen tanto los datos como
las operaciones posibles con tales datos. En cierto sentido, se podrá pensar en
los objetos como en datos a los que se les ha puesto una inyección de
inteligencia que les permite saber cómo comportarse, sin tener que apoyarse
en aplicaciones externas.
http://www.monografias.com/trabajos11/basda/basda.shtml
Definición y Características de un SBD
Se puede definir una base de datos, como un fichero en el cual se
almacena información de cualquier tipo. En dicho fichero la
información se guarda en campos o delimitadores, por ejemplo,
podemos almacenar el nombre y el apellido de las personas de
modo separado, de ésta forma es posible obtener del fichero todos
los nombres o todos los apellidos, tanto de forma separada como
conjunta.
Normalmente el número de campos que se tienen en una base varía
según las necesidades en cuanto a gestión de datos, de forma que
después se pueda explotar la información de forma ordenada y
separada, aunque el resto de la información sigue almacenada y
guardada en la base de datos
Una base de datos, no es solo el fichero en donde están datos, sino
que en dicho arvhivo se encuentra la estructura de los datos, osea,
para saber que longitud tiene cada campo,hay que conocer como se
llama el campo y qué longitud en caracteres tiene, asi como el tipo
de datos en dicho campo, porque puede contener desde letras a
números o incluso otros datos más complejos, dependiendo de la
estructura de la base y del sistema gestor.
En realidad aparte de los datos que son almacenados en el archivo,
también hay una serie de datos, en los que se informa del tipo de
campo, los campos y la longitud de cada campo, es lo que se llama
gestor de datos, que permite saber que cada registro (un registro es
una suma de campos, por ejemplo a Ana LOPEZ LOPEZ, Ana lo
guardamos en el campo Nombre y LOPEZ LOPEZ en el campo
Apellidos, cada registro es cada persona que almacenamos en la
base, osea una persona es un registro y cada regitro està
constituido por los campos Nombre y Apellido
Un Sistema de Bases de Datos (SBD) es una serie de recursos para
manejar grandes volúmenes de información, sin embargo no todos
los sistemas que manejan información son bases de datos.
Un sistema de bases de datos debe responder a las siguientes
características:
 Independencia de los Datos. Es decir, que los datos no dependen
del programa y por tanto cualquier aplicación puede hacer uso de
los datos.
 Reducción de la Redundancia.Llamamos redundancia a la
existencia de duplicación de los datos, al reducir ésta al máximo
conseguimos un mayor aprovechamiento del espacio y además
evitamos que existan inconsistencias entre los datos. Las
inconsistencias se dan cuando nos encontramos con datos
contradictorios.
 Seguridad. Un SBD debe permitir que tengamos un control sobre
la seguridad de los datos.
2.- Recursos que componen un SBD
Un SBD está formado por:

Personas

Máquinas

Programas
Son los encargados de manejar los datos, son conocidos
como DBMS (Data Base Management System) o también
SGBD (Sistema Gestor de Base de Datos). Los DBMS tienen
dos funciones principales que son:
- La definición de las estructuras para
almacenar los datos.
- La manipulación de los datos.

Datos
Es lo que se conoce como base de datos propiamente dicha.
Para manejar estos datos utilizamos una serie de programas.
3.- Distintos Niveles de un SBD
Los SBD pueden ser estudiados desde tres niveles distintos:
1 Nivel Físico
Es el nivel real de los datos almacenados. Es decir como se
almacenan los datos, ya sea en registros, o como sea. Este nivel es
usado por muy pocas personas que deben estar cualificadas para
ello. Este nivel lleva asociada una representación de los datos, que
es lo que denominamos Esquema Físico.
2 Nivel Conceptual
Es el correspondiente a una visión de la base de datos desde el
punto de vista del mundo real. Es decir tratamos con la entidad u
objeto representado, sin importarnos como está representado o
almacenado. Este nivel lleva asociado el Esquema Conceptual.
3 Nivel Visión
Son partes del esquema conceptual. El nivel conceptual presenta
toda la base de datos, mientras que los usuarios por lo general sólo
tienen acceso a pequeñas parcelas de ésta. El nivel visión es el
encargado de dividir estas parcelas. Un ejemplo sería el caso del
empleado que no tiene porqué tener acceso al sueldo de sus
compañeros o de sus superiores. El esquema asociado a éste nivel
es el Esquema de Visión.
Los tres niveles vistos, componen lo que conocemos como
arquitectura de base de datos a tres niveles.
A menudo el nivel físico no es facilitado por muchos DBMS, esto es,
no permiten al usuario elegir como se almacenan sus datos y vienen
con una forma estándar de almacenamiento y manipulación de los
datos.
La arquitectura a tres niveles se puede representar como sigue:
4.- Modelos de datos
Para representar el mundo real a través de esquemas conceptuales
se han creado una serie de modelos:
Existen multitud de estos modelos que se conocen como Modelos
de Datos,los más conocidos son:



Modelo Relacional de Datos
Modelo de Red
Modelo Jerárquico
4.1 Modelo Relacional de Datos
Representa al mundo real mediante tablas relacionadas entre sí por
columnas comunes. Ej.:
Num.
empleado
Nombre Sección
33
Pepe
25
34
Juan
25
Num_sección
Nombre
25
Textil
26
Pintura
4.2 Modelo de Red
Representamos al mundo real como registros lógicos que
representan a una entidad y que se relacionan entre sí por medio de
flechas. Ej.:
4.3
Modelo
Jerárquico
Tiene forma de árbol invertido. Un padre puede tener varios hijos
pero cada hijo sólo puede tener un padre. Ej.:
Al llegar a este punto adoptaremos una convención con respecto a
las restricciones que se pueden dar en un modelo, en cuanto a la
capacidad de relacionarse que pueda tener cada entidad de ese
modelo con el resto de entidades.
Como se ha dicho el modelo jerárquico sólo admite relaciones 1 : 1
ó 1 : N.
En caso de que tuviésemos la necesidad de otro tipo de
asociaciones y queramos usar el esquema jerárquico, recurriríamos
a una duplicación de la información en el esquema, pero sólo a nivel
esquemático.
Ej.: Tenemos dos entidades (cliente y cuenta), queremos que un
cliente pueda poseer varias cuentas, y que una cuenta pueda tener
como titulares a varios clientes. Usando el modelo jerárquico
tendríamos que recurrir a una duplicación de los datos en el
esquema.
Esta duplicación sólo ocurriría a nivel esquemático, pero a nivel
físico existiría un único registro por cliente, y por cuenta que
relacionaríamos mediante varios punteros con todo lo necesario.
En el modelo de red no existen restricciones, si queremos
representar que un cliente puede tener varias cuentas, cada una de
las cuáles sólo puede tener un titular, y cada cuenta ésta en una
sola sucursal, que por supuesto puede ser compartida por varias
cuentas.
Con el modelo relacional podríamos tener ambas entidades
definidas de la siguiente forma:
Cliente = (Nº Cliente: Acceso Principal; Nombre, Dirección, Nº
Cuenta: Acceso Ajeno)
Cuenta = (Nº Cuenta: Acceso Principal; Saldo)
Se podría hablar de otro modelo que está un nivel más arriba y que
se denomina Modelo Entidad-Relación (E/R). Este modelo sólo
realiza el diseño, no realiza la implementación, por lo tanto una vez
hecho el diseño se puede llevar al modelo relacional, de red o
jerárquico. En el esquema siguiente define dos entidades y una
forma de relación entre ellas.
Sus características principales son:

Reflejan tan sólo la existencia de los datos sin expresar lo que
se hace con ellos.

Es independiente de las bases de datos y de los sistemas
operativos (por lo que puede ser desarrollado en cualquier
base de datos).

Está abierto a la evolución del sistema.

Incluye todos los datos que se estudian sin tener en cuenta
las aplicaciones que se van a tratar.

No tienen en cuenta las
almacenamiento del sistema.
restricciones
de
espacio
Conceptos del Modelo Entidad-Relación
Entidades
Son objetos concretos o abstractos que presentan interés para el
sistema y sobre los que se recoge información que será
representada en un sistema de bases de datos. Por ejemplo,
clientes, proveedores y facturas serían entidades en el entorno de
una empresa.
Atributos
Es una unidad básica e indivisible de información acerca de una
entidad o una relación. Por ejemplo la entidad proveedor tendrá los
atributos nombre, domicilio, población, CIF.
y
Dominios
Es el conjunto de valores que puede tomar cada atributo. Por
ejemplo el dominio del atributo población, será la relación de todas
las poblaciones del ámbito de actuación de nuestra empresa.
Tablas
Es la forma de estructurar los datos en filas o registros y columnas
o atributos.
Relación
Es la asociación que se efectúa entre entidades. Por ejemplo la
relación entre las entidades facturas emitidas y clientes.
Los diagramas Entidad - Relación representan la estructura lógica de una base
de datos de manera gráfica. Los símbolos utilizados son los siguientes:
Rectángulo.Conjunto
de
entidades.
Elipse.Atributos.
Rombos.Conjunto
de
relaciones
- Líneas.- Unen atributos a conjuntos de entidades; unen atributos a conjuntos
de relaciones; y unen conjuntos de entidades con conjuntos de relaciones. Si la
flecha tiene punta, en ese sentido está el uno y si no la tiene, en ese sitio está el
muchos.
La
orientación
señala
cardinalidad.
- Elípse doble.- Se trata de dos elipses concéntricas. Representan atributos
multivalorados.
Elipse
discontinua.Atributos
derivados.
- Líneas dobles.- Indican participación total de un conjunto de entidades en un
conjunto de relaciones. - Subrayado.- Subraya los atributos que forman parte
de
la
clave
primaria
del
conjunto
de
entidades.
Si el conjunto de relaciones tiene atributos asociados, se le unen a la relación.
En los diagramas Entidad - Relación se indican los papeles (roles) mediante
etiquetas en las líneas que unen los conjuntos de relaciones con conjuntos de
entidades.
Los conjuntos de relaciones no binarias se especifican uniendo al conjunto de
relaciones tantas entidades como marque la relación. No es recomendable su
utilización, prefiriéndose el uso de relaciones binarias.
5.- Programas que conforman el DBMS
El DBMS se compone de una serie de módulos:
 El Compilador de DDL (Data Definition Language). El DDL sirve
para definir estructuras de almacenamiento, y por tanto para crear
esquemas conceptuales.
 El resultado de compilar todas las instrucciones DDL se va a
almacenar en lo que se conoce como Diccionario de Datos. Este
diccionario nos aportará información acerca de la base de datos. El
diccionario de datos depende del DBMS.
 El Precompilador DML (Data Management Language). Las
instrucciones de manejo que define van dentro de un lenguaje de
alto nivel cualquiera (Lenguaje Anfitrión) (El DML se llama Lenguaje
Huésped). El primer paso del pre-compilador es traducir las
instrucciones del DML al lenguaje anfitrión.
 El Procesador de Consultas permite al usuario "jugar" con los
datos, o sea consultarlos sin necesidad de construir un programa
de aplicación. Cuenta con un Optimizador de DML para optimizar
esas consultas.
 El Manejador de Bases de Datos realiza la traducción entre los
diferentes esquemas de la base de datos. Si un usuario quiere
acceder a unos datos, el manejador comprobará su esquema
externo para averiguar a que datos tiene acceso ese usuario; luego
estudia el esquema conceptual completo, a continuación accede al
esquema físico para saber como trabajar con ellos y finalmente los
proporcionará al usuario.
6.- Personas relacionadas con un SBD
Administrador de base de datos (DBA)
Define los esquemas de la base de datos; estructuras y esquemas
de los 3 niveles. Más que una persona suele ser un grupo de
personas.
Programador de aplicaciones
Utilizando un lenguaje de alto nivel y llamadas en DML crean
programas para usar la base de datos.
Usuarios casuales
Son usuarios que tienen conocimientos de los DL, hacen uso de los
DML de modo interactivo (es decir a través del procesador de
consultas)
Usuarios ingenuos
Emplean el SBD sin conocimientos de informática, es decir usan los
programas de aplicación.
Otros tipos de bases de datos, que no se tratarán en esta asignatura, son los
agrupados como postrrelacionales:
- Modelo Orientado a Objetos.
Los datos se representan mediante objetos, que contienen variables y métodos,
y su manipulación se realiza mediante mensajes.
- Modelo Semántico.
Tienen como objetivo describir de un modo más preciso la información
contenida en la base de datos.
- Modelo Deductivo.
Son capaces de deducir hechos a partir de las relaciones base y una serie de
axiomas deductivas o reglas de inferencia.
http://www.um.es/docencia/barzana/IAGP/Iagp6.html
ARQUITECTURA DE UN SISTEMA DE BASES DE DATOS DISTRIBUIDAS
La mayoría de los sistemas de manejo de bases de datos disponibles actualmente están
basadas en la arquitectura ANSI-SPARC la cual divide a un sistema en tres niveles:
interno, conceptual y externo, como se puede apreciar en la Figura 2.4.
La vista conceptual, conocida también como vista lógica global, representa la visión de
la comunidad de usuarios de los datos en la base de datos. No toma en cuenta la forma
en que las aplicaciones individuales observan los datos o como éstos son almacenados.
La vista conceptual está basada en el esquema conceptual y su construcción se hace en
la primera fase del diseño de una base de datos.
Los usuarios, incluyendo a los programadores de aplicaciones, observan los datos a
través de un esquema externo definido a nivel externo. La vista externa proporciona una
ventana a la vista conceptual lo cual permite a los usuarios observar únicamente los
datos de interés y los aísla de otros datos en la base de datos. Puede existir cualquier
número de vistas externas y ellos pueden ser completamente independientes o
traslaparse entre sí.
El esquema conceptual se mapea a un esquema interno a nivel interno, el cual es el nivel
de descripción más bajo de los datos en una base de datos. Este proporciona una interfaz
al sistema de archivos del sistema operativo el cual es el responsable del acceso a la
base de datos. El nivel interno tiene que ver con la especificación de qué elementos
serán indexados, qué técnica de organización de archivos utilizar y como los datos se
agrupan en el disco mediante "clusters" para mejorar su acceso.
En las Figuras 2.5, 2.6 y 2.7 se presenta la definición de los esquemas conceptual,
interno y externo para las relaciones de la Figura 2.1.
Figura 2.4. Arquitectura ANSI/SPARC de una base de datos.
Figura 2.5. Vista conceptual de las relaciones E, S, J y G.
Figura 2.6. Definición de una vista interna a partir de la relación S.
Figura 2.7. Dos ejemplos de vistas externas.
Desafortunadamente, no existe un equivalente de una arquitectura estándar para
sistemas de manejo de bases de datos distribuidas. La tecnología y prototipos de
SMBDD se han desarrollado más o menos en forma independiente uno de otro y cada
sistema ha adoptado su propia arquitectura.
Para definir un esquema de estandarización en bases de datos distribuidas se debe
definir un modelo de referencia el cual sería un marco de trabajo conceptual cuyo
propósito es dividir el trabajo de estandarización en piezas manejables y mostrar a un
nivel general como esas piezas se relacionan unas con otras. Para definir ese modelo de
referencia se puede seguir uno de los siguientes tres enfoques:
1. Basado en componentes. Se definen las componentes del sistema junto con las
relaciones entre ellas. Así, un SMBD consiste de un número de componentes,
cada uno de los cuales proporciona alguna funcionalidad.
2. Basado en funciones. Se identifican las diferentes clases de usuarios junto con
la funcionalidad que el sistema ofrecerá para cada clase. La especificación del
sistema en esta categoría típicamente determina una estructura jerárquica para
las clases de usuarios. La ventaja de este enfoque funcional es la claridad con la
cual se especifican los objetivos del sistema. Sin embargo, este enfoque no
proporciona una forma de alcanzar los objetivos.
3. Basado en datos. Se identifican los diferentes tipos de descripción de datos y se
especifica un marco de trabajo arquitectural el cual define las unidades
funcionales que realizarán y/o usarán los datos de acuerdo con las diferentes
vistas. La ventaja de este enfoque es la importancia que asigna al manejo de
datos. Este es un enfoque significativo para los SMBD dado que su propósito
principal es manejar datos. Sin embargo, la desventaja de este enfoque es que es
prácticamente imposible especificar un modelo arquitectural sin especificar los
modelos para cada una de sus unidades funcionales. Este es el enfoque seguido
por el modelo ANSI/SPARC.
Figura 2.8. Dimensiones a considerar al integrar múltiples bases de datos.
ALTERNATIVAS PARA LA IMPLEMENTACION DE SMBD
En la Figura 2.8 se presentan las diferentes dimensiones (factores) que se deben
considerar para la implementación de un sistema manejador de base de datos. Las
dimensiones son tres:
1. Distribución. Determina si las componentes del sistema están localizadas en la
misma computadora o no.
2. Heterogeneidad. La heterogeneidad se puede presentar a varios niveles:
hardware, sistema de comunicaciones, sistema operativo o SMBD. Para el caso
de SMBD heterogéneos ésta se puede presentar debido al modelo de datos, al
lenguaje de consultas o a los algoritmos para manejo de transacciones.
3. Autonomía. La autonomía se puede presentar a diferentes niveles:



Autonomía de diseño. La habilidad de un componente del SMBD para decidir
cuestiones relacionadas a su propio diseño.
Autonomía de comunicación. La habilidad de un componente del SMBD para
decidir como y cuando comunicarse con otros SMBD.
Autonomía de ejecución. La habilidad de un componente del SMBD para
ejecutar operaciones locales de la manera que él quiera.
Figura 2.9. Arquitectura de un SMBDD homogéneo.
Desde el punto de vista funcional y de organización de datos, los sistemas de datos
distribuidos están divididos en dos clases separadas, basados en dos filosofía totalmente
diferentes y diseñados para satisfacer necesidades diferentes:
1. Sistemas de manejo de bases de datos distribuidos homogéneos
2. Sistemas de manejo de bases de datos distribuidos heterogéneos
Un SMBDD homogéneo tiene múltiples colecciones de datos; integra múltiples
recursos de datos como se muestra en la Figura 2.9. Los sistemas homogéneos se
parecen a un sistema centralizado, pero en lugar de almacenar todos los datos en un solo
lugar, los datos se distribuyen en varios sitios comunicados por la red. No existen
usuarios locales y todos ellos accesan la base de datos a través de una interfaz global. El
esquema global es la unión de toda las descripciones de datos locales y las vistas de los
usuarios se definen sobre el esquema global.
Para manejar los aspectos de la distribución, se deben agregar dos niveles a la
arquitectura estándar ANSI-SPARC, como se muestra en la Figura 2.10. El esquema de
fragmentación describe la forma en que las relaciones globales se dividen entre las
bases de datos locales. La Figura 2.11 presenta el ejemplo de una relación, R, la cual se
divide en cinco fragmentos. El esquema de asignamiento especifica el lugar en el cual
cada fragmento es almacenado. De aquí, los fragmentos pueden migrar de un sitio a otro
en respuesta a cambios en los patrones de acceso.
Figura 2.10. Arquitectura de los esquemas de un SMBDD homogéneo.
Figura 2.11. Fragmentación de una relación global.
Figura 2.12. Arquitectura de un sistema multi-bases de datos.
La clase de sistemas heterogéneos es aquella caracterizada por manejar diferentes
SMBD en los nodos locales. Una subclase importante dentro de esta clase es la de los
sistemas de manejo multi-bases de datos. Un sistema multi-bases de datos (SmultiBD) tiene múltiples SMBDs, que pueden ser de tipos diferentes, y múltiples bases de
datos existentes. La integración de todos ellos se realiza mediante subsistemas de
software. La arquitectura general de tales sistemas se presenta en la Figura 2.12. En
contraste con los sistemas homogéneos, existen usuarios locales y globales. Los
usuarios locales accesan sus bases de datos locales sin verse afectados por la presencia
del Smulti-BD.
En algunas ocasiones es importante caracterizar a los sistemas de bases de datos
distribuidas por la forma en que se organizan sus componentes. En la Figura 2.13 se
presenta la arquitectura basada en componentes de un SMBD distribuido. Consiste de
dos partes fundamentales, el procesador de usuario y el procesador de datos. El
procesador de usuario se encarga de procesar las solicitudes del usuario, por tanto,
utiliza el esquema externo del usuario y el esquema conceptual global. Así también,
utiliza un diccionario de datos global. El procesador de usuario consiste de cuatro
partes: un manejador de la interfaz con el usuario, un controlador semántico de datos, un
optimizador global de consultas y un supervisor de la ejecución global. El procesador de
datos existe en cada nodo de la base de datos distribuida. Utiliza un esquema local
conceptual y un esquema local interno. El procesador de datos consiste de tres partes:
un procesador de consultas locales, un manejador de recuperación de fallas locales y un
procesador de soporte para tiempo de ejecución.
Figura 2.13. Arquitectura basada en componentes de un SMBD distribuido.
En la Figura 2.14, se presenta la arquitectura basada en componentes de un sistema
multi-bases de datos. Consiste un sistema de manejo de bases datos para usuarios
globales y de sistemas de manejo de bases de datos para usuarios locales. Las
solicitudes globales pasan al procesador global el cual consiste de un procesador de
transacciones, una interfaz de usuario, un procesador de consultas, un optimizador de
consultas, un esquema y un administrador de recuperación de fallas, todos ellos
actuando de manera global.
En cada sitio existe un SMBD completo el cual consiste de la interfaz con el usuario, el
procesador y optimizador de consultas, el manejador de transacciones, el despachador
de operaciones, el manejador de recuperación de fallas y el sistema de soporte para
tiempo de ejecución, todos ellos actuando de manera local. Para comunicar el sistema
global con los sistemas locales se define una interfaz común entre componentes
mediante la cual, las operaciones globales se convierten en una o varias acciones
locales.
El manejo de directorio de datos es de una importancia mayor en bases de datos
distribuidas. Por un lado, puede haber directorios locales o un solo directorio global. Por
otra parte, su manejo puede ser local o distribuido. Finalmente, desde otro punto de
vista el directorio puede ser replicado o no replicado. Como se puede ver en la Figura
2.15, existen combinaciones, en estas tres dimensiones, que no tienen mayor relevancia.
Sin embargo, en varios de los vértices del cubo en tres dimensiones aparecen las
combinaciones importantes para bases de datos distribuidas.
Figura 2.14. Arquitectura basada en componentes de un sistema multi-bases de datos.
Figura 2.15. Manejo del directorio de datos en bases de datos distribuidas.
http://www.cs.cinvestav.mx/SC/prof_personal/adiaz/Disdb/Cap_2.html
Unidad 2. Lenguaje de Definición de
Datos (DDL)
2.1 Creación de base de datos.
La creación de bases de datos.
Con los antecedentes señalados, se inicia la creación de las bases de datos. En primer lugar, y
acorde con los diferentes niveles de arquitectura de bases de datos reseñados, tiene lugar la
construcción del modelo y del esquema conceptual de la base de datos (REINGRUBER y
GREGORY, 1994):
2.6.1. El esquema conceptual.
El esquema conceptual puede definirse como una descripción abstracta y general de la parte o
sector del universo real que el contenido de la base de datos va a representar, llamada en
ocasiones "universo del discurso". En este nivel de análisis se está tratando con una
descripción de la realidad, no con datos, y suele contener listas de tipos de entidades, de las
relaciones existentes entre esas entidades y de las restricciones de integridad que se aplican
sobre ellas. El esquema conceptual de la base de datos puede utilizarse para integrar los
intereses de los diferentes usuarios, como herramienta de representación y de formación, así
como para prever futuras modificaciones del sistema. En el aspecto de la representación, lo
más interesante es utilizar algún tipo de especificación formal en sentido matemático, lo que
facilita la consistencia y los análisis lógicos de los esquemas propuestos. Del esquema
conceptual formalizado pueden derivarse diferentes subesquemas conceptuales, que
representan aquellas partes del esquema conceptual de interés para un usuario o grupo de
usuarios finales.
2.6.2. El esquema de la base de datos.
Una vez construido el esquema conceptual, el diseño de bases de datos obliga a realizar varias
tareas previas a la construcción del esquema lógico global del sistema, también llamado
esquema de bases de datos. Por el momento, basta saber que el esquema de la base de datos
representa la descripción de los datos de la base de datos, mientras que el esquema
conceptual representaba a la realidad. La primera de las tareas necesarias es la identificación
de los datos requeridos, para obtener como resultado las partes del área de aplicación que
deben representarse mediante datos, y en que forma deben presentarse éstos a los usuarios.
El siguiente paso es el análisis de datos, consistente en la definición y clasificación de esos
datos, su descripción, que suele presentarse en forma de diccionario de datos, como una
"metabase de datos". Por último, debe hacerse la especificación de los paquetes de entrada y
de salida, correspondientes con los datos que deben introducir y obtener como respuesta los
usuarios, según sus necesidades. Las tres tareas habrán permitido obtener tres documentos
sobre descripción del área de aplicación, definición y clasificación de los datos y especificación
de las características de los diversos paquetes, respectivamente. Tomando como punto de
partida estos tres elementos, se construye la especificación de esquema de la base de datos,
que responderá al contenido total de la base de datos y las características de las vías de
acceso requeridas a través de estos datos. Frente al análisis de datos, que es la definición y
clasificación de los datos, el esquema se encarga de la utilización de esos datos.
2.6.3. El diccionario de recursos de información (MIGUEL y PIATTINI, 1995).
La gestión efectiva de los datos involucrados en la base de datos implica necesariamente
disponer de alguna herramienta que controle las características y funciones de aquéllos. Esta
función es cubierta mediante el diccionario de recursos de información (DRI),que asegura la
integración de toda la información contenida en el sistema. Se habla entonces de metadatos,
como datos que definen y describen los datos existentes en el sistema. En un primer momento,
este tipo de cuestiones eran resueltas a través de los diccionarios de datos, que reunían
información sobre los datos almacenados, sus descripciones, significados, restricciones, usos,
etc., y los directorios de datos, subsistemas del sistema de gestión, encargados de describir
dónde y cómo se almacenaban los datos, Actualmente se aplica el concepto de diccionario de
recursos de información, que engloban todo lo señalado anteriormente, dando lugar a lo que ha
pasado a llamarse "metabases".
2.6.4. El enfoque de tratamiento de los datos.
La construcción de los modelos conceptual y lógico de las bases de datos requiere la adopción
de un determinado enfoque para la descripción y el tratamiento de los datos. Sin embargo, es
necesario insistir en que la modelización de datos se orienta al conocimiento en profundidad de
los datos que va a manejar la organización, para lograr una implantación óptima. La unión del
modelo de datos con el sistema de gestión de base de datos dará como resultado la base de
datos real. El modelo de datos será una representación gráfica orientada a la obtención de las
estructuras de datos de forma metódica y sencilla, agrupando esos datos en entidades
identificables e individualizables, y será reflejo del sistema de información en estudio.
http://tramullas.com/documatica/2-6.html
Creación de una base de datos: enfoque E/R y transformación relacional.
2.7.1. El enfoque entidad-relación de Chen.
Por sus características, se ha seleccionado el enfoque entidad-relación propuesto por Chen
(CHEN, 1976; MOTA, CELMA Y CASAMAYOR, 1994; KORTH y SILBERSCHATZ, 1993: 25226; BATINI, CERI y NAVATHE, 1994). Este modelo toma como punto de partida considerar la
existencia de entidades, que representan objetos, personas, etc, sobre las que se quiere
almacenar información relevante. Las entidades con las mismas características forman un tipo
de entidad. A las características necesarias para describir completamente a cada tipo de
entidad se les denominará atributo. Posteriormente, las entidades y sus atributos se
representan físicamente a través de tablas (transformación en un modelo relacional) en las que
los datos se almacenan en dos dimensiones. Las filas de la tabla contienen los atributos de
cada una de las entidades, y las columnas el conjunto de atributos del mismo tipo de cada
entidad. El grado de la tabla corresponderá al número de columnas de la tabla. En este
momento estaremos trasladando el modelo semántico entidad/relación al modelo clásico
relacional, se decir, la transformación entre el modelo conceptual y el lógico. El principio
fundamental en este modelado, que no puede obviarse de ninguna forma, es que hechos
distintos deben almacenarse en objetos distintos.
Uno de los puntos fuertes de este modelo es que prevé que las entidades puedan mantener
relaciones entre ellas. En primer lugar, es necesario definir la clave de la entidad. La claves
serán el atributo, o conjunto de atributos, perteneciente al mismo tipo de entidad que hacen
único el acceso a esa entidad u ocurrencia de la tabla, determinando de esta forma a una única
entidad. La presencia de varios atributos que pueden funcionar como clave da lugar a la
existencia de claves candidatas, y por otra parte se puede hablar de claves simples (formadas
por un único atributo) y claves múltiples, compuestas o concatenadas (formadas por un
conjunto de atributos. No hay que obviar tampoco el concepto de clave ajena, aquel atributo de
una tabla que puede funcionar como clave en otra. La ocurrencia de entidad será, en este
contexto, cada uno de los posibles valores reales que puede tomar la clave de una entidad.
Las relaciones entre tablas, basadas en la conexión de éstas a través de las claves, pueden
ofrecer diferentes cardinalidades, entendiendo como tal el número de ocurrencias de una
entidad que se relacionan con ocurrencias de la otra entidad. Pueden identificarse tres tipos:
(1,1), donde una ocurrencia se relaciona con otra; (1,m), donde una ocurrencia puede
relacionarse con varias; y (m,n), donde varias ocurrencias de una entidad pueden relacionarse
con varias ocurrencias de la otra entidad. El modelo de Chen es n-ario, lo cual quiere decir que
las relaciones pueden establecerse entre una, dos o más entidades. Las entidades pueden ser
de dos tipos:
1. Entidad regular: aquella sobre la que se puede definir la clave primario dentro de sus propios
atributos.
2. Entidad débil: aquellas que no puede utilizar sus propios atributos como clave, al estar
asociada a otra entidad.
La definición del modelo conceptual con la técnica propuesta por Chen propone una secuencia
de fases para la obtención del modelo:
1. Identificar las entidades dentro del sistema: para ello, debe conocerse el funcionamiento del
sistema en estudio, a través de estudios de usuarios, de necesidades de información, de tipos
de información, etc. Como guía puede utilizarse para la definición de las entidades objetos
reales, personas, actividades del sistema, objetos abstractos, etc.
2. Determinar las claves o identificadores de entidades: señalar aquellos atributos que
identifiquen inequívocamente cada ocurrencia de la entidad, y que no puedan ofrecer valores
nulos.
3. Establecer las relaciones entre la entidades, describiendo el grado de las mismas: estudiar
las asociaciones entre las entidades, para definir su importancia dentro del contexto del
sistema, y obtener su cardinalidad.
4. Dibujar el modelo de datos: representar gráficamente el modelo obtenido.
5. Identificar y describir los atributos de cada entidad: señalar aquellas propiedades de la
entidad de interés para el sistema.
6. Verificaciones: eliminación de las relaciones redundantes y que puedan ser obtenidas a
través de combinar otras asociaciones.
El modelo obtenido se representa mediante una notación gráfica especializada, a través de
diagramas, cuyas normas generales y variantes especializadas pueden encontrase en la
bibliografía pertinente.
2.7.2. La normalización.
El modelo conceptual de datos obtenido mediante la técnica de entidad-relación será refinado y
convertido en un modelo lógico relacional, utilizando la normalización, lo que ofrecerá como
resultado el conjunto de tablas a implementar en la base de datos (JACKSON, 1990; MIGUEL
Y PIATTINI, 1993: 425-674). Su finalidad es reducir las inconsistencias y redundancias de los
datos, facilitar el mantenimiento y evitar las anomalías en las manipulaciones de datos. El
objetivo será obtener un modelo lógico normalizado que represente las entidades normalizadas
y las interrelaciones existentes entre ellas. Para ello, se toma como punto teórico de partida el
concepto de dependencia funcional, que dice: "Un atributo B depende funcionalmente de otro
atributo A, de la misma entidad si a cada valor de A le corresponde sólo un valor de B." Lo
anterior se completa mediante la dependencia funcional completa y la dependencia transitiva.
El procedimiento de normalización consiste en someter a las tablas que representan entidades
a un análisis formal para ver si cumplen, o no, las restricciones necesarias que aseguren evitar
los problemas citados con anterioridad. A mayor nivel de normalización, mayor calidad en la
organización de los datos y menor peligro para la integridad de los datos. Este procedimiento
consiste en ir alcanzando formas normales
Todo el proceso se basa en que una primera relación universal plantearía enormes problemas
de redundancia, consistencia e integridad de los datos, por lo que es necesario mejorar las
relaciones. Estas mejoras deben dar como resultado tablas equivalentes y mejores que sus
respectivas originales, y poseer siempre tres propiedades: conservación de la información (de
atributos y de tuplas), conservación de dependencias y mínima redundancia de los datos. Las
mejoras introducidas obligan a plantear hasta que Forma Normal es necesario llegar, es decir,
a que nivel de depuración. Normalmente, es recomendable alcanzar la máxima Forma Normal,
aunque luego es muy probable que restricciones existentes, de algún tipo, obliguen a
retroceder a un nivel inferior de normalización, o incluso a cierto nivel de "desnormalización".
http://tramullas.com/documatica/2-7.html
Lenguaje SQL
Creación de bases de datos y tablas
A nivel teórico, existen dos lenguajes para el manejo de bases de datos:
DDL (Data Definition Language) Lenguaje de definición de datos. Es el lenguaje que se
usa para crear bases de datos y tablas, y para modificar sus estructuras, así como los
permisos y privilegios.
Este lenguaje trabaja sobre unas tablas especiales llamadas diccionario de datos.
DML (Data Manipilation Language) lenguaje de manipulación de datos. Es el que se
usa para modificar y obtener datos desde las bases de datos.
SQL engloba ambos lenguajes DDL+DML, y los estudiaremos juntos, ya que ambos
forman parte del conjunto de sentencias de SQL.
En este capítulo vamos a explicar el proceso para pasar del modelo lógico relacional, en
forma de esquemas de relaciones, al modelo físico, usando sentencias SQL, y viendo las
peculiaridades específicas de MySQL.
Crear una base de datos
Cada conjunto de relaciones que componen un modelo completo forma una base de
datos. Desde el punto de vista de SQL, una base de datos es sólo un conjunto de
relaciones (o tablas), y para organizarlas o distinguirlas se accede a ellas mediante su
nombre. A nivel de sistema operativo, cada base de datos se guarda en un directorio
diferente.
Debido a esto, crear una base de datos es una tarea muy simple. Claro que, en el
momento de crearla, la base de datos estará vacía, es decir, no contendrá ninguna tabla.
Vamos a crear y manipular nuestra propia base de datos, al tiempo que nos
familiarizamos con la forma de trabajar de MySQL.
Para empezar, crearemos una base de datos para nosotros solos, y la llamaremos
"prueba". Para crear una base de datos se usa una sentencia CREATE DATABASE:
CREATE DATABASE
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
[create_specification [, create_specification] ...]
create_specification:
[DEFAULT] CHARACTER SET charset_name
| [DEFAULT] COLLATE collation_name
CREATE DATABASE crea una base de datos con el nombre dado. Para usar
CREATE DATABASE se necesita el privilegio CREATE en la base de datos.
Existen reglas para los nombres permitidos de bases de datos, tablas, índices, columnas.
Se producirá un error si la base de datos ya existe y no se ha especificado IF NOT
EXISTS.
Desde MySQL 4.1.1, se pueden usar las opciones create_specification para especificar
características de las base de datos. Estas características se almacenan en el fichero
'db.opt' en el direcorio de la base de datos. La clausula CHARACTER SET especifica el
conjunto de caracteres por defecto para la base de datos. La clausula COLLATE
especifica el conjunto de reglas de comparación de caracteres (collation) por defecto
para la base de datos. Para más detalles sobre juegos de caracteres y reglas de
comparación de caracteres ver Caracteres y reglas.
En MySQL las bases de datos se implementan como directorios que contienen los
ficheros correspondientes a las tablas de la base de datos. Como no hay tablas en una
base de datos cuando esta es creada, la sentencia CREATE DATABASE sólo crea un
directorio bajo el directorio "data" de MySQL (y el fichero 'db.opt' para MySQL 4.1.1 y
siguientes).
CREATE SCHEMA se puede usar a partir de MySQL 5.0.2.
mysql> CREATE DATABASE prueba;
Query OK, 1 row affected (0.03 sec)
mysql>
Podemos averiguar cuántas bases de datos existen en nuestro sistema usando la
sentencia SHOW DATABASES:
SHOW DATABASES
SHOW {DATABASES | SCHEMAS} [LIKE 'patrón']
SHOW DATABASES lista las bases de datos en el ordenador del servidor MySQL.
También se puede obtener esa lista usando el comando mysqlshow. Desde MySQL
4.0.2, sólo es posible ver aquellas bases de datos para las cuales se dispone algún tipo de
privilegio, si no se posee el privilegio global SHOW DATABASES.
Si el servidor fue arrancado con la opción --skip-show-database, no se podrá usar esta
sentencia de ninguna manera, salvo que se disponga del privilegio SHOW DATABASES.
SHOW SCHEMAS se puede usar desde MySQL 5.0.2.
mysql> SHOW DATABASES;
+--------------------+
| Database
|
+--------------------+
| mysql
|
| prueba
|
| test
|
+--------------------+
3 rows in set (0.00 sec)
mysql>
A partir de ahora, en los próximos capítulos, trabajaremos con esta base de datos, por lo
tanto la seleccionaremos como base de datos por defecto. Esto nos permitirá obviar el
nombre de la base de datos en consultas. Para seleccionar una base de datos se usa el
comando USE, que no es exactamente una sentencia SQL, sino más bien de una opción
de MySQL:
USE
USE db_name
La sentencia USE db_name indica a MySQL que use la base de datos db_name como
la base de datos por defecto (actual) en sentencias subsiguientes. La base de datos sigue
siendo la base de datos por defecto hasta el final de la sesión o hasta que se use otra
sentencia USE:
mysql>
mysql>
mysql>
mysql>
USE db1;
SELECT COUNT(*) FROM mytable;
USE db2;
SELECT COUNT(*) FROM mytable;
# selecciona desde db1.mytable
# selecciona desde db2.mytable
Hacer que una base de datos determinada sea la actual mediante el uso de la sentencia
USE no descarta que se pueda acceder a tablas de otras bases de datos. El ejemplo
siguiente accede a la tabla author de la base de datos db1 y a la tabla editor de la base
de datos db2:
mysql> USE db1;
mysql> SELECT author_name,editor_name FROM author,db2.editor
->
WHERE author.editor_id = db2.editor.editor_id;
La sentencia USE se proporciona por compatibilidad con Sybase.
mysql> USE prueba;
Database changed
mysql>
http://mysql.conclase.net/curso/index.php?cap=007
2.2
Creación de tablas.
Crear una tabla
Veamos ahora la sentencia CREATE TABLE que sirve para crear tablas.
La sintaxis de esta sentencia es muy compleja, ya que existen muchas opciones y
tenemos muchas posibilidades diferentes a la hora de crear una tabla. Las iremos viendo
paso a paso, y en poco tiempo sabremos usar muchas de sus posibilidades.
En su forma más simple, la sentencia CREATE TABLE creará una tabla con las
columnas que indiquemos. Crearemos, como ejemplo, una tabla que nos permitirá
almacenar nombres de personas y sus fechas de nacimiento. Deberemos indicar el
nombre de la tabla y los nombres y tipos de las columnas:
mysql> USE prueba
Database changed
mysql> CREATE TABLE gente (nombre VARCHAR(40), fecha DATE);
Query OK, 0 rows affected (0.53 sec)
mysql>
Hemos creado una tabla llamada "gente" con dos columnas: "nombre" que puede
contener cadenas de hasta 40 caracteres y "fecha" de tipo fecha.
Podemos consultar cuántas tablas y qué nombres tienen en una base de datos, usando la
sentencia SHOW TABLES:
mysql> SHOW TABLES;
+------------------+
| Tables_in_prueba |
+------------------+
| gente
|
+------------------+
1 row in set (0.01 sec)
mysql>
Pero tenemos muchas más opciones a la hora de definir columnas. Además del tipo y el
nombre, podemos definir valores por defecto, permitir o no que contengan valores
nulos, crear una clave primaria, indexar...
La sintaxis para definir columnas es:
nombre_col tipo [NOT NULL | NULL] [DEFAULT valor_por_defecto]
[AUTO_INCREMENT] [[PRIMARY] KEY] [COMMENT 'string']
[definición_referencia]
Veamos cada una de las opciones por separado.
Valores nulos
Al definir cada columna podemos decidir si podrá o no contener valores nulos.
Debemos recordar que, como vimos en los capítulos de modelado, aquellas columnas
que son o forman parte de una clave primaria no pueden contener valores nulos.
Veremos que, si definimos una columna como clave primaria, automáticamente se
impide que pueda contener valores nulos, pero este no es el único caso en que puede ser
interesante impedir la asignación de valores nulos para una columna.
La opción por defecto es que se permitan valores nulos, NULL, y para que no se
permitan, se usa NOT NULL. Por ejemplo:
mysql> CREATE TABLE ciudad1 (nombre CHAR(20) NOT NULL, poblacion INT
NULL);
Query OK, 0 rows affected (0.98 sec)
Valores por defecto
Para cada columna también se puede definir, opcionalmente, un valor por defecto. El
valor por defecto se asignará de forma automática a una columna cuando no se
especifique un valor determinado al añadir filas.
Si una columna puede tener un valor nulo, y no se especifica un valor por defecto, se
usará NULL como valor por defecto. En el ejemplo anterior, el valor por defecto para
poblacion es NULL.
Por ejemplo, si queremos que el valor por defecto para poblacion sea 5000, podemos
crear la tabla como:
mysql> CREATE TABLE ciudad2 (nombre CHAR(20) NOT NULL,
-> poblacion INT NULL DEFAULT 5000);
Query OK, 0 rows affected (0.09 sec)
Claves primarias
También se puede definir una clave primaria sobre una columna, usando la palabra
clave KEY o PRIMARY KEY.
Sólo puede existir una clave primaria en cada tabla, y la columna sobre la que se define
una clave primaria no puede tener valores NULL. Si esto no se especifica de forma
explícita, MySQL lo hará de forma automática.
Por ejemplo, si queremos crear un índice en la columna nombre de la tabla de ciudades,
crearemos la tabla así:
mysql> CREATE TABLE ciudad3 (nombre CHAR(20) NOT NULL PRIMARY KEY,
-> poblacion INT NULL DEFAULT 5000);
Query OK, 0 rows affected (0.20 sec)
Usar NOT NULL PRIMARY KEY equivale a PRIMARY KEY, NOT NULL KEY o
sencillamente KEY. Personalmente, prefiero usar la primera forma o la segunda.
Existe una sintaxis alternativa para crear claves primarias, que en general es preferible,
ya que es más potente. De hecho, la que hemos explicado es un alias para la forma
general, que no admite todas las funciones (como por ejemplo, crear claves primarias
sobre varias columnas). Veremos esta otra alternativa un poco más abajo.
Columnas autoincrementadas
En MySQL tenemos la posibilidad de crear una columna autoincrementada, aunque esta
columna sólo puede ser de tipo entero.
Si al insertar una fila se omite el valor de la columna autoinrementada o si se inserta un
valor nulo para esa columna, su valor se calcula automáticamente, tomando el valor más
alto de esa columna y sumándole una unidad. Esto permite crear, de una forma sencilla,
una columna con un valor único para cada fila de la tabla.
Generalmente, estas columnas se usan como claves primarias 'artificiales'. MySQL está
optimizado para usar valores enteros como claves primarias, de modo que la
combinación de clave primaria, que sea entera y autoincrementada es ideal para usarla
como clave primaria artificial:
mysql> CREATE TABLE ciudad5 (clave INT AUTO_INCREMENT PRIMARY KEY,
-> nombre CHAR(20) NOT NULL,
-> poblacion INT NULL DEFAULT 5000);
Query OK, 0 rows affected (0.11 sec)
mysql>
Comentarios
Adicionalmente, al crear la tabla, podemos añadir un comentario a cada columna. Este
comentario sirve como información adicional sobre alguna característica especial de la
columna, y entra en el apartado de documentación de la base de datos:
mysql> CREATE TABLE ciudad6
-> (clave INT AUTO_INCREMENT PRIMARY KEY COMMENT 'Clave
principal',
-> nombre CHAR(50) NOT NULL,
-> poblacion INT NULL DEFAULT 5000);
Query OK, 0 rows affected (0.08 sec)
CREATE TABLE
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
[(definición_create,...)]
[opciones_tabla] [sentencia_select]
O
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
[(] LIKE viejo_tbl_name [)];
Sintaxis de definición_create:
|
|
|
|
definición_columnas
[CONSTRAINT [símbolo]] PRIMARY KEY (index_nombre_col,...)
KEY [nombre_index] (nombre_col_index,...)
INDEX [nombre_index] (nombre_col_index,...)
[CONSTRAINT [símbolo]] UNIQUE [INDEX]
[nombre_index] [tipo_index] (nombre_col_index,...)
| [FULLTEXT|SPATIAL] [INDEX] [nombre_index] (nombre_col_index,...)
| [CONSTRAINT [símbolo]] FOREIGN KEY
[nombre_index] (nombre_col_index,...) [definición_referencia]
| CHECK (expr)
Sintaxis de definición_columnas:
nombre_col tipo [NOT NULL | NULL] [DEFAULT valor_por_defecto]
[AUTO_INCREMENT] [[PRIMARY] KEY] [COMMENT 'string']
[definición_referencia]
Sintaxis de tipo:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TINYINT[(longitud)] [UNSIGNED] [ZEROFILL]
SMALLINT[(longitud)] [UNSIGNED] [ZEROFILL]
MEDIUMINT[(longitud)] [UNSIGNED] [ZEROFILL]
INT[(longitud)] [UNSIGNED] [ZEROFILL]
INTEGER[(longitud)] [UNSIGNED] [ZEROFILL]
BIGINT[(longitud)] [UNSIGNED] [ZEROFILL]
REAL[(longitud,decimales)] [UNSIGNED] [ZEROFILL]
DOUBLE[(longitud,decimales)] [UNSIGNED] [ZEROFILL]
FLOAT[(longitud,decimales)] [UNSIGNED] [ZEROFILL]
DECIMAL(longitud,decimales) [UNSIGNED] [ZEROFILL]
NUMERIC(longitud,decimales) [UNSIGNED] [ZEROFILL]
DATE
TIME
TIMESTAMP
DATETIME
CHAR(longitud) [BINARY | ASCII | UNICODE]
VARCHAR(longitud) [BINARY]
TINYBLOB
BLOB
MEDIUMBLOB
LONGBLOB
TINYTEXT
TEXT
MEDIUMTEXT
LONGTEXT
ENUM(valor1,valor2,valor3,...)
SET(valor1,valor2,valor3,...)
tipo_spatial
Sintaxis de nombre_col_index:
nombre_col [(longitud)] [ASC | DESC]
Sintaxis de definición_referencia:
REFERENCES nombre_tbl [(nombre_col_index,...)]
[MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]
[ON DELETE opción_referencia]
[ON UPDATE opción_referencia]
Sintaxis de opción_referencia:
RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
Sintaxis de opciones_tabla:
opción_tabla [opción_tabla] ...
Sintaxis de opción_tabla:
{ENGINE|TYPE} = {BDB|HEAP|ISAM|InnoDB|MERGE|MRG_MYISAM|MYISAM }
AUTO_INCREMENT = valor
AVG_ROW_LENGTH = valor
CHECKSUM = {0 | 1}
COMMENT = 'cadena'
MAX_ROWS = valor
MIN_ROWS = valor
PACK_KEYS = {0 | 1 | DEFAULT}
PASSWORD = 'cadena'
DELAY_KEY_WRITE = {0 | 1}
ROW_FORMAT = { DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNTANT|COMPACT}
RAID_TYPE = { 1 | STRIPED | RAID0 }
RAID_CHUNKS=valor
RAID_CHUNKSIZE=valor
| UNION = (nombre_tabla,[nombre_tabla...])
| INSERT_METHOD = { NO | FIRST | LAST }
| DATA DIRECTORY = 'camino de directorio absoluto'
| INDEX DIRECTORY = 'camino de directorio absoluto'
| [DEFAULT] CHARACTER SET nombre_conjunto_caracteres [COLLATE
nombre_cotejo]
|
|
|
|
|
|
|
|
|
|
|
Sintaxis de sentencia_select:
[IGNORE | REPLACE] [AS] SELECT ...
legal)
(Alguna sentencia select
CREATE TABLE crea una tabla con el nombre dado. Se debe poseer el privilegio
CREATE para la tabla.
Las reglas para nombres válidos de tablas se pueden ver aquí. Por defecto, la tabla se
crea en la base de datos actual. Se producirá un error si la tabla ya existe, si no hay una
base de datos actual o si la base de datos no existe.
En versiones de MySQL 3.22 y posteriores, el nombre de la tabla se puede especificar
como db_name.tbl_name para la creación de la tabla en una base de datos específica.
Esto funciona aunque no exista una base de datos seleccionada. Si se escribe el nombre
de la tabla entre comillas, el nombre de la base de datos y el de la tabla se deben
entrecomillar separadamente. Por ejemplo, `midb`.`mitabla` es legal, pero
`midb.mitabla` no lo es.
Desde la versión 3.23 de MySQL se puede usar la palabra clave TEMPORARY cuando
se quiere crear una tabla. La tabla temporal sólo es visible para la conexión actual, y
será borrada automáticamente cuando se cierre la conexión. Esto significa que dos
conexiones diferentes pueden usar simultaneamente el mismo nombre para una tabla
temporal sin conflictos entre ellas o con una tabla existente con el mismo nombre. (La
tabla existente se ocultará hasta que la tabla temporal sea borrada). Desde MySQL 4.0.2
se debe tener el privilegio CREATE TEMPORARY TABLES para que sea posible crear
tablas temporales.
Desde la versión 3.23 de MySQL se puede usar IF NOT EXISTS de modo que no se
obtiene un error si la tabla ya existe. No se hace verificación de si la tabla existente tiene
una estructura idéntica a la indicada por la sentecia CREATE TABLE.
Cada tabla tbl_name se representa mediante algunos ficheros en el directorio de la base
de datos. En el caso de tablas de tipo MyISAM se tendrá:
Fichero
tbl_name.frm
Propósito
Fichero de definición de formato de tabla
tbl_name.MYD Fichero de datos
tbl_name.MYI Fichero de índices
En la documentación de MySQL es posible encontrar información sobre el modo en que
cada motor de almacenamiento crea los ficheros que representan las tablas.
Para detalles sobre tipos de columnas ver el capítulo 5.
De momento no hemos incluido información sobre las extensiones espaciales de
MySQL (spatial).


Si no se especifica ni NULL ni NOT NULL, la columna se trata como si se
hubiese especificado NULL.
Una columna entera puede tener el atributo adicional AUTO_INCREMENT.
Cuando se inserta un valor NULL (que es lo recomendado) o 0 en una columna
indexada AUTO_INCREMENT, se usa como valor para la columna el siguiente
valor secuencial. Normalmente ese valor es valor+1, donde valor es el mayor
valor en la columna actual en la tabla. Las secuencias AUTO_INCREMENT
empiezan en 1. Ver mysql_insert_id.
Nota: sólo puede existir una columna AUTO_INCREMENT por tabla, debe estar
indexada y no puede tener un valor DEFAULT.
En la versión 3.23 de MySQL una columna AUTO_INCREMENT sólo
funcionará correctamente si contiene valores positivos. La inserción de un
número negativo se considera como un número positivo muy grande. Esto se
hace para evitar que por problemas de precisión números pasen de positivo a
negativo y también para asegurar que accidentalmente una columa
AUTO_INCREMENT contenga un cero. En tablas MyISAM y BDB se puede
especificar AUTO_INCREMENT en una columna secundaria dentro de una clave
multi-columna. Para hacer MySQL compatible con algunas aplicaciones ODBC,
se puede encontrar el valor AUTO_INCREMENT para la última fila insertada
mediante la siguiente consulta:
SELECT * FROM tbl_name WHERE auto_col IS NULL

Desde la versión 4.1 de MySQL, las definiciones de columnas de caracteres
pueden incluir un atributo CHARACTER SET para especificar el conjunto de
caracteres y, opcionalmente, un conjunto de reglas de comparación para la
columna. Ver apéndice C.
CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);
También desde la versión 4.1, MySQL interpreta las especificaciones de
longitud en definiciones de columnas de texto en caracteres. (Versiones
anteriores las interpretaban en bytes.)


Los valores NULL se manejan de modo diferente para columnas del tipo
TIMESTAMP que para otros tipos. Antes de la versión 4.1.6 de MySQL no era
posible almacenar un literal NULL en una columna TIMESTAMP; un valor
NULL para la columna le asignaba el valor de fecha y hora actual. Debido a ese
comportamiento de TIMESTAMP, los atributos NULL y NOT NULL no se
aplicaban del modo normal, y eran ignorados si se especifican. Por otra parte,
para hacer más fácil para los clientes MySQL el uso de columnas TIMESTAMP,
el servidor informa que a esas columnas se les puede asignar valores NULL, lo
cual es cierto, aunque TIMESTAMP nunca puede contener un valor NULL. Es
posible ver esto cuando se usa DESCRIBE tbl_name para obtener la descripción
de una tabla. Por cierto, asignar 0 a una columna TIMESTAMP no es lo mismo
que asignar NULL, ya que 0 es un valor válido para TIMESTAMP.
La clausula DEFAULT especifica un valor por defecto para una columna. Con
una excepción, el valor por defecto debe ser una constante, no puede ser una
función o una expresión. Esto significa, por ejemplo, que no se puede asignar
como fecha por defecto para una columna el valor de una función como NOW()
o CURRENT_DATE. La excepción es que se puede asignar
CURRENT_TIMESTAMP como el valor por defecto par auna columna
TIMESTAMP desde la versión 4.1.2 de MySQL. Si no se especifica un valor
explicito por defecto para una columna, MySQL automáticamente asigna uno,
como sigue. Si la columna puede tomar un valor NULL, la columna se define
con una clausula DEFAULT NULL explícita. Si la columna no puede tomar el
valor NULL, MySQL define la columna con una clausula DEFAULT explícita,
usando el valor implícito para el tipo de columna. El valor por defecto implícito
se define como:
o Para tipos numéricos no declarados con el atributo AUTO_INCREMENT,
el valor por defecto es 0. Para las columnas AUTO_INCREMENT, el
valor por defecto es el siguiente valor dentro de la secuencia.
o Para tipos de fecha y tiempo distintos de TIMESTAMP, el valor por
defecto es el valor cero apropiado para el tipo. Para la primera columna
TIMESTAMP de la tabla, el valor por defecto es la fecha y hora actuales.
o Para tipos de cadena distintos de ENUM, el valor por defecto es la
cadena vacía. Para los ENUM, el valor por defecto es el primero valor de
la enumeración.
A las columnas BLOB y TEXT no se les puede asignar un valor por defecto.


Se puede especificar un comentario para una columna con la opción
COMMENT. El comentario se muestra mediante la sentencia SHOW CREATE
TABLE, y por SHOW FULL COLUMNS. Esta opción está disponible desde
MySQL 4.1. (Está permitida pero se ignora en versiones anteriores.)
Desde la versión 4.1.0 de MySQL 4.1.0, se puede usar el atributo SERIAL como
un alias para BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE.
Esta es una característica de compatibilidad.










KEY normalmente es sinónimo de INDEX. Desde la versión 4.1, el atributo de
clave PRIMARY KEY puede especificarse también como KEY. Esto se ha
implementado para compatibilidad con otras base de datos.
En MySQL, una clave UNIQUE sólo puede contener valores diferentes. Se
produce un error si se intenta insertar una fila nueva con una clave que coincida
con la de una fila existente. La excepción es si una columan en el índice puede
tomar valores NULL, entonces puede contener múltiples valores NULL. Esta
excepción no se aplica a tablas BDB, para las que una columna indexada permite
sólo un valor NULL.
Una PRIMARY KEY es una KEY única donde todas las columnas clave deben
estar definidas como NOT NULL. Si no están declarados específicamente como
NOT NULL, debe hacerse implícitamente (y discretamente). Una tabla sólo
puede contener una PRIMARY KEY. Si no se tiene una y alguna aplicación
solicita una, MySQL devolverá el primer índice UNIQUE que no tenga
columnas NULL, como PRIMARY KEY.
En la tabla creada, una PRIMARY KEY se coloca la primera, seguida por todos
los índices UNIQUE, y después los índices no únicos. Esto ayuda al optimizador
de MySQL para dar prioridad sobre qué índice usar y para detectar más
rápudamente claves UNIQUE duplicadas.
Una PRIMARY KEY puede se un índice multicolumna. Sin embargo, no se
puede crear un índice multicolumna usando el atributo PRIMARY KEY en la
especificación de columna. Hacer esto marca sólo esa columna como primaria.
Se debe usar una clausula adicional PRIMARY KEY(nombre_col_index, ...).
Si la clave PRIMARY o UNIQUE consiste sólo en una columna y es de tipo
entero, se puede también referenciar como _rowid en una sentencia SELECT
(desde la Versión 3.23.11).
En MySQL, el nombre de un PRIMARY KEY es PRIMARY. Para otros índices,
si no se asigna un nombre, se le asigna el mismo nombre que la primera
columna indexada, con un sufijo opcional (_2, _3. ...) para hacerlo único. Se
pueden ver los nombres de los índices usando la sentencia SHOW INDEX
FROM nombre_tabla.
Desde MySQL 4.1.0, algunos motores de almacenamiento premiten especificar
un tipo de índice cuando este es creado. La sintaxis para el especificador de
tipo_indice es USING nombre_tipo. Por ejemplo:
CREATE TABLE lookup
(id INT, INDEX USING BTREE (id))
ENGINE = MEMORY;
Ver CREATE INDEX para más detalles.


Sólo las tablas de tipos MyISAM, InnoDB, BDB y (desde MySQL 4.0.2)
MEMORY soportan índices en columnas que contengan valors NULL. En otros
casos se deben declarar esas columnas como NOT NULL o se producirá un error.
Con al sintaxis col_name(longitud) en una especificación de un índice, se puede
crear un índice que use sólo los primeros 'longitud' bytes de una columna CHAR
o VARCHAR. Esto puede hacer que el fichero de índices sea mucho más
pequeño. Las tablas de tipos MyISAM y (desde MySQL 4.0.14) InnoDB
soportan indexación en columnas BLOB y TEXT. Cuando se usa un índice en
una columna BLOB o TEXT se debe especificar siempre la longitud de los
índices. Por ejemplo:
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
Los prefijos pueden tener hasta 255 bytes de longitud (o 1000 bytes para tablas
MyISAM y InnoDB desde MySQL 4.1.2). Notar que los límites de los prefijos
se miden en bytes, aunque la longitud del prefijo en sentencias CREATE
INDEX se interpretan como número de caracteres. Hay que tener esto en cuenta
cuando se especifica una longitud de prefijo para una columna que usa un
conjunto de caracteres multi-byte.









Una especificación de nombre_col_index puede terminar con ASC o DESC.
Estas palabras clave están permitidas para futuras extensiones para la
especificación de almacenamiento de índices ascendentes o descendentes.
Actualmente se verifica su sintaxis, pero se ignoran; los valores de índices
siempre se almacenan en orden ascendente.
Cuando se usa ORDER BY o GROUP BY con una columna TEXT o BLOB, el
servidor ordena los valores usando sólo los bytes iniciales indicados por la
variable del servidor max_sort_length.
En versiones de MySQL 3.23.23 o posteriores, se pueden crear índices
especiales FULLTEXT. Se usan para búsquerdas de texto completo. Sólo las
tablas de tipo MyISAM soportan índices FULLTEXT. Sólo pueden ser creados
desde columnas CHAR, VARCHAR y TEXT. La indexación siempre se hace
sobre la columna completa; la indexación parcial no está soportada y cualquier
longitud de prefijo es ignorada si se especifica.
A partir de MySQL 4.1, se pueden crear índices SPATIAL en columnas de tipo
espacial. Los tipos espaciales se soportan sólo para tablas MyISAM y las
columnas indexadas deben declararse como NOT NULL.
A partir de la versión 3.23.44 de MySQL, las tablas InnoDB soportan
verificación para restricciones de claves foráneas. Hay que tener en cuenta que
la sintaxis para FOREIGN KEY en InnoDB es mucho más restrictiva que la
sintaxis presentada antes: las columnas en la tabla referenciada deben ser
nombradas explícitamente. InnoDB soporta las acciones ON DELETE y ON
UPDATE para claves ajenas tanto para MySQL 3.23.50 como para 4.0.8,
respectivamente. Para otros tipos de tablas, el servidor MySQL verifica la
sintaxis de FOREIGN KEY, CHECK y REFERENCES en comandos CREATE
TABLE, pero no se toma ninguna acción.
Para tablas MyISAM y ISAM, cada columna NULL require un bit extra,
redondeando hacia arriba al siguiente byte. El tamaño máximo para un registro,
en bytes, puede calcularse del siquiente modo:
row length = 1
+ (sum of column lengths)
+ (number of NULL columns + delete_flag + 7)/8
+ (number of variable-length columns)
El delete_flag es 1 para tablas con formato de registro estático. Las tablas
estáticas usan un bit en una fila de registro como un banderín que indica si la fila
ha sido borrada.
delete_flag es 0 para tablas dinámicas porque el banderín se almacena en una
fila de cabecera dinámica. Estos cálculos no se aplican a tablas InnoDB, para las
que el tamaño de almacenamiento no es diferente para columnas NULL en
comparación con las NOT NULL.
La parte opciones_tabla de CREATE TABLE sólo están disponibles desde MySQL
3.23.
Las opciones ENGINE y TYPE especifican el motor de almacenamiento para la tabla.
ENGINE se añadió en MySQL 4.0.18 (para 4.0) y 4.1.2 (para 4.1). Esta es la opción
aconsejada desde esas versiones, y TYPE queda desaconsejada. TYPE será soportada a
lo largo de la serie 4.x series, pero será eliminada en MySQL 5.1.
Las opciones ENGINE y TYPE pueden tomar los valores siguientes:
Motor de
almacenamiento
BDB
Tablas de transacción segura con bloqueo de página.
BerkeleyDB
Alias para BDB.
HEAP
Los datos para esta tabla sólo se almacenan en memoria.
ISAM
El motor de almacenamoento original de MySQL.
InnoDB
Tablas de transacción segura con bloqueo de fila y claves
foráneas.
MEMORY
Alias para HEAP.
MERGE
Una colección de tablas MyISAM usadas como una tabla.
MRG_MyISAM
Un alias para MERGE.
MyISAM
El nuevo motor binario de almacenamiento portable que
reemplaza a ISAM.
Descripción
Si se especifica un tipo de tabla, y ese tipo particular no está disponible, MySQL usará
el tipo MyISAM. Por ejemplo, si la definición de la tabla incluye la opción
ENGINE=BDB pero el servidor MySQL no soporta tablas BDB, la tabla se creará como
una tabla MyISAM. Esto hace posible tener un sistema de réplica donde se tienen tablas
operativas en el maestro pero las tablas creadas en el esclavo no son operativas (para
obtener mayor velocidad). En MySQL 4.1.1 se obtiene un aviso si el tipo de tabla
especificado no es aceptable.
Las otras opciones de tabla se usan para optimizar el comportamiento de la tabla. En la
mayoría de los casos, no se tendrá que especificar ninguna de ellas. Las opciones
trabajan con todos los tipos de tabla, salvo que se indique otra cosa:
Option
Descripción
El valor inicial AUTO_INCREMENT que se quiere seleccionar
para la tabla. Sólo funciona en tablas MyISAM. Para poner el
AUTO_INCREMENT primer valor de un auto-incrementado para una tabla InnoDB,
insertar una fila vacía con un valor una unidad menor, y
después borrarla.
Una aproximación de la longitud media de fila de la tabla. Sólo
se necesita esto para tablas largas con tamaño de registro
AVG_ROW_LENGTH
variable. When you create a MyISAM table, MySQL uses the
product of the MAX_ROWS and AVG_ROW_LENGTH
options to decide how big the resulting table will be. If you
don't specify either option, the maximum size for a table will
be 4GB (or 2GB if your operating system only supports 2GB
tables). The reason for this is just to keep down the pointer
sizes to make the index smaller and faster if you don't really
need big files. If you want all your tables to be able to grow
above the 4GB limit and are willing to have your smaller tables
slightly slower and larger than necessary, you may increase the
default pointer size by setting the myisam_data_pointer_size
system variable, which was added in MySQL 4.1.2.
CHECKSUM
Ponerlo a 1 si se quiere que MySQL mantenga un checksum
para todas las filas (es decir, un checksum que MySQL
actualiza automáticamente cuando la tabla cambia. Esto hace la
tabla un poco más lenta al actualizar, pero hace más sencillo
localizar tablas corruptas. La sentencia CHECKSUM TABLE
devuelve el valor del checksum. (Sólo MyISAM).
COMMENT
Un comentario de 60 caracteres para la tabla.
MAX_ROWS
Número máximo de filas que se planea almacenar en la tabla.
MIN_ROWS
Mínimo número de filas que se planea almacenar en la tabla.
Ponerlo a 1 si se quiere tener índices más pequeños. Esto
normalmente hace que las actualizaciones sean más lentas y las
lecturas más rápidas. Ponerlo a 0 desactiva cualquier
empaquetado de claves. Ponerlo a DEFAULT (MySQL 4.0)
indica al motor de almacenamiento que sólo empaquete
columnas CHAR/VARCHAR largas. (Sólo MyISAM y ISAM).
Si no se usa PACK_KEYS, por defecto sólo se empaquetan
cadenas, no números. Si se usa PACK_KEYS=1, los números
serán empaquetados también. Cuando se empaquetan claves de
números binarios, MySQL usa compresión con prefijo:


PACK_KEYS
Cada clave necesita un byte extra para indicar cuantos
bytes de la clave anterior son iguales en la siguiente.
El puntero a la fila se almacena guardando primero el
byte de mayor peso directamente después de la clave,
para mejorar la compresión.
Esto significa que si existen muchas claves iguales en dos filas
consecutivas, todas las claves "iguales" que sigan generalmente
sólo necesitarán dos bytes (incluyendo el puntero a la fila).
Comparar esto con el caso corriente, donde las claves
siguientes tendrán tamaño_almacenamiento_clave +
tamaño_puntero (donde el tamaño del puntero normalmente es
4). Por otra parte, sólo se obtendrá un gran beneficio de la
compresión prefija si hay muchos números que sean iguales. Si
todas las claves son totalmente distintas, se usará un byte más
por clave, si la clave no es una que pueda tener valores NULL.
(En ese caso, la longitud de la clave empaquetada será
almacenada en el mismo byte que se usa para marcar si la clave
es NULL.)
PASSWORD
Encripta el fichero `.frm' con un password. Esta opción no hace
nada en la versión estándar de MySQL.
DELAY_KEY_WRITE
Poner esto a 1 si se quiere posponer la actualización de la tabla
hasta que sea cerrada (sólo MyISAM).
ROW_FORMAT
Define cómo deben almacenarse las filas. Actualmente esta
opción sólo funciona con tablas MyISAM. El valor de la
opción puede ser DYNAMIC o FIXED para formatos de fila
estático o de longitud variable.
RAID_TYPE
La opción RAID_TYPE permite exceder el límite de 2G/4G
para un fichero de datos MyISAM (no el fichero de índice) en
sistemas operativos que no soportan ficheros grandes.
Observese que esta opción es innecesaria y no se recomienda
para sistemas de ficheros que soporten ficheros grandes. Se
puede obtener mayor velocidad de cuellos de botella de
entrada/salida usando directorios RAID en discos físicos
diferentes. Por ahora, el único valor permitido para
RAID_TYPE es STRIPED. 1 y RAID0 son alias de STREPED.
Si se especifica al opción RAID_TYPE para una tabla
MyISAM, también es posible especificar las opciones
RAID_CHUNKS y RAID_CHUNKSIZE. El valor máximo para
RAID_CHUNCKS es 255. MyISAM creará RAID_CHUNKS
subdirectorios con los nombres '00', '01', '02',... '09', '0a', '0b,...
en el directorio de la base de datos. En cada uno de esos
directorios, MyISAM creará un "table_name.MYD". Cuando
se escriban datos al fichero de datos, el manipulador RAID
mapea los primeros RAID_CHUNKSIZE *1024 bytes al primer
fichero, los siguientes RAID_CHUNKSIZE *1024 bytes al
siguiente, y así sucesivamente. RAID_TYPE funciona en
cualquier sistema operativo, siempre que se construya MySQL
con la opción de configuración --with-raid. Para determinar si
el servidor soporta tablas RAID, usar SHOW VARIABLES
LIKE 'have_raid' para ver si el valor de la variable es YES.
UNION
UNION se usa cuando se quiere usar una colección de tablas
idénticas como una. Esto sólo funciona con tablas MERGE.
Por el momento es necesario tener los privilegios SELECT,
UPDATE y DELETE en las tablas a mapear en una tabla
MERGE. Originalmente, todas las tablas mapeadas deben
pertenecer a la misma base de datos que la propia tabla
MERGE. Esta restricción ha sido eliminada a partir de MySQL
4.1.1.
INSERT_METHOD
Si se quiere insertar tados en una tabla MERGE, se debe
especificar con INSERT_METHOD dentro de qué la tabla se
insertará la fila. INSERT_METHOD es una opción frecuente
sólo en tablas MERGE. Esta opción se introdujo en MySQL
4.0.0.
DATA DIRECTORY
Usando DATA DIRECTORY='directory' o INDEX
INDEX DIRECTORY DIRECTORY='directory' se puede especificar dónde colocará
el motor de almacenamiento el fichero de datos y el de índices.
Este directorio debe ser un camino completo al directorio (no
un camino relativo). Esto sólo funciona con tablas MyISAM
desde MySQL 4.0, cuando no se está usando la opción --skipsymlink.
A partir de MySQL 3.23, se puede crear una tabla a partir de otra añadiendo la sentencia
SELECT al final de la sentencia CREATE TABLE:
CREATE TABLE new_tbl SELECT * FROM orig_tbl;
MySQL creará nuevos campos para todos los elementos del SELECT. Por ejemplo:
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
->
PRIMARY KEY (a), KEY(b))
->
TYPE=MyISAM SELECT b,c FROM test2;
Esto creará una tabla MyISAM con tres columnas, a, b y c. Hay que tener en cuenta que
esas tres columnas de la sentencia SELECT se añaden al lado derecho de la tabla, no
superpuestos. Ver el siguiente ejemplo:
mysql> SELECT * FROM foo;
+---+
| n |
+---+
| 1 |
+---+
mysql> CREATE TABLE bar (m INT) SELECT n FROM foo;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM bar;
+------+---+
| m
| n |
+------+---+
| NULL | 1 |
+------+---+
1 row in set (0.00 sec)
Para cada fila en la tabla foo, se inserta una fila en bar con los valores de foo y los
valores por defecto para las nuevas columnas.
Si se produce cualquier error mientras se copian los datos a la tabla, esta se eliminará
automáticamente y no se creará.
CREATE TABLE ... SELECT no creará indices de forma automática. Esto se ha
hecho de forma intencionada para hacer el comando tan flexible como sea posible. Si se
quiere tener índices en la tabla creada, se puede especificar después de la sentencias
SELECT:
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
Se pueden producir algunas conversiones de tipos de columna. Por ejemplo, el atributo
AUTO_INCREMENT no se preserva, y columasn VARCHAR se pueden convertir en
CHAR.
Cuando se crea una tabla con CREATE ... SELECT, hay que asegurarse de crear alias
para cualquier llamada a función o expresión en la consulta. Si no se hace, la sentencia
CREATE podrá fallar o pueden resultar nombres de columna no deseados.
CREATE TABLE artists_and_works
SELECT artist.name, COUNT(work.artist_id) AS number_of_works
FROM artist LEFT JOIN work ON artist.id = work.artist_id
GROUP BY artist.id;
Desde MySQL 4.1, se puede especificar explícitamente el tipo para una columna
generada:
CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;
En MySQL 4.1, también se puede usar LIKE para crear una tabla vacía basada en la
definición de otra tabla, incluyendo cualquier atributo de columna e indices que tenga la
tabla original:
CREATE TABLE new_tbl LIKE orig_tbl;
CREATE TABLE ... LIKE no copia ninguna opción de tabla DATA DIRECTORY o
INDEX DIRECTORY que se haya especificado en la tabla original, o cualquier
definición de clave foránea.
Se puede preceder el SELECT por IGNORE o REPLACE para indicar como manipular
registros que dupliquen claves únicas. Con IGNORE, los nuevos registros que dupliquen
la clave única de un registro existente serán descartados. Con REPLACE, los nuevos
registros reemplazan a los que tengan el mismo valor de clave única. Si no se especifica
IGNORE ni REPLACE, la repetición de claves únicas producirá un error.
Para asegurar que el diario de modificación puede ser usado para recrear las tablas
originales, MySQL no permite la inserción concurrente durante CREATE TABLE ...
SELECT.
Cambios de especificaciones de columna sin
notificación
En algunos casos, MySQL hace cambios en las especificaciones de columna dadas en
una sentencia CREATE TABLE o ALTER TABLE sin notificarlo:


Las columnas VARCHAR con una longitud menor de cuatro se cambian a
CHAR.
Si cualquier columna en una tabla tiene una longitud variable, la fila completa se
conviente en una de longitud variable. Del mismo modo, si una tabla contiene
alguna columna de longitud variable (VARCHAR, TEXT o BLOB), todas las
columnas CHAR de más de cuatro caracteres se cambian a columnas VARCHAR.







Esto no afecta al modo en que se usen estas columnas; en MySQL, VARCHAR
es sólo una forma diferente de almacenar caracteres. MySQL realiza esta
conversión porque esto ahorra espacio y hace las operaciones en la tabla más
rápidas.
A partir de MySQL 4.1.0, una columna CHAR o VARCHAR con una
especificación de longitud mayor de 255 se convierte al tipo TEXT más pequeño
que pueda contener valores de la longitud dada. Por ejemplo, VARCHAR(500) se
convierte a TEXT, y VARCHAR(200000) se convierte a MEDIUMTEXT. Esto es
un comportamiento para compatibilidad.
Los tamaños de visualización de TIMESTAMP han sido descartados a partir de
MySQL 4.1, debido a las modificaciones hechas al tipo de columna
TIMESTAMP en esta versión. Antes de MySQL 4.1, los tamaños de
visualización de TIMESTAMP deben aparecer siempre, y estar en el rango desde
2 a 14. Si se especifica un tamaño de visualización de 0 ó mayor que 14, el
tamaño se ajusta a 14. Los valores impares en el rango entre 1 a 13 se ajustan al
siguiente valor par.
No se puede almacenar un valor literal NULL en una columna TIMESTAMP;
asignar el valor NULL equivale a asignar el valor de fecha y hora actual. Debido
a este comportamiento de las columnas TIMESTAMP, los atributos NULL y
NOT NULL no se aplican de la forma normal y se ignoran si se especifican.
DESCRIBE tbl_name siempre informa que a una columna TIMESTAMP se
puede le pueden asignar valores NULL.
Columns that are part of a PRIMARY KEY are made NOT NULL even if not
declared that way.
A partir de MySQL 3.23.51, los espacios inciciales son borrados
automáticamente de las valores de los miembros ENUM y SET cuando la tabla
es creada.
MySQL mapea ciertos tipos de columna usados por otros productos de bases de
datos SQL a los tipos de MySQL.
Si se incluye una clausula USING para especificar un tipo índice que no es legal
para un motor de almacenamiento, pero hay algún otro tipo de índice disponible
que el motor puede usar sin afectar a los resultados de la consulta, el motor usará
el tipo disponible.
Para comprobar si MySQL ha usado un tipo de columna diferente del especificado, se
puede usar una sentencia DESCRIBE o SHOW CREATE TABLE después de crear la
tabla o alterar una tabla.
Pueden producirse otros cambios de tipo de columna si se comprime una tabla usando
myisampack.
SHOW TABLES
SHOW [FULL|OPEN] TABLES [FROM nombre_db] [LIKE 'patrón']
SHOW TABLES lista las tablas no temporales en una base de datos dada. También se
puede obtener esta lista usando el comando mysqlshow db_name.
Antes de MySQL 5.0.1, la salida de SHOW TABLES contiene una única columna con
los nombres de las tablas. A partir de MySQL 5.0.1, también se listan las vistas de la
base de datos. A partir de MySQL 5.0.2, se soporta el modificador FULL de modo que
SHOW FULL TABLES muestra una segunda columna. Los valores de esta segunda
columna son BASE TABLE para una tabla y VIEW para una vista.
Nota: si no se dispone de privilegios para una tabla, la tabla no será mostrada en la
salida de SHOW TABLES o mysqlshow db_name.
SHOW OPEN TABLES lista las tablas que estén actualmente abiertas en la caché de
tablas. El campo de comentario en la salida indica las veces que la tabla está en el caché
y en uso. OPEN puede usarse a partir de MySQL 3.23.33.
Creación de tablas
El mandato para la creación de tablas o esquemas relacionales es CREATE TABLE.
Básicamente se debe definir los atributos que componen la tabla, la clave primaria, las
posibles claves ajenas y las restricciones a imponer sobre los valores de los atributos.
Cada definición se separa de la siguiente con una coma. La sintaxis general es la
siguiente:
CREATE TABLE nombre_tabla(
definición de atributo 1,
.....................
definición de atributo a,
definición de clave primaria,
definición de clave foránea 1,
.....................
definición de clave foránea f,
definición de restricción 1,
definición de restricción r);
El orden de realización de las definiciones es muy flexible, aunque es evidente que
antes de definir un atributo como formando parte de una clave primaria o ajena, o bien
definir una restricción sobre sus posibles valores, es necesario haber definido ese
atributo con anterioridad.
Una tabla recién creada no tiene contenido y por lo tanto su cardinalidad es cero.
Aunque esté vacía ocupa algún espacio en el espacio de tablas en el que se crea.
Las definiciones de las tablas que componen una base de datos se almacenan en un
lugar especial denominado "diccionario de datos" donde son accedidas por el SGBD
cuando es necesario.
Definición de atributos
Para definir un atributo se debe especificar su nombre, su tipo básico de datos y una
sencilla restricción opcional sobre sus posibles valores. El tipo de datos indica el
dominio general del atributo, que puede restringirse mediante la restricción opcional.
nombre_atributo tipo_atributo restricción_atributo
El tipo de datos del atributo especifica sus posibles valores válidos. Los tipos de datos
más habituales son NUMBER (número entero), DATE (fecha), CHAR (cadena de caracteres
de longitud fija) y VARCHAR2 (cadena de caracteres de longitud máxima fija y longitud
real variable).
Si no se especifica ninguna restricción sobre el atributo, entonces puede tomar cualquier
valor compatible con su tipo de datos, y el valor nulo (null). Las posibles restricciones
son:
PRIMARY
KEY
El atributo es clave primaria. Por tanto no acepta valores repetidos ni
nulos.
UNIQUE
El atributo no acepta valores repetidos, pero sí nulos.
NOT NULL
El atributo no acepta valores nulos, pero sí únicos.
CHECK
Restricción arbitraria.
Es frecuente combinar las restricciones UNIQUE y NOT NULL, por lo cual el atributo no
aceptaría valores repetidos ni nulos, siendo considerado una clave alternativa o
secundaria del modelo relacional.
Las restricciones arbitrarias se especifican mediante CHECK seguida de una condición
lógica entre paréntesis. En la condición pueden emplearse operadores lógicos
relacionales (menor, mayor, etc.), operadores lógicos booleanos (AND, OR, NOT) y otros,
como el de pertenencia a una lista de valores. La condición debe ser simple en el sentido
de que no debe involucrar a los valores de otros atributos, sino que únicamente debe
contemplarse el atributo en cuestión.
El SGBD debe comprobar automáticamente que se verifican las restricciones definidas
cuando se insertan nuevas filas en la tabla, se borran filas o se modifica el valor de un
atributo en una fila. Esta comprobación requiere un tiempo, por lo que el rendimiento de
las operaciones anteriores puede verse negativamente afectado si se definiera un gran
número de restricciones. En la sección sobre restricciones del documento SQL IV
(Aspectos adicionales) se trata con mayor detenimiento la definición de restricciones.
Definición de la clave primaria
Si la clave primaria se compone de un solo atributo (situación muy habitual) entonces
puede añadirse PRIMARY KEY al final de la definición del atributo primo. Para definir
una clave primaria en general se acompaña además de una lista de los atributos primos,
separados por comas.
PRIMARY KEY (atributo, ..., atributo)
Definición de claves ajenas
Una clave ajena, externa o foránea se define similarmente a la clave primaria, indicando
FOREIGN KEY seguida de la lista de atributos, separados por comas, que componen la
clave ajena, seguida a continuación de la palabra REFERENCES tras la cual se indica el
nombre de la table referenciada (la tabla de la cual los atributos anteriores son clave
primaria).
FOREIGN KEY (atributo, ..., atributo) REFERENCES nombre_tabla
Lógicamente para que la definición sea correcta los atributos que la componen deben
estar ya definidos y la tabla referenciada debe existir con anterioridad. Por tanto la
existencia de claves ajenas restringe el orden de creación de las tablas que componen la
base de datos, pues si una tabla B incluye una clave ajena de la tabla A, ésta debe
crearse primero.
Ejemplos
CREATE TABLE provincia(
codprov NUMBER(2) PRIMARY KEY,
nomprov CHAR(20) UNIQUE NOT NULL);
CREATE TABLE alumno(
num NUMBER(4),
nombre CHAR(10) NOT NULL,
apellidos CHAR(20) NOT NULL,
edad NUMBER(2) CHECK (edad>16),
codprov NUMBER(2),
nota NUMBER(4,2) CHECK (nota >=0 AND nota <= 10),
PRIMARY KEY (num),
FOREIGN KEY (codprov) REFERENCES provincia);
Borrado de tablas
El mandato para el borrado o eliminación de tablas es DROP TABLE.
DROP TABLE nombre_tabla;
Esta orden elimina la definición de la tabla en cuestión, que no existirá en lo sucesivo.
La situación es muy diferente a la de una tabla en la cual se borran todas sus filas,
utilizando para ello un mandado del lenguaje de manipulación de datos. En este caso la
tabla se queda vacía pero sigue existiendo.
Modificación de la estructura de las tablas
El mandato para modificar la definición de una tabla o esquema relacional es ALTER
TABLE. Lo más habitual es añadir atributos o columnas nuevos (ADD).
ALTER TABLE alumno ADD (tipo NUMBER(1) CHECK (tipo IN (0,1,2)));
http://www.cs.us.es/cursos/bd-2001/temas/sql_I.html
2.2.1
2.2.2
2.3
Integridad.
Integridad referencial declarativa.
Creación de índices
Creación de Índices
Si se utiliza el motor de datos Jet de Microsoft sólo se pueden crear índices en bases de
datos del mismo motor. La sintaxis para crear un índice en ua tabla ya definida en la
siguiente:
CREATE [ UNIQUE ] INDEX índice
ON Tabla (campo [ASC|DESC][, campo [ASC|DESC], ...])
[WITH { PRIMARY | DISALLOW NULL | IGNORE NULL }]
En donde:
índice
tabla
campo
ASC|DESC
UNIQUE
DISALLOW
NULL
IGNORE
NULL
PRIMARY
Es el nombre del índice a crear.
Es el nombre de una tabla existente en la que se creará el índice.
Es el nombre del campo o lista de campos que constituyen el índice.
Indica el orden de los valores de los campos ASC indica un orden
ascendente (valor predeterminado) y DESC un orden descendente.
Indica que el índice no puede contener valores duplicados.
Prohibe valores nulos en el índice
Excluye del índice los valores nulos incluidos en los campos que lo
componen.
Asigna al índice la categoría de clave principal, en cada tabla sólo puede
existir un único índice que sea "Clave Principal". Si un índice es clave
principal implica que no puede contener valores nulos ni duplicados.
En el caso de ACCESS, se puede utilizar CREATE INDEX para crear un pseudo
índice sobre una tabla adjunta en una fuente de datos ODBC tal como SQL Server que
no tenga todavía un índice. No necesita permiso o tener acceso a un servidor remoto
para crear un pseudo índice, además la base de datos remota no es consciente y no es
afectada por el pseudo índice. Se utiliza la misma sintaxis para las tablas adjuntas que
para las originales. Esto es especialmente útil para crear un índice en una tabla que sería
de sólo lectura debido a la falta de un índice.
CREATE INDEX
MiIndice
ON
Empleados (Prefijo, Telefono)
(Crea un índice llamado MiIndice en la tabla empleados con los campos Prefijo y
Teléfono.)
CREATE UNIQUE INDEX
MiIndice
ON
Empleados (IdEmpleado)
WITH DISALLOW NULL
(Crea un índice en la tabla Empleados utilizando el campo IdEmpleado, obligando que
el campo IdEmpleado no contenga valores nulos ni repetidos.)
http://www.mailxmail.com/curso/informatica/sql/capitulo37.htm
INDICES
definicion = lista de palabras clave seguidas de la localizacion de la información
asociada a esa palabra clave. Acelera las consultas.
- formato:
create index nom_indice
on nom_tabla (columnas [, columna(s)]
nombre del indice : nom_tabla_nom_columna(s)
Rowind:
Pseudocolumna que indica la localización física de una fila de la bd. El rowind
de una fila es único en toda la bd.
Físicamente son 16 bits y al final está el número de fichero de bd en la que está
guardado la fila.
Nº bloque en el fichero Nº fila dentro del bloque Nº fichero de la bd
Ejemplo : create index productos_denominacion
On productos (denominacion);
Cuando crear un indice:
- para tablas grandes (+ 100 filas)
- sobre columnas que aparezcan frecuentemente en clausulas where con una
igualdad. Cuando hay operaciones que se hacen muy frecuentemente.
- sobre columnasque relacionen tablas (foreign key).
- sobre columnas con gran variedad en sus datos.
Borrar indices:
Drop index nom_indice
http://kataix.umag.cl/~mmarin/bdr/sql/cap3.html
Índices
Los índices constituyen un mecanismo informático para acelerar el acceso a datos
almacenados en ficheros. Son importantes para posibilitar un procesamiento eficiente de
las operaciones sobre la base de datos y también para garantizar un cumplimiento
eficiente de las restricciones de integridad referencial. Los índices están asociados a
atributos concretos de una tabla (un solo atributo o la agregación de varios atributos) y
su función es agilizar las operaciones que se realicen sobre dichos atributos.
Físicamente adoptan la forma de un fichero adjunto a la tabla. Existen varios tipos de
índices y una gran variedad de técnicas de implementación, algunas de ellas muy
sofisticadas, pero siempre se persigue el objetivo general de evitar en lo posible el
acceso secuencial a las tuplas de una tabla para realizar una operación. Considérese por
ejemplo una selección en una tabla condicionada al valor de un determinado atributo:
SELECT * FROM tabla WHERE atributo=valor;
La obtención de las tuplas de salida requiere en principio realizar un recorrido
secuencial de todas las tuplas de la tabla para ver en cuáles se produce la igualdad. Si la
cardinalidad de la tabla es grande (muchas filas) este recorrido puede consumir mucho
tiempo. Por el contrario si se dispone de un índice asociado al correspondiente atributo
de la tabla entonces la consulta anterior es muy rápida y el acceso a las tuplas que
satisfacen la igualdad es inmediato gracias al acceso directo o indexado. El índice
también permite optimizar el acceso con condicionales de menor, mayor, etc.
Un índice está siempre asociado a un subconjunto de los atributos de una tabla. La
creación de índices se realiza mediante la sentencia CREATE INDEX de la siguiente
manera:
CREATE INDEX nombre_indice ON nombre_tabla(atributo1, atributo2, ...);
La eliminación o borrado de índices se realiza mediante la sentencia DROP INDEX de la
siguiente manera:
DROP INDEX nombre_indice;
Para una misma tabla pueden crearse varios índices y cada uno de ellos puede estar
asociado a un solo atributo o en general a la agregación de varios atributos (clave de
búsqueda). No es obligatoria la existencia de índices pero lo normal es crear
automáticamente por defecto un índice para la clave primaria de una tabla y las alternas
que pudieran existir (restricciones de tipo UNIQUE). No es obligatorio que los atributos
sobre los que se define un índice deban aceptar únicamente valores únicos o no
repetidos.
Los índices pueden crearse y borrarse dinámicamente en el tiempo según se necesiten
para realizar alguna consulta determinada. Se ha de tener muy presente que la creación
de un índice requiere de un cierto tiempo de computación y de cantidad de memoria de
almacenamiento secundario (disco). En general el efecto de un índice es escaso en
tablas con cardinalidad (número de filas) pequeña pero puede llegar a ser muy relevante
en tablas grandes.
Internamente los índices se implementan utilizando una potente estructura de datos
denominada árbol-B. Aunque no es lo corriente existen implementaciones en las cuales
las columnas indexadas se almacenan una sola vez, no en el fichero índice y en la tabla
aparte. Esto evidentemente reduce el tiempo de actualización del índice y requiere
menos espacio en disco.
La gestión de los índices se realiza de manera inteligente por el propio sistema. No es
necesario indicar explícitamente qué índices se van a utilizar para una consulta
determinada sino que es el propio SGBD, al analizar la condición de la consulta
(clausula WHERE) el que selecciona automáticamente el índice a usar.
Un índice asociado a un conjunto de atributos de una tabla debe actualizarse cada vez
que se realice alguna de las siguientes operaciones:
1. Inserción de una nueva tupla.
2. Borrado de una tupla.
3. Modificación del valor de alguno de los atributos indexados.
Esta actualización la realiza automáticamente el SGBD y requiere de un tiempo de
procesado usualmente pequeño dependiente del número de filas afectadas por la
operación. La conveniencia de utilizar un índice sobre unos atributos dependerá de la
frecuencia relativa con que se realicen operaciones de consulta sobre esos atributos. En
general durante la utilización práctica de una base de datos las operaciones de consulta
son con mucho las más frecuentes.
A modo de ejemplo veamos el caso de una operación de consulta en una tabla basada en
una comparación de igualdad de los valores de dos atributos a1 y a2, según se hayan
definido índices o no.
SELECT * FROM tabla WHERE a1=v1 AND a2=v2;
Índice
Procesamiento
Ninguno
Recorrido de todas las filas de la tabla comprobando la
condición compuesta.
Sobre a1
1. Usar el índice para obtener directamente todas las tuplas que
satisfagan la igualdad del atributo a1 con el valor v1.
2. Examinar secuencialmente todas esas tuplas comprobando la
igualdad del atributo a2 con el valor v2.
Sobre a2
1. Usar el índice para obtener directamente todas las tuplas que
satisfagan la igualdad del atributo a2 con el valor v2.
2. Examinar secuencialmente todas esas tuplas comprobando la
igualdad del atributo a1 con el valor v1.
Un índice sobre a1 y
otro sobre a2
1. Usar el índice sobre a1 para obtener todas las tuplas que
satisfagan la igualdad del atributo a1 con el valor v1.
2. Usar el índice sobre a2 para obtener todas las tuplas que
satisfagan la igualdad del atributo a2 con el valor v2.
3. La salida es la intersección de esos dos conjuntos de tuplas.
Índice múltiple:
Agregación de a1 y
Usar el índice para obtener directamente todas las tuplas que
verifican la condición compuesta de igualdad.
a2
En general, para una condición compuesta de este tipo el procesamiento más eficiente se
obtiene para un índice agregado de los dos atributos, aunque la eficiencia práctica
dependerá del número de tuplas que verifiquen las condiciones. Puede darse el caso de
que un índice múltiple que sea bastante bueno para realizar eficientemente consultas con
condiciones de igualdad no lo sea para comparaciones de menor o mayor.
http://www.cs.us.es/cursos/bd-2001/temas/sql_IV.html
Unidad 3. Consultas y Lenguaje de
Manipulación de Datos (DML)
3.1 Instrucciones INSERT, UPDATE, DELETE.
Consultas de Actualización
Las consultas de actualización son aquellas que no devuelven ningún registro,
son las encargadas de acciones como añadir y borrar y modificar registros.
5.1 DELETE
Crea una consulta de eliminación que elimina los registros de una o más de las
tablas listadas en la cláusula FROM que satisfagan la cláusula WHERE. Esta
consulta elimina los registros completos, no es posible eliminar el contenido de
algún campo en concreto. Su sintaxis es:
DELETE Tabla.* FROM Tabla WHERE criterio
DELETE es especialmente útil cuando se desea eliminar varios registros. En
una instrucción DELETE con múltiples tablas, debe incluir el nombre de tabla
(Tabla.*). Si especifica más de una tabla desde la que eliminar registros, todas
deben ser tablas de muchos a uno. Si desea eliminar todos los registros de una
tabla, eliminar la propia tabla es más eficiente que ejecutar una consulta de
borrado.
Se puede utilizar DELETE para eliminar registros de una única tabla o desde
varios lados de una relación uno a muchos. Las operaciones de eliminación en
cascada en una consulta únicamente eliminan desde varios lados de una
relación. Por ejemplo, en la relación entre las tablas Clientes y Pedidos, la tabla
Pedidos es la parte de muchos por lo que las operaciones en cascada solo
afectaran a la tabla Pedidos. Una consulta de borrado elimina los registros
completos, no únicamente los datos en campos específicos. Si desea eliminar
valores en un campo especificado, crear una consulta de actualización que
cambie los valores a Null.
Una vez que se han eliminado los registros utilizando una consulta de borrado,
no puede deshacer la operación. Si desea saber qué registros se eliminarán,
primero examine los resultados de una consulta de selección que utilice el
mismo criterio y después ejecute la consulta de borrado. Mantenga copias de
seguridad de sus datos en todo momento. Si elimina los registros equivocados
podrá recuperarlos desde las copias de seguridad.
DELETE * FROM Empleados WHERE Cargo = 'Vendedor';
5.2 INSERT INTO
Agrega un registro en una tabla. Se la conoce como una consulta de datos
añadidos. Esta consulta puede ser de dos tipos: Insertar un único registro ó
Insertar en una tabla los registros contenidos en otra tabla.
5.2.1 Para insertar un único Registro:
En este caso la sintaxis es la siguiente:
INSERT INTO Tabla (campo1, campo2, .., campoN)
VALUES (valor1, valor2, ..., valorN)
Esta consulta graba en el campo1 el valor1, en el campo2 y valor2 y así
sucesivamente. Hay que prestar especial atención a acotar entre comillas
simples (') los valores literales (cadenas de caracteres) y las fechas indicarlas
en formato mm-dd-aa y entre caracteres de almohadillas (#).
5.2.2 Para insertar Registros de otra Tabla:
En este caso la sintaxis es:
INSERT INTO Tabla [IN base_externa] (campo1, campo2, ..., campoN)
SELECT TablaOrigen.campo1, TablaOrigen.campo2, ...,
TablaOrigen.campoN
FROM TablaOrigen
En este caso se seleccionarán los campos 1,2, ..., n de la tabla origen y se
grabarán en los campos 1,2,.., n de la Tabla. La condición SELECT puede
incluir la cláusula WHERE para filtrar los registros a copiar. Si Tabla y
TablaOrigen poseen la misma estructura podemos simplificar la sintaxis a:
INSERT INTO Tabla SELECT TablaOrigen.* FROM TablaOrigen
De esta forma los campos de TablaOrigen se grabarán en Tabla, para realizar
esta operación es necesario que todos los campos de TablaOrigen estén
contenidos con igual nombre en Tabla. Con otras palabras que Tabla posea
todos los campos de TablaOrigen (igual nombre e igual tipo).
En este tipo de consulta hay que tener especial atención con los campos
contadores o autonuméricos puesto que al insertar un valor en un campo de
este tipo se escribe el valor que contenga su campo homólogo en la tabla
origen, no incrementándose como le corresponde.
Se puede utilizar la instrucción INSERT INTO para agregar un registro único a
una tabla, utilizando la sintaxis de la consulta de adición de registro único tal y
como se mostró anteriormente. En este caso, su código específica el nombre y
el valor de cada campo del registro. Debe especificar cada uno de los campos
del registro al que se le va a asignar un valor así como el valor para dicho
campo. Cuando no se especifica dicho campo, se inserta el valor
predeterminado o Null. Los registros se agregan al final de la tabla.
También se puede utilizar INSERT INTO para agregar un conjunto de registros
pertenecientes a otra tabla o consulta utilizando la cláusula SELECT ... FROM
como se mostró anteriormente en la sintaxis de la consulta de adición de
múltiples registros. En este caso la cláusula SELECT especifica los campos
que se van a agregar en la tabla destino especificada.
La tabla destino u origen puede especificar una tabla o una consulta.
Si la tabla destino contiene una clave principal, hay que asegurarse que es
única, y con valores no-Null ; si no es así, no se agregarán los registros. Si se
agregan registros a una tabla con un campo Contador, no se debe incluir el
campo Contador en la consulta. Se puede emplear la cláusula IN para agregar
registros a una tabla en otra base de datos.
Se pueden averiguar los registros que se agregarán en la consulta ejecutando
primero una consulta de selección que utilice el mismo criterio de selección y
ver el resultado. Una consulta de adición copia los registros de una o más
tablas en otra. Las tablas que contienen los registros que se van a agregar no
se verán afectadas por la consulta de adición. En lugar de agregar registros
existentes en otra tabla, se puede especificar los valores de cada campo en un
nuevo registro utilizando la cláusula VALUES. Si se omite la lista de campos, la
cláusula VALUES debe incluir un valor para cada campo de la tabla, de otra
forma fallará INSERT.
INSERT INTO Clientes SELECT Clientes_Viejos.* FROM
Clientes_Nuevos;
INSERT INTO Empleados (Nombre, Apellido, Cargo)
VALUES ('Luis', 'Sánchez', 'Becario');
INSERT INTO Empleados SELECT Vendedores.* FROM Vendedores
WHERE Fecha_Contratacion < Now() - 30;
5.3 UPDATE
Crea una consulta de actualización que cambia los valores de los campos de
una tabla especificada basándose en un criterio específico. Su sintaxis es:
UPDATE Tabla SET Campo1=Valor1, Campo2=Valor2, ... CampoN=ValorN
WHERE Criterio;
UPDATE es especialmente útil cuando se desea cambiar un gran número de
registros o cuando éstos se encuentran en múltiples tablas. Puede cambiar
varios campos a la vez. El ejemplo siguiente incrementa los valores Cantidad
pedidos en un 10 por ciento y los valores Transporte en un 3 por ciento para
aquellos que se hayan enviado al Reino Unido.:
UPDATE Pedidos SET Pedido = Pedidos * 1.1, Transporte = Transporte
* 1.03
WHERE PaisEnvío = 'ES';
UPDATE no genera ningún resultado. Para saber qué registros se van a
cambiar, hay que examinar primero el resultado de una consulta de selección
que utilice el mismo criterio y después ejecutar la consulta de actualización.
UPDATE Empleados SET Grado = 5 WHERE Grado = 2;
UPDATE Productos SET Precio = Precio * 1.1 WHERE Proveedor = 8 AND
Familia = 3;
Si en una consulta de actualización suprimimos la cláusula WHERE todos los
registros de la tabla señalada serán actualizados.
UPDATE Empleados SET Salario = Salario * 1.1
http://www.maestrosdelweb.com/editorial/tutsql5/
Sentencia INSERT
La sentencia de INSERT se utiliza para añadir registros a las tablas de la base
de datos. El formato de la sentencia es:
INSERT INTO nombre_tabla [(nombre_columna, ...)] VALUES (expr, ...)
nombre_tabla puede ser únicamente el nombre de la tabla.
nombre_columna es una lista opcional de nombres de campo en los que se
insertarán valores en el mismo número y orden que se especificarán en la
cláusula VALUES. Si no se especifica la lista de campos, los valores de expr en
la cláusula VALUES deben ser tantos como campos tenga la tabla y en el
mismo orden que se definieron al crear la tabla.
expr es una lista de expresiones o valores constantes, separados por comas,
para dar valor a los distintos campos del registro que se añadirá a la tabla. Las
cadenas de caracteres deberán estar encerradas entre comillas ‘.
Ejemplo para añadir un registro a una tabla:
INSERT INTO RUBROS (CLAVE, NOMBRE) VALUES 9, 'Otros');
Cada sentencia INSERT añade un único registro a la tabla. En el ejemplo solo
se han especificado 2 campos con sus respectivos valores, el resto de campos
quedaran a nulo. Un valor nulo NULL no significa blancos o ceros sino
simplemente que el campo nunca ha tenido un valor.
Sentencia UPDATE
La sentencia UPDATE se utiliza para cambiar el contenido de los registros de
una tabla de la base de datos. Su formato es:
UPDATE nombre_tabla SET nombre_columna = expr, ...
[WHERE { condición }]
nombre_tabla puede ser únicamente el nombre de la tabla.
nombre_columna es el nombre de columna o campo cuyo valor se desea
cambiar.
En una misma sentencia UPDATE pueden actualizarse varios campos de cada
registro de la tabla.
expr es el nuevo valor que se desea asignar al campo que le precede. La
expresión puede ser un valor constante o una subconsulta. Las cadenas de
caracteres deberán estar encerradas entre comillas ‘ . Las subconsultas entre
paréntesis.
La cláusula WHERE sigue el mismo formato que la vista en la sentencia
SELECT y determina que registros se modificarán.
Por ejemplo, cambiar los nombres de los de la tabla RUBROS de aquellos de
aquelos cuya clave sea mayor que 2, sería:
UPDATE RUBROS SET NOMBRE = 'Nuevo' WHERE CLAVE = 9,
Sentencia DELETE
La sentencia DELETE se utiliza para borrar registros de una tabla de la base de
datos. El formato de la sentencia es:
DELETE FROM nombre_tabla [WHERE { condición }]
nombre_tabla puede ser únicamente el nombre de la tabla.
La cláusula WHERE sigue el mismo formato que la vista en la sentencia
SELECT y determina que registros se borrarán.
Cada sentencia DELETE borra los registros que cumplen la condición impuesta
o todos si no se indica cláusula WHERE.
DELETE FROM RUBROS WHERE CLAVE = 9
Con el ejemplo anterior se borrarían todos los registros de la tabla rubros cuya
clave sea igual a 2.
http://www.lania.mx/biblioteca/seminarios/basedatos/sql.html#cgroupby
SQL, cuenta con módulos DDL, para la definición de datos que nos permite crear o modificar la
estructura de las tablas.
Las instrucciones para realizar estas operaciones son:
CREATE TABLE: Nos permite crear una tabla de datos vacía.
INSERT: Permite almacenar registros en una tabla creada.
UPDATE: Permite modificar datos de registros almacenados en la tabla.
DELETE: Borra un registro entero o grupo de registros de una tabla.
CREATE INDEX: Crea un índice que nos puede auxiliar para las consultas.
DROP TABLE: Permite borrar una tabla.
DROP INDEX: Borra el índice indicado.
Para ejemplificar las instrucciones anteriores consideremos el ejemplo
ALUMNO cursa
- MATERIA, que tienen los siguientes atributos:
NControl
NControl
Clave
NombreA
Clave
NombreM
Especialidad Calif
Creditos
Dirección
* Estructura de la sentencia CREATE TABLE.
CREATE TABLE <Nombre de la tabla>
(
Atributo1: tipo de dato longitud ,
Atributo2: tipo de dato longitud ,
Atributo3: tipo de dato longitud ,
:
:
Atributon: tipo de dato longitud ,
PRIMARY KEY (Opcional) ) ;
Los campos pueden definirse como NOT NULL de manera opcional excepto en la llave
primaria para lo cual es obligatorio. Además al definir la llave primaria se genera
automáticamente un índice con respecto al campo llave; para definir la llave la denotamos
dentro de los paréntesis de PRIMARY KEY.
Ejemplo:
Crear la tabla alumno con los atributos antes descritos, tomando como llave el numero de
control.
CREATE TABLE Alumno
(
NControl char(8) NOT NULL,
NombreA char(20),
Especialidad char(3),
Dirección char(30),
PRIMARY KEY (NControl) );
Tabla Alumno:
NControl NombreA Especialidad Dirección
Pueden existir más de una llave primaria, esto es si se requiere, se crearán tantos índices
como llaves primarias se establezcan.
Pueden existir tantos campos Not Null (No nulos) como se requieran; En si estructurar la
creación de una tabla es siempre parecida al ejemplo anterior.
* Estructura de la sentencia INSERT
INSERT
INTO Nombre de la tabla a la que se le va a insertar el registro
VALUES (Conjunto de valores del registro ) ;
Ejemplo:
Insertar en la tabla Alumno, antes creada los datos del alumno Daniel colín, con numero de
control 95310518 de la especialidad de Ingeniería civil, con domicilio Abasolo Norte #45.
INSERT
INTO Alumno
VALUES("95310518","Daniel Colín","IC","Abasolo Norte #45") ;
Nótese que la inserción de los datos se realiza conforme la estructura que se implanto en la
tabla, es decir en el orden en que se creo dicha tabla. En caso de querer omitir un dato que no
sean no nulos solamente se ponen las comillas indicando el vacío de la cadena.
* Estructura de la Sentencia CREATE INDEX
CREATE INDEX Nombre que se le asignara al índice.
ON Nombre de la taba a la cual se le creara el índice (Campo(s) por el cual se creara el
índice);
Ejemplo:
Crear un índice de la tabla Alumno por el campo Especialidad.
CREATE INDEX Indice1
ON Alumno(Especialidad);
Este índice contendrá a todos los alumnos ordenados por el campo especialidad.
CREATE INDEX UNIQUE INDEX Indice2
ON Alumno (Especialidad);
En la creación de este índice utilizamos la sentencia UNIQUE, es un indicador para permitir
que se cree un índice único por especialidad, esta sentencia siempre se coloca antes de
CREATE INDEX. En este ejemplo se creara un índice que contenga un alumno por
especialidad existente.
* Estructura de la sentencia UPDATE
UPDATE Nombre de la tabla en donde se modificaran los datos.
SET Valores
WHERE (Condición);
Ejemplo:
Modificar el número de control del registro de Daniel Colín de la Tabla alumno por el número
96310518.
UPDATE Alumno
SET NControl ‘96310518’
WHERE NombreA=’Daniel Colín’;
* Estructura de la sentencia DROP TABLE
DROP TABLE Nombre de la tabla a borrar ;
Ejemplo:
Borrar la tabla Alumno creada anteriormente.
DROP TABLE Alumno;
* Estructura de la sentencia DROP INDEX
DROP INDEX Nombre del índice a borrar;
Ejemplo:
Borrar el índice Indice1 creado anteriormente.
DROP INDEX Indice1;
* Estructura de la sentencia DELETE
DELETE
FROM Nombre de la tabla
WHERE Condición;
Ejemplos:
- Borrar el registro cuyo número de control es 95310386.
DELETE
FROM Alumno
WHERE Control=’95310386’;
- Borrar todos los registros de la tabla alumno.
DELETE
FROM Alumno;
En el primer ejemplo, se borrara todo el registro(todos los datos), del alumno con número de
control = 95310386.
En el segundo ejemplo se borraran todos los registros de la tabla alumno, pero sin borrar la
estructura de la tabla, ya que la orden Delete solo borra registros, la sentencia Drop Table es la
que borra toda la estructura de la tabla junto con los registros de la misma.
3.2
Consultas Básicas SELECT, WHERE y
funciones a nivel de registro.
La estructura básica de una expresión en SQL contiene 3 partes, Select, From y Where.
La cláusula Select se usa para listar los atributos que se desean en el resultado de una
consulta.
From, Lista las relaciones que se van a examinar en la evaluación de la expresión.
Where, es la definición de las condiciones a las que puede estar sujeta una consulta.
La consulta típica de SQL tiene la siguiente forma:
Select A1,A2,A3...An
From r1,r2,r3...rm
Where Condición(es)
Donde:
A1,A2,A3...An: Representan a cada atributo(s) o campos de las
tablas de la base de datos relacional.
R1,r2,r3...rm: Representan a la(s) tabla(s) involucradas en la consulta.
Condición: Es el enunciado que rige el resultado de la consulta.
Si se omite la cláusula Where, la condición es considerada como verdadera, la lista de
atributos (A1,A2..An) puede sustituirse por un asterisco (*), para seleccionar todos los atributos
de todas las tablas que aparecen en la cláusula From.
Funcionamiento del SQL.
El SQL forma el producto cartesiano de las tablas involucradas en la cláusula From,
cumpliendo con la condición establecida en la orden Where y después proyecta el resultado
con la orden select.
Para nuestros ejemplos consideremos una tabla llamada CURSO, que contiene los
siguientes campos:
Nombre del campo
NumC
NombreC
Descripción
Número del curso, único para identificar cada curso
Nombre del curso, también es único
DescC
Creditos
Descripción del curso
Créditos, número de estos que gana al estudiante al
cursarlo
Costo
Costo del curso.
Depto
Departamento académico que ofrece el curso.
Datos contenidos en la tabla CURSO
NumC
NombreC
DescC
Creditos
Costo
Depto
A01
Liderazgo
Para público
General
10
100.00
Admón.
S01
Introducción a la inteligencia artificial
Para ISC y LI
10
90.00
Sistemas.
C01
Construcción de torres
Para IC y
Arquitectura
8
0.00
Ciencias
B01
Situación actual y perspectivas de la
alimentación y la nutrición
Para IB
8
80.00
Bioquímica
E01
Historia presente y futuro de la energía solar
IE e II
10
100.00
Electromecánica.
S02
Tecnología OLAP
Para ISC y LI
8
100.00
Sistemas
C02
Tecnología del concreto y de las Estructuras
Para IC
10
100.00
Ciencias
B02
Metabolismo de lípidos en el camarón
Para IB
10
0.00
Bioquímica
E02
Los sistemas eléctricos de potencia
Para IE
10
100.00
Electromecánica
S03
Estructura de datos
Para ISC y LI
8
0.00
Sistemas
A01
Diseño bioclimático
Para
Arquitectura
10
0.00
Arquitectura
C03
Matemáticas discretas
General
8
0.00
Ciencias
S04
Circuitos digitales
Para ISC
10
0.00
Sistemas
S05
Arquitectura de Computadoras
Para ISC
10
50.00
Sistemas
I01
Base de Datos Relacionales
Para ISC y LI
10
150.00
Informática
Ejemplos de consultas:
OBTENCIÓN DE UNA TABLA ENTERA

Obtener toda la información disponible sobre un curso donde Costo sea 0.
SELECT *
FROM CURSO
WHERE Costo=0.00
Resultado de la consulta anterior.
NumC
NombreC
DescC
Creditos
Costo
Depto
C01
Construcción de torres
Para IC y
Arquitectura
8
0.00
Ciencias
B02
Metabolismo de lípidos en el camarón
Para IB
10
0.00
Bioquímica
S03
Estructura de datos
Para ISC y LI
8
0.00
Sistemas
A01
Diseño bioclimático
Para
Arquitectura
10
0.00
Arquitectura
C03
Matemáticas discretas
General
8
0.00
Ciencias
Colocamos un * debido a que no nos limitan la información de la tabla, es decir nos piden
que mostremos todos los datos atributo de la tabla CURSO.
Como la única condición en la sentencia WHERE es que la tarifa del curso sea igual a 0,
esta consulta regresa todas las tuplas donde se encuentre que Costo = 0.00.
Debido a que Costo es un campo numérico, la condición solo puede comparar con campos
del mismo tipo. Para representar valores negativos se antepone a la izquierda el signo (-), en
este ejemplo se considera solo el signo (=) para establecer la condición, sin embargo otros
operadores que se pueden utilizar son:
Menor que <
Mayor que >
Menor o igual que <=
Mayor o igual que >=
Diferente <>
Además de los operadores booleanos AND, NOT, OR.
Cabe señalar que en la sentencia Where cuando se requiere establecer condiciones con
cadenas, estas son delimitadas por apóstrofos (‘’). Las expresiones de cadenas son
comparadas carácter por carácter, dos cadenas son iguales solo si coinciden todos los
caracteres de las mismas.
Ejemplos de consultas con cadenas:

Obtener toda la información sobre cualquier curso que ofrezca el departamento de
Ciencias.
SELECT *
FROM CURSO
WHERE Depto = 'Ciencias';
Resultado de la consulta.
NumC
NombreC
DescC
Creditos
Costo
Depto
C01
Construcción de torres
Para IC y
Arquitectura
8
0.00
Ciencias
C02
Tecnología del concreto y de las
Para IC
10
100.00
Ciencias
Estructuras
S04
Circuitos digitales
Para ISC
10
0.00
Sistemas
VISUALIZACIÓN DE COLUMNAS ESPECIFICADAS.
En los ejemplos anteriores obteníamos toda la tabla completa, ahora veremos como mostrar
solo algunos atributos específicos de una tabla.

Obtener los valores NumC,NombreC y Depto, en este orden de toda la tabla curso.
SELECT NumC, NombreC, Depto
FROM CURSO;
Resultado de la consulta:
NumC
NombreC
Depto
A01
Liderazgo
Admón.
S01
Introducción a la inteligencia artificial
Sistemas.
C01
Construcción de torres
Ciencias
B01
Situación actual y perspectivas de la alimentación y la
nutrición
E01
Historia presente y futuro de la energía solar
S02
Tecnología OLAP
Sistemas
C02
Tecnología del concreto y de las Estructuras
Ciencias
B02
Metabolismo de lípidos en el camarón
E02
Los sistemas eléctricos de potencia
S03
Estructura de datos
Sistemas
A01
Diseño bioclimático
Arquitectura
C03
Matemáticas discretas
Ciencias
S04
Circuitos digitales
Sistemas
S05
Arquitectura de Computadoras
Sistemas
I01
Base de Datos Relacionales
Bioquímica
Electromecánica.
Bioquímica
Electromecánica
Informática
Observamos que en este caso no se tiene la sentencia Where, no existe condición, por lo
tanto, todas las filas de la tabla CURSO se recuperan, pero solo se visualizaran las tres
columnas especificadas.
Así mismo, empleamos la (,) para separar los campos que deseamos visualizar.
VISUALIZACIÓN DE UN SUBCONJUNTO DE FILAS Y COLUMNAS

Seleccionar los valores NumC, Depto y Costo para todos los cursos que tengan un
Costo inferior a $100
SELECT NumC, Depto, Costo
FROM CURSO
WHERE Costo < 100.00
Como resultado de esta consulta se obtendrán todas aquellas tuplas que tengan un costo en
CTARIFA menor que 100, y se visualizaran solo los campos de NumC, Depto,Costo.
Podemos observar que este ejemplo cubre el formato general de una consulta SQL.
La palabra clave DISTINCT
DISTINCT, es una palabra reservada que elimina las filas que duplicadas en el resultado de
una consulta.

Visualizar todos los departamentos académicos que ofrezcan cursos, rechazando los
valores duplicados.
SELECT DISTINCT Depto
FROM CURSO;
Resultado de la consulta
Depto
Administración
Sistemas
Ciencias
Bioquímica
electromecánica
Arquitectura
Informática
La palabra DISTINCT va estrictamente después de la palabra SELECT.
De no haberse utilizado la palabra DISTINCT, el resultado hubiera mostrado todas las tuplas
del atributo Depto que se encontraran, es decir, se hubiera visualizado la columna de Depto
completamente.
EMPLEO DE LOS CONECTORES BOOLEANOS (AND, OR, NOT)
Para emplear las condiciones múltiples dentro de la sentencia WHERE, utilizamos los
conectores lógicos.
El conector AND.
Este conector pide al sistema que seleccione una sola columna únicamente si ambas
condiciones se cumplen.

Obtener toda la información sobre todos los cursos que ofrece el departamento
Sistemas que tengan una tarifa igual a 0.
SELECT *
FROM CURSO
WHERE Depto=’Sistemas’ AND Costo=0.00;
El resultado de esta consulta sería todas aquellas tuplas que cumplan exactamente con las
dos condiciones establecidas.
El conector OR.
Este conector al igual que el AND permite conectar condiciones múltiples en la sentencia
WHERE, a diferencia del conector AND, el OR permite la selección de filas que cumplan con
una sola de las condiciones establecidas a través de este conector.

Obtener toda la información existente sobre cualquier curso ofrecido por los
departamentos Arquitectura o Bioquímica.
SELECT *
FROM CURSO
WHERE Depto = ‘Arquitectura’ OR Depto= ‘Bioquímica’;
El resultado de esta consulta será la de visualizar todas aquellas tuplas donde se cumpla
cualquiera de las 2 condiciones, es decir mostrara todas las tuplas que tengan en el atributo
Depto=Arquitectura o Bioquímica.
El conector NOT
Este nos permite marcar aquellas tuplas que por alguna razón no deseamos visualizar.

Obtener el nombre del curso y del departamento de todos los cursos que no sean
ofrecidos por el departamento Sistemas.
SELECT NombreC, Depto
FROM CURSO
WHERE NOT (Depto=’Sistemas’);
JERARQUIA DE OPERADORES BOOLEANOS.
En orden descendente (de mayor a menor prioridad)
NOT
AND
OR
Existen dos formas para realizar consultas: Join de Querys y Subquerys.
Cuando en la sentencia From colocamos los nombres de las tablas separados por comas se
dice que efectuamos una consulta de la forma Join de Querys, en este caso se requiere
anteponer el nombre de la tabla y un punto al nombre del atributo. En el Join de Querys el
resultado que se produce con las tablas que intervienen en la consulta es la concatenación de
las tablas, en donde los valores de una columna de la primera tabla coinciden con los valores
de una segunda tabla, la tabla de resultado tiene una fila por cada valor coincidente que resulte
de las dos tablas originales.
Para ejemplificar esto, consideremos 2 tablas: Tabla1 y Tabla2, entonces:
C1
C2
C3
CA
CB
A
AAA
10
35
R
B
BBB
45
10
S
C
CCC
55
65
T
D
DDD
20
20
U
E
EEE
20
90
V
F
FFF
90
90
W
G
GGG
15
75
X
H
HHH
90
90
Y
35
Z
Resultado de la operación Join:
C1
C2
C3
CA
CB
A
AAA
10
10
S
D
DDD
20
20
U
E
EEE
20
20
U
F
FFF
90
90
V
F
FFF
90
90
W
F
FFF
90
90
Y
H
HHH
90
90
V
H
HHH
90
90
W
H
HHH
90
90
Y
Como podemos observar, la comparación se efectuó por las columnas C3 y CA, que son
donde se encontraron valores iguales, el resultado muestra una tupla por cada coincidencia
encontrada.
Cuando las consultas se anidan se conoce como Subquerys o subconsultas. Este tipo de
consulta obtiene resultados parciales reduciendo el espacio requerido para realizar una
consulta.
Nota: Todas las consultas que se resuelven con subquerys pueden resolverse con Join de
Querys, pero no todas las consultas hechas con Join de Querys pueden resolverse utilizando
Subquerys.
Para ejemplificar lo anterior consideremos el ejemplo
ALUMNO cursa
NControl
NControl
NombreA
Clave
Especialidad Calif
Dirección
- MATERIA, que tienen los siguientes atributos:
Clave
NombreM
Creditos
Representando en tablas a los atributos quedarían de la siguiente forma:
Tabla alumno:
NControl NombreA Especialidad Dirección
Tabla cursa:
NControl Clave
Calif
Tabla materia:
Clave NombreM Creditos

Obtener el nombre de la materia que cursa el alumno con número de control 97310211
con créditos igual a ocho.
SELECT NombreA
FROM Materia
WHERE creditos=’8’ and clave in(SELECT clave
FROM cursa
WHERE NControl=’97310211’;

Obtener el número de control del alumno que tenga alguna calificación igual a 100
SELECT DISTINC(NControl)
FROM Cursa
WHERE Calif=’100’;

Obtener el nombre de las materias que cursa el alumno Salvador Chávez.
SELECT NombreM
FROM Materia
WHERE Clave in (SELECT DISTINC (Clave)
FROM Cursa
WHERE NControl in (SELECT NControl)
FROM Alumno
WHERE NombreA=’Salvador
Chávez’));
FUNCIONES AVANZADAS APLICABLES A CONSULTAS
Existen funciones que permiten la agilización de consultas similares a una hoja de cálculo,
ya que trabajan en base a renglones y columnas.
COUNT ( ): Cuenta el número de tuplas en la columna establecida
MIN ( ): Localiza el valor mínimo de la columna establecida
MAX ( ): Localiza el valor máximo de la columna establecida.
AVG ( ): Obtiene el promedio de valores de la columna establecida
SUM ( ): Obtiene el valor total que implican los valores obtenidos en la columna establecida.
Ejemplos:

Obtener el número de alumnos que existen en la carrera de Ingeniería en Sistemas
Computacionales.
SELECT Count (*)
FROM Alumno
WHERE especialidad=’ISC’;

Obtener la máximo calificación que ha obtenido J.M. Cadena.
SELECT Max(Calif)
FROM Cursa
WHERE NControl IN (SELECT NControl
FROM Alumno
WHERE NombreA= ‘J.M. Cadena ’);

Obtener el promedio de calificaciones de Salvador Chávez.
SELECT Avg (Calif)
FROM Cursa
WHERE NCotrol IN (SELECT NControl
FROM Alumno
WHERE NombreA=’Salvador Chávez’);

Obtener la suma total de las calificaciones obtenidas por Daniel Colín.
SELECT Sum (Calif)
FROM Cursa
WHERE NControl IN (SELECT NControl
FROM Alumno
WHERE NombreA=’Daniel Colín’);
Hasta aquí hemos visto el manejo sencillo de realizar consultas con SQL, hay que destacar
que en la realización de consultas anidadas se tiene que poner cuidando a la prioridad de los
operadores, teniendo cuidado también al momento de agrupar los paréntesis que involucran las
condiciones con los operadores.
La estructura básica de una expresión para consulta SQL consta de tres cláusulas:



SELECT
FROM
WHERE
La cláusula SELECT se usa para listar los atributos que se desean en el resultado de una
consulta.
La cláusula FROM lista las relaciones que se van a examinar en la evaluación de la expresión
La cláusula WHERE costa de un predicado que implica atributos de las relaciones que
aparecen en la cláusula FROM.
Una consulta básica en SQL tiene la forma:
SELECT A1,A2,...,An
FROM r1,r2,...,rn
WHERE P
Donde Ai = atributo ( Campo de la tabla )
ri = relación ( Tabla )
P = predicado ( condición )
Ejemplo 2.1 : Seleccionar todos los nombres de las personas que tengan el apellido
MARQUESI de la tabla persona
SELECT nombre
FROM persona
WHERE apellido = " MARQUESI"
ANSWER
NOMBRE
1
MARTIN
2
PABLO
El resultado de una consulta es por supuesto otra relación. Si se omite la cláusula WHERE, el
predicado P es verdadero. La lista A1, A2,..., An puede sustituirse por un asterisco (*) para
seleccionar todos los atributos de todas las relaciones que aparecen en la cláusula FROM,
aunque no es conveniente elegir esta ultima opción salvo que sea necesario pues
desperdiciamos mucho tiempo en obtenerlo
Alias
Es posible renombrar los atributos y las relaciones, a veces por conveniencia y otras veces por
ser necesario, para esto usamos la clausula AS como en el siguiente ejemplo.
Ejemplo 2.2
SELECT P.nombre AS [PRIMER NOMBRE]
FROM persona P
WHERE apellido = "MARQUESI"
ANSWER
PRIMER NOMBRE
1
MARTIN
2
PABLO
En este ejemplo cabe destacar un par de cosas. Cuando nos referimos a un atributo como es el
caso de nombre, podemos referirnos a este usando la relación ( o el alias en este ejemplo ) a la
que pertenece el atributo seguido de un punto seguido del atributo <P.nombre>, a veces esta
notación será necesaria para eliminar ambigüedades. Los corchetes los usamos cuando
usamos espacios en blancos o el caratér (–) en el nombre de atributo o alias.
Usar alias en los atributos nos permite cambiar el nombre de los atributos de la respuesta a la
consulta.
Cuando asociamos un alias con una relación decimos que creamos una variable de tupla.
Estas variables de tuplas se definen en la cláusula FROM después del nombre de la relación.
En las consultas que contienen subconsultas, se aplica una regla de ámbito a las variables de
tupla. En una subconsulta esta permitido usar solo variables de tupla definidas en la misma
subconsulta o en cualquier consulta que tenga la subconsulta.
http://www.monografias.com/trabajos11/prosq/prosq.shtml#es
Consultas de Selección
Las consultas de selección se utilizan para indicar al motor de datos que
devuelva información de las bases de datos, esta información es devuelta en
forma de conjunto de registros que se pueden almacenar en un objeto
recordset. Este conjunto de registros es modificable.
2.1 Consultas básicas
La sintaxis básica de una consulta de selección es la siguiente:
SELECT Campos FROM Tabla;
En donde campos es la lista de campos que se deseen recuperar y tabla es el
origen de los mismos, por ejemplo:
SELECT Nombre, Telefono FROM Clientes;
Esta consulta devuelve un recordset con el campo nombre y teléfono de la
tabla clientes.
2.2 Ordenar los registros
Adicionalmente se puede especificar el orden en que se desean recuperar los
registros de las tablas mediante la claúsula ORDER BY Lista de Campos. En
donde Lista de campos representa los campos a ordenar. Ejemplo:
SELECT CodigoPostal, Nombre, Telefono FROM Clientes ORDER BY
Nombre;
Esta consulta devuelve los campos CodigoPostal, Nombre, Telefono de la tabla
Clientes ordenados por el campo Nombre.
Se pueden ordenar los registros por mas de un campo, como por ejemplo:
SELECT CodigoPostal, Nombre, Telefono FROM Clientes ORDER BY
CodigoPostal, Nombre;
Incluso se puede especificar el orden de los registros: ascendente mediante la
claúsula (ASC -se toma este valor por defecto) ó descendente (DESC)
SELECT CodigoPostal, Nombre, Telefono FROM Clientes ORDER BY
CodigoPostal DESC , Nombre ASC;
2.3 Consultas con Predicado
El predicado se incluye entre la claúsula y el primer nombre del campo a
recuperar, los posibles predicados son:
Predicado
Descripción
ALL
Devuelve todos los campos de la tabla
Devuelve un determinado número de registros de la
TOP
tabla
Omite los registros cuyos campos seleccionados
DISTINCT
coincidan totalmente
Omite los registros duplicados basandose en la
DISTINCROW totalidad del registro y no sólo en los campos
seleccionados.
ALL:
Si no se incluye ninguno de los predicados se asume ALL. El Motor de base de
datos selecciona todos los registros que cumplen las condiciones de la
instrucción SQL. No se conveniente abusar de este predicado ya que
obligamos al motor de la base de datos a analizar la estructura de la tabla para
averiguar los campos que contiene, es mucho más rápido indicar el listado de
campos deseados.
SELECT ALL FROM Empleados;
SELECT * FROM Empleados;
TOP:
Devuelve un cierto número de registros que entran entre al principio o al final
de un rango especificado por una cláusula ORDER BY. Supongamos que
queremos recuperar los nombres de los 25 primeros estudiantes del curso
1994:
SELECT TOP 25 Nombre, Apellido FROM Estudiantes
ORDER BY Nota DESC;
Si no se incluye la cláusula ORDER BY, la consulta devolverá un conjunto
arbitrario de 25 registros de la tabla Estudiantes .El predicado TOP no elige
entre valores iguales. En el ejemplo anterior, si la nota media número 25 y la 26
son iguales, la consulta devolverá 26 registros. Se puede utilizar la palabra
reservada PERCENT para devolver un cierto porcentaje de registros que caen
al principio o al final de un rango especificado por la cláusula ORDER BY.
Supongamos que en lugar de los 25 primeros estudiantes deseamos el 10 por
ciento del curso:
SELECT TOP 10 PERCENT Nombre, Apellido FROM Estudiantes
ORDER BY Nota DESC;
El valor que va a continuación de TOP debe ser un Integer sin signo.TOP no
afecta a la posible actualización de la consulta.
DISTINCT:
Omite los registros que contienen datos duplicados en los campos
seleccionados. Para que los valores de cada campo listado en la instrucción
SELECT se incluyan en la consulta deben ser únicos.
Por ejemplo, varios empleados listados en la tabla Empleados pueden tener el
mismo apellido. Si dos registros contienen López en el campo Apellido, la
siguiente instrucción SQL devuelve un único registro:
SELECT DISTINCT Apellido FROM Empleados;
Con otras palabras el predicado DISTINCT devuelve aquellos registros cuyos
campos indicados en la cláusula SELECT posean un contenido diferente. El
resultado de una consulta que utiliza DISTINCT no es actualizable y no refleja
los cambios subsiguientes realizados por otros usuarios.
DISTINCTROW:
Devuelve los registros diferentes de una tabla; a diferencia del predicado
anterior que sólo se fijaba en el contenido de los campos seleccionados, éste lo
hace en el contenido del registro completo independientemente de los campo
indicados en la cláusula SELECT.
SELECT DISTINCTROW Apellido FROM Empleados;
Si la tabla empleados contiene dos registros: Antonio López y Marta López el
ejemplo del predicado DISTINCT devuleve un único registro con el valor López
en el campo Apellido ya que busca no duplicados en dicho campo. Este último
ejemplo devuelve dos registros con el valor López en el apellido ya que se
buscan no duplicados en el registro completo.
2.4 Alias
En determinadas circunstancias es necesario asignar un nombre a alguna
columna determinada de un conjunto devuelto, otras veces por simple capricho
o por otras circunstancias. Para resolver todas ellas tenemos la palabra
reservada AS que se encarga de asignar el nombre que deseamos a la
columna deseada. Tomado como referencia el ejemplo anterior podemos hacer
que la columna devuelta por la consulta, en lugar de llamarse apellido (igual
que el campo devuelto) se llame Empleado. En este caso procederíamos de la
siguiente forma:
SELECT DISTINCTROW Apellido AS Empleado FROM Empleados;
2.5 Recuperar Información de una base de Datos Externa
Para concluir este capítulo se debe hacer referencia a la recuperación de
registros de bases de datos externa. Es ocasiones es necesario la
recuperación de información que se encuentra contenida en una tabla que no
se encuentra en la base de datos que ejecutará la consulta o que en ese
momento no se encuentra abierta, esta situación la podemos salvar con la
palabra reservada IN de la siguiente forma:
SELECT DISTINCTROW Apellido AS Empleado FROM Empleados
IN 'c:\databases\gestion.mdb';
En donde c:\databases\gestion.mdb es la base de datos que contiene la tabla
Empleados.
http://www.maestrosdelweb.com/editorial/tutsql3/
3. Criterios de Selección
En el capítulo anterior se vio la forma de recuperar los registros de las tablas,
las formas empleadas devolvían todos los registros de la mencionada tabla. A
lo largo de este capítulo se estudiarán las posibilidades de filtrar los registros
con el fin de recuperar solamente aquellos que cumplan unas condiciones
preestablecidas.
Antes de comenzar el desarrollo de este capítulo hay que recalcar tres detalles
de vital importancia. El primero de ellos es que cada vez que se desee
establecer una condición referida a un campo de texto la condición de
búsqueda debe ir encerrada entre comillas simples; la segunda es que no se
posible establecer condiciones de búsqueda en los campos memo y; la tercera
y última hace referencia a las fechas. Las fechas se deben escribir siempre en
formato mm-dd-aa en donde mm representa el mes, dd el día y aa el año, hay
que prestar atención a los separadores -no sirve la separación habitual de la
barra (/), hay que utilizar el guión (-) y además la fecha debe ir encerrada entre
almohadillas (#). Por ejemplo si deseamos referirnos al día 3 de Septiembre de
1995 deberemos hacerlo de la siguiente forma; #09-03-95# ó #9-3-95#.
3.1 Operadores Lógicos
Los operadores lógicos soportados por SQL son: AND, OR, XOR, Eqv, Imp, Is
y Not. A excepción de los dos últimos todos poseen la siguiente sintaxis:
<expresión1> operador <expresión2>
En donde expresión1 y expresión2 son las condiciones a evaluar, el resultado
de la operación varía en función del operador lógico. La tabla adjunta muestra
los diferentes posibles resultados:
<expresión1>
Verdad
Verdad
Falso
Falso
Operador
AND
AND
AND
AND
<expresión2>
Falso
Verdad
Verdad
Falso
Resultado
Falso
Verdad
Falso
Falso
Verdad
Verdad
Falso
Falso
Verdad
Verdad
Falso
Falso
Verdad
Verdad
Falso
Falso
Verdad
Verdad
Verdad
Falso
Falso
Falso
Null
Null
Null
OR
OR
OR
OR
XOR
XOR
XOR
XOR
Eqv
Eqv
Eqv
Eqv
Imp
Imp
Imp
Imp
Imp
Imp
Imp
Imp
Imp
Falso
Verdad
Verdad
Falso
Verdad
Falso
Verdad
Falso
Verdad
Falso
Verdad
Falso
Verdad
Falso
Null
Verdad
Falso
Null
Verdad
Falso
Null
Verdad
Verdad
Verdad
Falso
Falso
Verdad
Verdad
Falso
Verdad
Falso
Falso
Verdad
Verdad
Falso
Null
Verdad
Verdad
Verdad
Verdad
Null
Null
Si a cualquiera de las anteriores condiciones le anteponemos el operador NOT
el resultado de la operación será el contrario al devuelto sin el operador NOT.
El último operador denominado Is se emplea para comparar dos variables de
tipo objeto <Objeto1> Is <Objeto2>. Este operador devuelve verdad si los dos
objetos son iguales.
SELECT * FROM Empleados WHERE Edad > 25 AND Edad < 50;
SELECT * FROM Empleados WHERE (Edad > 25 AND Edad < 50) OR Sueldo
= 100;
SELECT * FROM Empleados WHERE NOT Estado = 'Soltero';
SELECT * FROM Empleados WHERE (Sueldo > 100 AND Sueldo < 500) OR
(Provincia = 'Madrid' AND Estado = 'Casado');
3.2 Intervalos de Valores
Para indicar que deseamos recuperar los registros según el intervalo de valores
de un campo emplearemos el operador Between cuya sintaxis es:
(campo [Not] Between valor1 And valor2 (la condición Not es opcional)
En este caso la consulta devolvería los registros que contengan en "campo"
un valor incluido en el intervalo valor1, valor2 (ambos inclusive). Si
anteponemos la condición Not devolverá aquellos valores no incluidos en el
intervalo.
SELECT * FROM Pedidos WHERE CodPostal Between 28000 And 28999;
(Devuelve los pedidos realizados en la provincia de Madrid)
SELECT IIf(CodPostal Between 28000 And 28999, 'Provincial',
'Nacional')
FROM Editores;
(Devuelve el valor 'Provincial' si el código postal se encuentra
en el intervalo,
'Nacional' en caso contrario)
3.3 El Operador Like
Se utiliza para comparar una expresión de cadena con un modelo en una
expresión SQL. Su sintaxis es:
expresión Like modelo
En donde expresión es una cadena modelo o campo contra el que se compara
expresión. Se puede utilizar el operador Like para encontrar valores en los
campos que coincidan con el modelo especificado. Por modelo puede
especificar un valor completo (Ana María), o se pueden utilizar caracteres
comodín como los reconocidos por el sistema operativo para encontrar un
rango de valores (Like An*).
El operador Like se puede utilizar en una expresión para comparar un valor de
un campo con una expresión de cadena. Por ejemplo, si introduce Like C* en
una consulta SQL, la consulta devuelve todos los valores de campo que
comiencen por la letra C. En una consulta con parámetros, puede hacer que el
usuario escriba el modelo que se va a utilizar.
El ejemplo siguiente devuelve los datos que comienzan con la letra P seguido
de cualquier letra entre A y F y de tres dígitos:
Like 'P[A-F]###'
Este ejemplo devuelve los campos cuyo contenido empiece con una letra de la
A a la D seguidas de cualquier cadena.
Like '[A-D]*'
En la tabla siguiente se muestra cómo utilizar el operador Like para comprobar
expresiones con diferentes modelos.
Tipo de coincidencia
Varios caracteres
Carácter especial
Varios caracteres
Un solo carácter
Un solo dígito
Modelo Planteado
'a*a'
'a[*]a'
'ab*'
'a?a'
'a#a'
Coincide
'aa', 'aBa', 'aBBBa'
'a*a'
'abcdefg', 'abc'
'aaa', 'a3a', 'aBa'
'a0a', 'a1a', 'a2a'
No Coincide
'aBC'
'aaa'
'cab', 'aab'
'aBBBa'
'aaa', 'a10a'
Rango de caracteres
Fuera de un rango
Distinto de un dígito
Combinada
'[a-z]'
'[!a-z]'
'[!0-9]'
'a[!b-m]#'
'f', 'p', 'j'
'9', '&', '%'
'A', 'a', '&', '~'
'An9', 'az0', 'a99'
'2', '&'
'b', 'a'
'0', '1', '9'
'abc', 'aj0'
3.4 El Operador In
Este operador devuelve aquellos registros cuyo campo indicado coincide con
alguno de los indicados en una lista. Su sintaxis es:
expresión [Not] In(valor1, valor2, . . .)
SELECT * FROM Pedidos WHERE Provincia In ('Madrid', 'Barcelona',
'Sevilla');
3.5 La cláusula WHERE
La cláusula WHERE puede usarse para determinar qué registros de las tablas
enumeradas en la cláusula FROM aparecerán en los resultados de la
instrucción SELECT. Después de escribir esta cláusula se deben especificar
las condiciones expuestas en los apartados 3.1 y 3.2. Si no se emplea esta
cláusula, la consulta devolverá todas las filas de la tabla. WHERE es opcional,
pero cuando aparece debe ir a continuación de FROM.
SELECT Apellidos, Salario FROM Empleados WHERE Salario > 21000;
SELECT Id_Producto, Existencias FROM Productos
WHERE Existencias <= Nuevo_Pedido;
SELECT * FROM Pedidos WHERE Fecha_Envio = #5/10/94#;
SELECT Apellidos, Nombre FROM Empleados WHERE Apellidos = 'King';
SELECT Apellidos, Nombre FROM Empleados WHERE Apellidos Like 'S*';
SELECT Apellidos, Salario FROM Empleados WHERE Salario Between 200
And 300;
SELECT Apellidos, Salario FROM Empl WHERE Apellidos Between 'Lon'
And 'Tol';
SELECT Id_Pedido, Fecha_Pedido FROM Pedidos WHERE Fecha_Pedido
Between #1-1-94# And #30-6-94#;
SELECT Apellidos, Nombre, Ciudad FROM Empleados WHERE Ciudad
In ('Sevilla', 'Los Angeles', 'Barcelona');
http://www.maestrosdelweb.com/editorial/tutsql3/
3.3
Consultas sobre múltiples tablas.
3.3.1
Subconsultas.
SubConsultas
Una subconsulta es una instrucción SELECT anidada dentro de una instrucción
SELECT, SELECT...INTO, INSERT...INTO, DELETE, o UPDATE o dentro de otra
subconsulta.
Puede utilizar tres formas de sintaxis para crear una subconsulta:
comparación [ANY | ALL | SOME] (instrucción sql)
expresión [NOT] IN (instrucción sql)
[NOT] EXISTS (instrucción sql)
En donde:
comparación: Es una expresión y un operador de comparación que compara la
expresión con el resultado de la subconsulta.
expresión: Es una expresión por la que se busca el conjunto resultante de la
subconsulta.
instrucción sql : Es una instrucción SELECT, que sigue el mismo formato y reglas
que cualquier otra instrucción SELECT. Debe ir entre paréntesis.
Se puede utilizar una subconsulta en lugar de una expresión en la lista de campos de
una instrucción SELECT o en una cláusula WHERE o HAVING. En una subconsulta,
se utiliza una instrucción SELECT para proporcionar un conjunto de uno o más valores
especificados para evaluar en la expresión de la cláusula WHERE o HAVING.
Se puede utilizar el predicado ANY o SOME, los cuales son sinónimos, para recuperar
registros de la consulta principal, que satisfagan la comparación con cualquier otro
registro recuperado en la subconsulta. El ejemplo siguiente devuelve todos los
productos cuyo precio unitario es mayor que el de cualquier producto vendido con un
descuento igual o mayor al 25 por ciento.:
SELECT * FROM Productos WHERE PrecioUnidad > ANY
(SELECT PrecioUnidad FROM DetallePedido WHERE Descuento >= 0 .25);
El predicado ALL se utiliza para recuperar únicamente aquellos registros de la
consulta principal que satisfacen la comparación con todos los registros recuperados
en la subconsulta. Si se cambia ANY por ALL en el ejemplo anterior, la consulta
devolverá únicamente aquellos productos cuyo precio unitario sea mayor que el de
todos los productos vendidos con un descuento igual o mayor al 25 por ciento. Esto es
mucho más restrictivo.
El predicado IN se emplea para recuperar únicamente aquellos registros de la consulta
principal para los que algunos registros de la subconsulta contienen un valor igual. El
ejemplo siguiente devuelve todos los productos vendidos con un descuento igual o
mayor al 25 por ciento.:
SELECT * FROM Productos WHERE IDProducto IN
(SELECT IDProducto FROM DetallePedido WHERE Descuento >= 0.25);
Inversamente se puede utilizar NOT IN para recuperar únicamente aquellos registros
de la consulta principal para los que no hay ningún registro de la subconsulta que
contenga un valor igual. El predicado EXISTS (con la palabra reservada NOT opcional)
se utiliza en comparaciones de verdad/falso para determinar si la subconsulta
devuelve algún registro.
Se puede utilizar también alias del nombre de la tabla en una subconsulta para
referirse a tablas listadas en la cláusula FROM fuera de la subconsulta. El ejemplo
siguiente devuelve los nombres de los empleados cuyo salario es igual o mayor que el
salario medio de todos los empleados con el mismo título. A la tabla Empleados se le
ha dado el alias T1::
SELECT Apellido, Nombre, Titulo, Salario FROM Empleados AS T1
WHERE Salario >= (SELECT Avg(Salario) FROM Empleados
WHERE T1.Titulo = Empleados.Titulo) ORDER BY Titulo;
En el ejemplo anterior , la palabra reservada AS es opcional.
SELECT Apellidos, Nombre, Cargo, Salario FROM Empleados
WHERE Cargo LIKE "Agente Ven*" AND Salario > ALL (SELECT Salario FROM
Empleados WHERE (Cargo LIKE "*Jefe*") OR (Cargo LIKE "*Director*"));
Obtiene una lista con el nombre, cargo y salario de todos los agentes de ventas cuyo
salario es mayor que el de todos los jefes y directores.
SELECT DISTINCTROW NombreProducto, Precio_Unidad FROM Productos
WHERE (Precio_Unidad = (SELECT Precio_Unidad FROM Productos WHERE
Nombre_Producto = "Almíbar anisado");
Obtiene una lista con el nombre y el precio unitario de todos los productos con el
mismo precio que el almíbar anisado.
SELECT DISTINCTROW Nombre_Contacto, Nombre_Compañia, Cargo_Contacto,
Telefono FROM Clientes WHERE (ID_Cliente IN (SELECT DISTINCTROW
ID_Cliente FROM Pedidos WHERE Fecha_Pedido >= #04/1/93# <#07/1/93#);
Obtiene una lista de las compañías y los contactos de todos los clientes que han
realizado un pedido en el segundo trimestre de 1993.
SELECT Nombre, Apellidos FROM Empleados AS E WHERE EXISTS
(SELECT * FROM Pedidos AS O WHERE O.ID_Empleado = E.ID_Empleado);
Selecciona el nombre de todos los empleados que han reservado al menos un pedido.
SELECT DISTINCTROW Pedidos.Id_Producto, Pedidos.Cantidad,
(SELECT DISTINCTROW Productos.Nombre FROM Productos WHERE
Productos.Id_Producto = Pedidos.Id_Producto) AS ElProducto FROM
Pedidos WHERE Pedidos.Cantidad > 150 ORDER BY Pedidos.Id_Producto;
Recupera el Código del Producto y la Cantidad pedida de la tabla pedidos, extrayendo
el nombre del producto de la tabla de productos.
http://www.maestrosdelweb.com/editorial/tutsql7/
3.3.2
Operadores JOIN.
1. Para las siguientes relaciones
computar
1.
2.
3.
4.
5.
6.
7.
Operadores Join-Like
Existen varios operadores del estilo del join que son provistos por bases de datos comerciales.
o
El semijoin de las relaciones y
tal que hay al menos una tupla en
atributos comunes de y .
o
El antisemijoin
, es la bolsa de tuplas en que no concuerdan
con ninguna tupla de en los atributos
.
El outerjoin
se forma con
más el agregado de las dangling
tuples de o , donde una tupla está colgando si esta no se junta con
ninguna de la otra relación. Las tuplas agregadas se rellenan con el
símbolo de indefinido o nulo , en aquellos atributos que la tupla
colgante no posee pero que si aparecen en la relación resultante.
o
, es el multiconjunto de tuplas
que concuerda con en todos los
o
El leftouterjoin
es como el outerjoin, pero solo las tuplas
colgantes de son rellenadas con y agregadas al resultado.
o
El rightouterjoin
también es como el outerjoin, pero esta vez el
argumento que genera las dangling tuples es el derecho.
2. Dar expresiones para los cinco operadores definidos en el párrafo anterior
usando solamente los operadores standard del álgebra relacional. Para las
variantes ``outerjoin'' puede usar una relación nula
de una única tupla con en cada componente.
3. Un operador unario
es idempotente si,
que consiste
. Para cada uno de los
operadores
, explique por que son idempotentes o muestre un
contraejemplo.
4. Cuando es posible empujar una selección en los dos argumentos de un operador
binario, es necesario decidir si hacerlo o no. ¿Cómo afectaría la existencia de
índices en uno de los argumentos?. Considere, por ejemplo, una expresión
, donde se tiene un índice sobre .
5. Dar ejemplos donde se muestre que la eliminación de duplicados no puede ser
empujada por debajo de la unión o diferencia de multiconjuntos.
6. Los operadores similares al join del ejercicio 2 obedecen algunas reglas
comunes y otras no. Para cada caso pruebe o de un contraejemplo para las
siguientes leyes.
o
o
o
o
7. Reemplace los join naturales en las expresiones siguientes por theta-joins y
proyecciones. Diga cuando los theta-join resultantes forman un grupo asociativo
y conmutativo.
0.
1.
2.
8. Dar reglas para convertir cada una de las siguientes formas de condición en
álgebra relacional. Asuma que las condiciones se aplican a una relación
y
no están correlacionadas a ella. Tenga especial cuidado para no introducir o
eliminar duplicados respecto a la definicion formal de SQL.
o
o
, donde
es un atributo de
o
, donde
es un atributo de
9. Transforme la siguiente query en un plan lógico y trate de mejorarlo aplicando
leyes algebraicas.
10.
11.
12.
13.
SELECT starName
FROM Actor1996
WHERE studioName="Paramount";
donde hay dos vistas definidas
CREATE VIEW Actor1996 AS
SELECT starName, studioName
FROM MoviesOf1996 NATURAL JOIN starsIn;
CREATE VIEW MovieOf1996 AS
SELECT *
FROM Movie
WHERE year=1996;
y los esquemas son
Movie(title,year,length,inColor,studioName,producerC#)
StarsIn(title,year,starName)
http://hal.famaf.unc.edu.ar/~bdd/Practico6/
JOIN (unir)
La sentencia JOIN, si es proveida, nombra una función de estimación selectiva join para
el operador (nota que esto es un nombre de una función, no un nombre de un operador).
Las sentencias JOIN solamente tienen sentido para operadores binarios que retorna
valores bouleanos. La idea detrás de un estimador selectivo join es suponer que fracción
de las filas de un par de tablas satisfacerán la condición de la sentencia WHERE del
formulario
table1.field1 OP table2.field2
para el operador corriente. Como la sentencia RESTRICT, esta ayuda al optimizador
muy sustancialmente permitiendole deducir cual de las posibles secuencias join es
probable que tome el menor trabajo.
como antes, este capítulo no procurará explicar como escribir una función estimadora
selectiva join, pero solamente sugeriremos que tu uses uno de los estimadores estandars
si alguna es aplicable:
eqjoinsel
for
neqjoinsel
for
scalarltjoinsel for
scalargtjoinsel for
areajoinsel
for
positionjoinsel for
contjoinsel
for
=
<>
< or <=
> or >=
2D area-based comparisons
2D position-based comparisons
2D containment-based comparisons
http://es.tldp.org/Postgresql-es/web/navegable/todopostgresql/xoper.html
3.4
Agregación GROUP BY, HAVING.
Agrupamiento de Registros
4.1 GROUP BY
Combina los registros con valores idénticos, en la lista de campos
especificados, en un único registro. Para cada registro se crea un valor sumario
si se incluye una función SQL agregada, como por ejemplo Sum o Count, en la
instrucción SELECT. Su sintaxis es:
SELECT campos FROM tabla WHERE criterio GROUP BY campos del grupo
GROUP BY es opcional. Los valores de resumen se omiten si no existe una
función SQL agregada en la instrucción SELECT. Los valores Null en los
campos GROUP BY se agrupan y no se omiten. No obstante, los valores Null
no se evalúan en ninguna de las funciones SQL agregadas.
Se utiliza la cláusula WHERE para excluir aquellas filas que no desea agrupar,
y la cláusula HAVING para filtrar los registros una vez agrupados.
A menos que contenga un dato Memo u Objeto OLE , un campo de la lista de
campos GROUP BY puede referirse a cualquier campo de las tablas que
aparecen en la cláusula FROM, incluso si el campo no esta incluido en la
instrucción SELECT, siempre y cuando la instrucción SELECT incluya al
menos una función SQL agregada.
Todos los campos de la lista de campos de SELECT deben o bien incluirse en
la cláusula GROUP BY o como argumentos de una función SQL agregada.
SELECT Id_Familia, Sum(Stock) FROM Productos GROUP BY Id_Familia;
Una vez que GROUP BY ha combinado los registros, HAVING muestra
cualquier registro agrupado por la cláusula GROUP BY que satisfaga las
condiciones de la cláusula HAVING.
HAVING es similar a WHERE, determina qué registros se seleccionan. Una vez
que los registros se han agrupado utilizando GROUP BY, HAVING determina
cuales de ellos se van a mostrar.
SELECT Id_Familia Sum(Stock) FROM Productos GROUP BY Id_Familia
HAVING Sum(Stock) > 100 AND NombreProducto Like BOS*;
4.2 AVG
Calcula la media aritmética de un conjunto de valores contenidos en un campo
especificado de una consulta. Su sintaxis es la siguiente
Avg(expr)
En donde expr representa el campo que contiene los datos numéricos para los
que se desea calcular la media o una expresión que realiza un cálculo
utilizando los datos de dicho campo. La media calculada por Avg es la media
aritmética (la suma de los valores dividido por el número de valores). La función
Avg no incluye ningún campo Null en el cálculo.
SELECT Avg(Gastos) AS Promedio FROM Pedidos WHERE Gastos > 100;
4.3 Count
Calcula el número de registros devueltos por una consulta. Su sintaxis es la
siguiente
Count(expr)
En donde expr contiene el nombre del campo que desea contar. Los
operandos de expr pueden incluir el nombre de un campo de una tabla, una
constante o una función (la cual puede ser intrínseca o definida por el usuario
pero no otras de las funciones agregadas de SQL). Puede contar cualquier tipo
de datos incluso texto.
Aunque expr puede realizar un cálculo sobre un campo, Count simplemente
cuenta el número de registros sin tener en cuenta qué valores se almacenan en
los registros. La función Count no cuenta los registros que tienen campos null
a menos que expr sea el carácter comodín asterisco (*). Si utiliza un asterisco,
Count calcula el número total de registros, incluyendo aquellos que contienen
campos null. Count(*) es considerablemente más rápida que Count(Campo).
No se debe poner el asterisco entre dobles comillas ('*').
SELECT Count(*) AS Total FROM Pedidos;
Si expr identifica a múltiples campos, la función Count cuenta un registro sólo
si al menos uno de los campos no es Null. Si todos los campos especificados
son Null, no se cuenta el registro. Hay que separar los nombres de los campos
con ampersand (&).
SELECT Count(FechaEnvío & Transporte) AS Total FROM Pedidos;
4.4 Max, Min
Devuelven el mínimo o el máximo de un conjunto de valores contenidos en un
campo especifico de una consulta. Su sintaxis es:
Min(expr)
Max(expr)
En donde expr es el campo sobre el que se desea realizar el cálculo. Expr
pueden incluir el nombre de un campo de una tabla, una constante o una
función (la cual puede ser intrínseca o definida por el usuario pero no otras de
las funciones agregadas de SQL).
SELECT Min(Gastos) AS ElMin FROM Pedidos WHERE Pais = 'España';
SELECT Max(Gastos) AS ElMax FROM Pedidos WHERE Pais = 'España';
4.5 StDev, StDevP
Devuelve estimaciones de la desviación estándar para la población (el total de
los registros de la tabla) o una muestra de la población representada (muestra
aleatoria) . Su sintaxis es:
StDev(expr)
StDevP(expr)
En donde expr representa el nombre del campo que contiene los datos que
desean evaluarse o una expresión que realiza un cálculo utilizando los datos de
dichos campos. Los operandos de expr pueden incluir el nombre de un campo
de una tabla, una constante o una función (la cual puede ser intrínseca o
definida por el usuario pero no otras de las funciones agregadas de SQL)
StDevP evalúa una población, y StDev evalúa una muestra de la población. Si
la consulta contiene menos de dos registros (o ningún registro para StDevP),
estas funciones devuelven un valor Null (el cual indica que la desviación
estándar no puede calcularse).
SELECT StDev(Gastos) AS Desviacion FROM Pedidos WHERE Pais =
'España';
SELECT StDevP(Gastos) AS Desviacion FROM Pedidos WHERE Pais=
'España';
4.6 Sum
Devuelve la suma del conjunto de valores contenido en un campo especifico de
una consulta. Su sintaxis es:
SumP(expr)
En donde expr representa el nombre del campo que contiene los datos que
desean sumarse o una expresión que realiza un cálculo utilizando los datos de
dichos campos. Los operandos de expr pueden incluir el nombre de un campo
de una tabla, una constante o una función (la cual puede ser intrínseca o
definida por el usuario pero no otras de las funciones agregadas de SQL).
SELECT Sum(PrecioUnidad * Cantidad) AS Total FROM DetallePedido;
4.7 Var, VarP
Devuelve una estimación de la varianza de una población (sobre el total de los
registros) o una muestra de la población (muestra aleatoria de registros) sobre
los valores de un campo. Su sintaxis es:
Var(expr)
VarP(expr)
VarP evalúa una población, y Var evalúa una muestra de la población. Expr el
nombre del campo que contiene los datos que desean evaluarse o una
expresión que realiza un cálculo utilizando los datos de dichos campos. Los
operandos de expr pueden incluir el nombre de un campo de una tabla, una
constante o una función (la cual puede ser intrínseca o definida por el usuario
pero no otras de las funciones agregadas de SQL)
Si la consulta contiene menos de dos registros, Var y VarP devuelven Null
(esto indica que la varianza no puede calcularse). Puede utilizar Var y VarP en
una expresión de consulta o en una Instrucción SQL.
SELECT Var(Gastos) AS Varianza FROM Pedidos WHERE Pais = 'España';
SELECT VarP(Gastos) AS Varianza FROM Pedidos WHERE Pais =
'España';
http://www.maestrosdelweb.com/editorial/tutsql4/
Cláusula GROUP BY
La cláusula GROUP BY especifica una consulta sumaria. En vez de producir un
fila de resultados por cada fila de datos de la base de datos, una consulta
sumaria agrupa todas las filas similares y luego produce una fila sumaria de
resultados para cada grupo.
Seguido de la cláusula GROUP BY se especifican los nombres de uno o más
campos cuyos resultados se desean agrupados. Tiene la forma:
GROUP BY expresión_columna
expresión_columna debe coincidir con la expresión de columna utilizada en la
cláusula SELECT. Puede ser uno o más nombres de campo de una tabla,
separados por coma o una o más expresiones separadas por comas.
SELECT RUBRO_CLAVE, COUNT(*) FROM ACTIVOS WHERE TIPO =
'Compra' GROUP BY RUBRO_CLAVE
Esta sentencia nos devolverá una fila por cada area RUBRO_CLAVE, y el
numero de veces de cada uno.
Cláusula HAVING
La cláusula HAVING dice a SQL que incluya solo ciertos grupos producidos por
la cláusula GROUP BY en los resultados de la consulta. Al igual que la cláusula
WHERE, utiliza una condición de búsqueda para especificar los grupos
deseados. En otras palabras, especifica la condición que deben de cumplir los
grupos. Sólo es válida si previamente se ha especificado la cláusula GROUP
BY. La cláusula HAVING tiene la forma:
HAVING expresión1 operador expresión2
expresión1 y expresión2 pueden ser nombres de campos, valores constantes o
expresiones y estas deben coincidir con una expresión de columna en la
cláusula SELECT.
operador es un operador relacional que une las dos expresiones. Más tarde se
verán los distintos operadores que se pueden utilizar.
La sentencia siguiente nos mostrará el número de RUBRO_CLAVE, y el
numero de los mismos en cada RUBRO_CLAVE cuyo numero supera el 1:
SELECT RUBRO_CLAVE, COUNT(*) FROM ACTIVOS WHERE TIPO =
'Compra' GROUP BY RUBRO_CLAVE HAVING RUBRO_CLAVE > 1
http://www.lania.mx/biblioteca/seminarios/basedatos/sql.html#cgroupby
3.5
Funciones de conjunto de registros COUNT,
SUM, AVG, MAX, MIN
Funciones de agrupamiento
Las funciones de agrupamiento pueden ser también parte de una cláusula
SELECT. Devuelven un único valor de un conjunto de registros.
Pueden usarse con un nombre de campo (por ejemplo, AVG(PROY_COSTO) o
en combinación con una expresión de columna más compleja (por ejemplo,
AVG(PROY_COSTO* 1.07).
La expresión de columna puede ir precedida por el operador DISTINCT. El
operador DISTINCT eliminará los valores repetidos de una expresión de
agrupamiento. Por ejemplo,
SELECT COUNT(DISTINCT RESP_CLAVE) FROM ACTIVOS
En este ejemplo, sólo aparecerán el nº de los responsables que se encuentran
en ACTIVOS
Las funciones de agrupamiento permitidas son:
SUM Devuelve la suma total de los valores de una expresión de columna o
campo numérica . Por ejemplo, SUM(COSTOS) devolverá el total costos de los
proyectos.
AVG Devuelve la media de los valores de una expresión de columna. Por
ejemplo, AVG(COSTOS) devolverá la media de costos de los proyectos.
COUNT Devuelve el número de valores en una expresión de columna. Por
ejemplo, COUNT(AREA_CLAVE) devolverá el número de registros con valores
no nulos en ese campo. Un ejemplo especial es COUNT(*), que nos devuelve
el número de registros incluyendo aquellos registros con valores nulos.
MAX Devuelve el valor más alto de los contenidos en una expresión de
columna. Por ejemplo, MAX(FREGISTRO) devolverá la fecha de registro mas
lata que existe en el tabla ACTIVOS.
MIN Devuelve el valor más bajo de los contenidos en una expresión de
columna. Por ejemplo, SELECT MIN(FREGISTRO) FROM ACTIVOS nos
devolverá la fecha de mas antigua.
http://www.lania.mx/biblioteca/seminarios/basedatos/sql.html
Funciones Agregadas de la cláusula SELECT
SQL provee algunas funciones especiales que pueden ser usadas con el
comando SELECT. Esas funciones son las siguientes:






COUNT
SUM
AVG
MAX
MIN
COUNT(*)
COUNT : La función COUNT se usa para obtener el número de valores en la
columna. Opera sobre una colección de valores en una columna de la tabla. La
palabra clave DISTINCT se puede usar conjuntamente con COUNT. Si el resultado
del argumento es el conjunto vacío la función COUNT retorna el valor cero. Un
ejemplo de COUNT es:
SELECT COUNT (DISTINCT MARCA)
FROM MOVIL;
SUM : La función SUM se usa para sumar los valores de una columna. La función
opera sobre una colección de valores en una columna de la tabla. Los valores deben
ser numéricos. Si el resultado del argumento es el conjunto vacío, SUM retorna
NULL. Un ejemplo de SUM es:
SELECT SUM (HORA_HASTA - HORA_DESDE)
FROM VIAJE
WHERE PATENTE_MOVIL = 'HL-8483';
AVG : La Función AVG se usa para promediar todos los valores seleccionados en
una columna, opera sobre una colección de valores (numéricos) en una sola
columna de la tabla. La función AVG puede ir precedida por la palabra clave
DISTINCT lo cual promediará sólo los valores únicos. Si el resultado del argumento
es el conjunto vacío, AVG retorna NULL.
Ejemplo :
SELECT AVG (HORA_HASTA - HORA_DESDE)
FROM VIAJE
WHERE PATENTE_MOVIL = 'HL-8483';
MIN (MAX): La función MIN (MAX) se usa para obtener el menor (mayor) valor en
una columna. Ambas funciones operan sobre una colección de valores en una
columna. Los valores no necesitan ser numéricos. Si el resultado del argumento es
el conjunto vacío, ambas retornan NULL.
Ejemplo:
SELECT MAX (HORA_HASTA - HORA_DESDE)
FROM VIAJE;
SELECT MIN (HORA_HASTA - HORA_DESDE)
FROM VIAJE;
COUNT(*): La función COUNT(*) se usa para contar la cardinalidad de una tabla
sin eliminación de valores duplicados. En las funciones anteriores, cualquier valor
nulo en el argumento se elimina antes que la función se aplique (indiferentemente
de si se usa o no la cláusula DISTINCT) . COUNT(*) retorna cero si el resultado del
argumento es el conjunto vacío.
Ejemplo:
SELECT COUNT(*)
FROM VIAJES
WHERE PATENTE_MOVIL = 'HL-8483';
http://macine.epublish.cl/tesis/index-A_2_.html
Count
Calcula el número de registros devueltos por una consulta. Su sintaxis es la siguiente:
Count(expr)
En donde expr contiene el nombre del campo que desea contar. Los operandos de expr
pueden incluir el nombre de un campo de una tabla, una constante o una función (la cual
puede ser intrínseca o definida por el usuario pero no otras de las funciones agregadas
de SQL). Puede contar cualquier tipo de datos incluso texto.
Aunque expr puede realizar un cálculo sobre un campo, Count simplemente cuenta el
número de registros sin tener en cuenta qué valores se almacenan en los registros. La
función Count no cuenta los registros que tienen campos null a menos que expr sea el
carácter comodín asterisco (*). Si utiliza un asterisco, Count calcula el número total de
registros, incluyendo aquellos que contienen campos null. Count(*) es
considerablemente más rápida que Count(Campo). No se debe poner el asterisco entre
dobles comillas ('*').
SELECT
Count(*) AS Total
FROM
Pedidos
Si expr identifica a múltiples campos, la función Count cuenta un registro sólo si al
menos uno de los campos no es Null. Si todos los campos especificados son Null, no se
cuenta el registro. Hay que separar los nombres de los campos con ampersand (&).
SELECT
Count(FechaEnvío & Transporte) AS Total
FROM
Pedidos
Podemos hacer que el gestor cuente los datos diferentes de un determinado campo
SELECT
Count(DISTINCT Localidad) AS Total
FROM
Pedidos
Max, Min
Devuelven el mínimo o el máximo de un conjunto de valores contenidos en un campo
especifico de una consulta. Su sintaxis es:
Min(expr)
Max(expr)
En donde expr es el campo sobre el que se desea realizar el cálculo. Expr pueden incluir
el nombre de un campo de una tabla, una constante o una función (la cual puede ser
intrínseca o definida por el usuario pero no otras de las funciones agregadas de SQL).
SELECT
Min(Gastos) AS ElMin
FROM
Pedidos
WHERE
Pais = 'España'
SELECT
Max(Gastos) AS ElMax
FROM
Pedidos
WHERE
Pais = 'España'
StDev, StDevP
Devuelve estimaciones de la desviación estándar para la población (el total de los
registros de la tabla) o una muestra de la población representada (muestra aleatoria). Su
sintaxis es:
StDev(expr)
StDevP(expr)
En donde expr representa el nombre del campo que contiene los datos que desean
evaluarse o una expresión que realiza un cálculo utilizando los datos de dichos campos.
Los operandos de expr pueden incluir el nombre de un campo de una tabla, una
constante o una función (la cual puede ser intrínseca o definida por el usuario pero no
otras de las funciones agregadas de SQL).
StDevP evalúa una población, y StDev evalúa una muestra de la población. Si la
consulta contiene menos de dos registros (o ningún registro para StDevP), estas
funciones devuelven un valor Null (el cual indica que la desviación estándar no puede
calcularse).
SELECT
StDev(Gastos) AS Desviación
FROM
Pedidos
WHERE
País = 'España'
SELECT
StDevP(Gastos) AS Desviación
FROM
Pedidos
WHERE
País = 'España'
http://www.mailxmail.com/curso/informatica/sql/capitulo28.htm
Sum
Devuelve la suma del conjunto de valores contenido en un campo especifico de una
consulta. Su sintaxis es:
Sum(expr)
En donde expr representa el nombre del campo que contiene los datos que desean
sumarse o una expresión que realiza un cálculo utilizando los datos de dichos campos.
Los operandos de expr pueden incluir el nombre de un campo de una tabla, una
constante o una función (la cual puede ser intrínseca o definida por el usuario pero no
otras de las funciones agregadas de SQL).
SELECT
Sum(PrecioUnidad * Cantidad) AS Total
FROM
DetallePedido
Var, VarP
Devuelve una estimación de la varianza de una población (sobre el total de los registros)
o una muestra de la población (muestra aleatoria de registros) sobre los valores de un
campo. Su sintaxis es:
Var(expr)
VarP(expr)
VarP evalúa una población, y Var evalúa una muestra de la población. Expr el nombre
del campo que contiene los datos que desean evaluarse o una expresión que realiza un
cálculo utilizando los datos de dichos campos. Los operandos de expr pueden incluir el
nombre de un campo de una tabla, una constante o una función (la cual puede ser
intrínseca o definida por el usuario pero no otras de las funciones agregadas de SQL)
Si la consulta contiene menos de dos registros, Var y VarP devuelven Null (esto indica
que la varianza no puede calcularse). Puede utilizar Var y VarP en una expresión de
consulta o en una Instrucción SQL.
SELECT
Var(Gastos) AS Varianza
FROM
Pedidos
WHERE
País = 'España'
SELECT
VarP(Gastos) AS Varianza
FROM
Pedidos
WHERE
País = 'España'
COMPUTE de SQL-SERVER
Esta cláusula añade una fila en el conjunto de datos que se está recuperando, se utiliza
para realizar cálculos en campos numéricos. COMPUTE actúa siempre sobre un campo
o expresión del conjunto de resultados y esta expresión debe figurar exactamente igual
en la cláusula SELECT y siempre se debe ordenar el resultado por la misma o al memos
agrupar el resultado. Esta expresión no puede utilizar ningún ALIAS.
SELECT
IdCliente, Count(IdPedido)
FROM
Pedidos
GROUP BY
IdPedido
HAVING
Count(IdPedido) > 20
COMPUTE
Sum(Count(IdPedido))
SELECT
IdPedido, (PrecioUnidad * Cantidad - Descuento)
FROM
[Detalles de Pedidos]
ORDER BY
IdPedido
COMPUTE
Sum((PrecioUnidad * Cantidad - Descuento)) // Calcula el Total
BY IdPedido // Calcula el Subtotal
http://www.mailxmail.com/curso/informatica/sql/capitulo29.htm
Unidad 4. Control de Transacciones.
4.1 Propiedades de la transacción.
Propiedades de las transacciones
La discusión en la sección previa clarifica el concepto de transacción. Sin embargo, aun
no se ha dado ninguna justificación para afirmar que las transacciones son unidades de
procesamiento consistentes y confiables. Las propiedades de una transacción son las
siguientes:
1. Atomicidad. Se refiere al hecho de que una transacción se trata como una unidad
de operación. Por lo tanto, o todas las acciones de la transacción se realizan o
ninguna de ellas se lleva a cabo. La atomicidad requiere que si una transacción
se interrumpe por una falla, sus resultados parciales deben ser deshechos. La
actividad referente a preservar la atomicidad de transacciones en presencia de
abortos debido a errores de entrada, sobrecarga del sistema o interbloqueos se le
llama recuperación de transacciones. La actividad de asegurar la atomicidad en
presencia de caídas del sistema se le llama recuperación de caídas.
2. Consistencia. La consistencia de una transacción es simplemente su correctitud.
En otras palabras, una transacción es un programa correcto que lleva la base de
datos de un estado consistente a otro con la misma característica. Debido a esto,
las transacciones no violan las restricciones de integridad de una base de datos.
3. Aislamiento. Una transacción en ejecución no puede revelar sus resultados a
otras transacciones concurrentes antes de su commit. Más aún, si varias
transacciones se ejecutan concurrentemente, los resultados deben ser los mismos
que si ellas se hubieran ejecutado de manera secuencial (seriabilidad).
4. Durabilidad. Es la propiedad de las transacciones que asegura que una vez que
una transacción hace su commit, sus resultados son permanentes y no pueden ser
borrados de la base de datos. Por lo tanto, los DBMS aseguran que los resultados
de una transacción sobrevivirán a fallas del sistema. Esta propiedad motiva el
aspecto de recuperación de bases de datos, el cual trata sobre como recuperar la
base de datos a un estado consistente en donde todas las acciones que han hecho
un commit queden reflejadas.
En resumen, las transacciones proporcionan una ejecución atómica y confiable en
presencia de fallas, una ejecución correcta en presencia de accesos de usuario múltiples
y un manejo correcto de réplicas (en el caso de que se soporten).
TRANSACCIONES
Los sistemas que tratan el problema de control de concurrencia permiten que
sus usuarios asuman que cada una de sus aplicaciones se ejecutan
atómicamente, como si no existieran otras aplicaciones ejecutándose
concurrentemente.
Esta abstracción de una ejecución atómica y confiable de una aplicación se
conoce como una transacción.
Un algoritmo de control de concurrencia asegura que las transacciones se
ejecuten atómicamente controlando la intercalación de transacciones
concurrentes, para dar la ilusión de que las transacciones se ejecutan
serialmente, una después de la otra, sin ninguna intercalación. Las ejecuciones
intercaladas cuyos efectos son los mismos que las ejecuciones seriales son
denominadas serializables y son correctos ya que soportan la ilusión de la
atomicidad de las transacciones.
El concepto principal es el de transacción. Informalmente, una transacción es la
ejecución de ciertas instrucciones que accesan a una base de datos
compartida. El objetivo del control de concurrencia y recuperación es asegurar
que dichas transacciones se ejecuten atómicamente, es decir:
Cada transacción accede a información compartida sin interferir con otras
transacciones, y si una transacción termina normalmente, todos sus efectos
son permanentes, en caso contrario no tiene afecto alguno.
Una base de datos está en un estado consistente si obedece todas las
restricciones de integridad (significa que cuando un registro en una tabla haga
referencia a un registro en otra tabla, el registro correspondientes debe existir)
definidas sobre ella.
Los cambios de estado ocurren debido a actualizaciones, inserciones y
supresiones de información. Por supuesto, se quiere asegurar que la base de
datos nunca entre en un estado de inconsistencia.
Sin embargo, durante la ejecución de una transacción, la base de datos puede
estar temporalmente en un estado inconsistente.
El punto importante aquí es asegurar que la base de datos regresa a un estado
consistente al fin de la ejecución de una transacción.
3. PROPIEDADES FUNDAMENTALES DE UNA TRANSACCIÓN:
1. Atomicidad Se refiere al hecho de que una transacción se trata como una
unidad de operación.
2. Por lo tanto, o todas las acciones de la transacción se realizan o ninguna de
ellas se lleva a cabo. La atomicidad requiere que si una transacción se
interrumpe por una falla, sus resultados parciales sean anulados.
3. Consistencia La consistencia de una transacción es simplemente su
correctitud. En otras palabras, una transacción es un programa correcto que
lleva a la base de datos de un estado consistente a otro con la misma
característica. Debido a esto, las transacciones no violan las restricciones de
integridad de una base de datos.
4. Aislamiento Una transacción en ejecución no puede revelar sus resultados a
otras transacciones concurrentes antes de finalizar.
5. Más aún, si varias transacciones se ejecutan concurrentemente, los resultados
deben ser los mismos que si ellas se hubieran ejecutado de manera
secuencial.
6. Permanencia Es la propiedad de las transacciones que asegura que una vez
que una transacción finaliza exitosamente, sus resultados son permanentes y
no pueden ser borrados de la base de datos por alguna falla posterior.
7. Por lo tanto, los sistemas manejadores de base de datos aseguran que los
resultados de una transacción sobrevivirán a fallas del sistema. Esta propiedad
motiva el aspecto de recuperación de base de datos, el cual trata sobre cómo
recuperar la base de datos a un estado consistente donde todas las acciones
que han finalizado con éxito queden reflejadas en la base.
8. En esencia, lo que se persigue con el procesamiento de transacciones es, por
una parte obtener una transparencia adecuada de las acciones concurrentes a
una base de datos y por otra, manejar adecuadamente las fallas que se
puedan presentar en una base de datos.
9. La mayoría de medianas y grandes compañías modernas utilizan el
procesamiento de transacciones para sus sistemas de producción, y es tan
imprescindible que las organizaciones no pueden funcionar en ausencia de él.
El procesamiento de transacciones representa una enorme y
significativa porción del mercado de los sistemas informáticos
(más de cincuenta billones de dólares al año) y es,
probablemente, la aplicación simple más amplia de las
computadoras.
Además, se ha convertido en el elemento que facilita el comercio
electrónico.
Como puede percibirse, el procesamiento de transacciones es
una de las tareas más importantes dentro de un sistema de base
de datos, pero a la vez, es una de las más difíciles de manejar
debido a diversos aspectos, tales como:
10. Confiabilidad Puesto que los sistemas de base de datos en línea no pueden
fallar.
11. Disponibilidad Debido a que los sistemas de base de datos en línea deben
estar actualizados correctamente todo el tiempo.
12. Tiempos de Respuesta En sistemas de este tipo, el tiempo de respuesta de las
transacciones no debe ser mayor a doce segundos.
13. Throughput Los sistemas de base de datos en línea requieren procesar miles
de transacciones por segundo.
14. Atomicidad En el procesamiento de transacciones no se aceptan resultados
parciales.
15. Permanencia No se permite la eliminación en la base de datos de los efectos
de una transacción que ha culminado con éxito.
http://www.monografias.com/trabajos24/concurrencia-base-datos/concurrencia-basedatos.shtml
4.2 Grados de consistencia.
4.3 Niveles de aislamiento.
http://www.microsoft.com/spanish/msdn/articulos/archivo/070602/voices/
Bdadotnetarch13.asp
Aislamiento transaccional
El estándar ANSI/ISO SQL define cuatro niveles de aislamiento transaccional en
función de tres hechos que deben ser tenidos en cuenta entre transacciones concurrentes.
Estos hechos no deseados son:
lecturas "sucias"
Una transacción lee datos escritos por una transacción no esperada, no cursada.
lecturas no repetibles
Una transacción vuelve a leer datos que previamente había leído y encuentra que
han sido modificados por una transacción cursada.
lectura "fantasma"
Una transacción vuelve a ejecutar una consulta, devolviendo un conjuto de filas
que satisfacen una condición de búsqueda y encuentra que otras filas que
satisfacen la condición han sido insertadas por otra transacción cursada.
Los cuatro niveles de aislamiento y sus correspondientes acciones se describen más
abajo.
Tabla 1. Niveles de aislamiento de Postgres
Lectura "sucia" Lectura no repetible Lectura "fantasma"
Lectura no cursada Posible
Posible
Posible
Lectura cursada
No posible
Posible
Posible
Lectura repetible
No posible
No posible
Posible
Serializable
No posible
No posible
No posible
Postgres ofrece lectura cursada y niveles de aislamiento serializables.
http://es.tldp.org/Postgresql-es/web/navegable/user/x3589.html
Niveles de aislamiento en SQL
SQL estándar define 4 niveles de aislamiento en términos de 3 fenómenos que deben ser
prevenidos entre transacción concurrentes. Estos son:



dirty read: Una transacción lee datos escritos por una transacción
concurrente que no ha hecho "commit"
nonrepeatable read: Una transacción re-lee datos que leyó
previamente y encuentra que han sido modificados por otra transacción
(que hizo commit en el inter).
phantom read: Una transacción re-ejecuta un query regresando un
conjunto de tuplas que satisfacen una condición de búsqueda y
encuentra que el resultado ha cambiado debido a otra transacción que
hizo "commit" recientemente.
SQL Transaction Isolation Levels
Isolation Level Dirty Read Nonrepeatable Read Phantom Read
Read uncommitted Possible
Possible
Possible
Read committed
Not possible Possible
Possible
Repeatable read
Not possible Not possible
Possible
Isolation Level Dirty Read Nonrepeatable Read Phantom Read
Serializable
Not possible Not possible
Not possible
*PostgreSQL ofrece Read Committed (default) y Serializable
*La mayoría de los dbms ofrecen los 4 niveles
Descripción de los niveles de aislamiento en Innodb (MySQL)
READ UNCOMMITTED
Tambíen llamado "dirty read": los selects que norequieren bloqueos son
realizados de manera que no es posible ver una versión más reciente del
registro, entonces no hay lecturas consistentes bajo este nivel. El
opuesto es el READ COMMITTED.
READ COMMITTED
Parecido al nivel de aislamiento en Oracle. Todos los queries del tipo SELECT
... FOR UPDATE and SELECT ... LOCK IN SHARE MODE únicamente bloquean
los índices de los registros, no los huecos (gaps) anteriores a ellos y así permite
insertar libremente nuevos registros después de los registros bloqueados. UPDATE
yDELETE que usan un índice único con una única condición de búsqueda, solo
bloquean el índice del registro encontrado, no los huecos entre ellos. Pero en
selecciones de "rangos" para UPDATE y DELETE en Innodb se debe aplicar un
bloqueo de "next-key o gap" y bloquear las inserciones de otros usuarios en los
huecos cubiertos en ese rango. Esto es necesario porque tuplas fantasmas
(phantom rows) tienen que ser bloqueadas para replicación y recuperación.
Lecturas consistentes llegan a ser como en Oracle: cada lectura consistente, aun
dentro de la misma transacción, lee y actualiza su propia copia.
REPEATABLE READ
El nivel por default en InnoDB. SELECT ... FOR UPDATE, SELECT ...
LOCK IN SHARE MODE, UPDATE, and DELETE, los cuales usan índices únicos
con una única condición de búsqueda, sólo bloquean el índice del
registro encontrado, no los huecos anteriores a él. De otra manera estas
operaciones emplean bloqueos "next-key", bloqueando el rango de
índices obtenido a partir del bloqueo "next-key" o "gap" y bloquea
nuevas inserciones por parte de otros usuarios. En lecturas consistentes
hay una diferencia muy importante con el nivel "read commited": en este
nivel todas las lecturas consistentes dentro de la misma transacción leen
la misma copia de información establecida por la primer lectura. Esta
convención significa que si se realizan varios selects simples dentro de la
misma transacción estos selects son consistentes entre si.
SERIALIZABLE
Este nivel es como el anterior, pero todos los selects simples son
implícitamente convertidos a SELECT ... LOCK IN SHARE MODE.
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ
UNCOMMITTED | READ COMMITTED | REPEATABLE READ |
SERIALIZABLE}
http://ict.udlap.mx/people/carlos/is341/bases10.html
4.4 Instrucciones COMMIT y ROLLBACK .
Gestión de las transacciones
Las transacciones SQL son conjuntos de instrucciones que hay que tratar como unidades
atómicas, es decir no descomponibles en las instrucciones individuales de las que están
formadas. Gracias a esta atomicidad, las transacciones permiten que se ejecuten operaciones
complejas en la base de datos, manteniendo la integridad. Efectivamente, una transacción se
ejecuta con éxito si y sólo si todas las operaciones que la componen terminan con éxito. Si no,
es decir si una de las operaciones falla, o si la transacción se anula explícitamente, todas las
operaciones anteriores son también anuladas. Las operaciones de una transacción no tienen
ningún efecto sobre la base de datos hasta que la transacción no se completa con éxito.
Desde el momento en que a una base de datos pueden acceder diferentes usuarios al mismo
tiempo, en cada instante podremos tener distintas transacciones que manipulen la base de
datos a la vez. El estándar SQL prevé que normalmente las transacciones se ejecuten en el
"nivel de aislamiento serializable" (isolation level SERIALIZABLE), o sea en una modalidad de
ejecución que garantice la "serializabilidad" de las transacciones. El hecho de que las
transacciones se puedan serializar significa que su efecto global sobre la base de datos es el
que se obtendría si aquéllas se ejecutasen no al mismo tiempo, sino una después de otra.
En el lenguaje SQL estándar, no existe una instrucción que haga iniciar explícitamente una
transacción. Las instrucciones se dividen en dos clases: las que pueden empezar una
transacción y las que no la hacen empezar. En el momento en que se intenta ejecutar una
instrucción del primer tipo, si no está ya en marcha una transacción, empieza una. La
transacción continúa hasta que una de las instrucciones falla, provocando la anulación de toda
la transacción, o hasta que se ejecuten las instrucciones COMMIT WORK o ROLLBACK
WORK. La instrucción COMMIT WORK termina la transacción confirmándola, convirtiendo en
definitivos los efectos de sus instrucciones sobre la base de datos. Sin embargo, la instrucción
ROLLBACK WORK acaba anulándola.
A menudo, las DBMS que se encuentran en el mercado implementan la gestión de las
transacciones de modo distinto a como está previsto en el estándar (al menos en sus
colocaciones por defecto). En este caso, normalmente está prevista una orden que empieza
explícitamente una transacción (BEGIN TRANSACTION, START WORK u otro). Si una
transacción no se ha empezado explícitamente, las instrucciones concretas componen una
cada una.
Para entender mejor cuáles podrían ser las consecuencias de la manipulación concurrente de
los datos de una base de datos sin usar transacciones, veamos un ejemplo. Supongamos que
tenemos una base de datos con la que gestionamos los pedidos de los productos que
vendemos. En concreto, cuando un cliente nos solicita un producto, comprobamos la
disponibilidad y, en el caso en que podamos satisfacer el pedido, restamos a la cantidad que
tenemos la cantidad que se nos ha pedido. Traduciendo todo esto a SQL, obtenemos la
cantidad almacenada con la instrucción (instrucción A):
SELECT almacenamiento FROM productos
WHERE productoID=1453
La actualización del almacenamiento, una vez comprobada la disponibilidad se obtiene con la
siguiente instrucción (instrucción B):
UPDATE productos
SET almacenamiento=almacenamiento-1
WHERE productoID=1453
Si dos usuarios intentan ejecutar esta operación, sin que las dos instrucciones que la
componen se hayan reagrupado en una transacción, podría suceder que las instrucciones se
ejecuten en el orden y con los resultados siguientes:
1. Instrucción A, ejecutada por el usuario 1: se devuelve un almacenamiento del producto
equivalente a 1, por lo que el pedido será aprobado.
2. Instrucción A, ejecutada por el usuario 2: como antes, el almacenamiento es 1 y
también en este caso el pedido se aprobará.
3. Instrucción B, ejecutada por el usuario 1: en este punto, en la base de datos el
almacenamiento para el producto vale 0.
4. Instrucción B, ejecutada por el usuario 2: ahora el almacenamiento vale -1, que,
obviamente, es un valor equivocado.
Como se ve, el resultado final es que uno de los dos clientes no podrá recibir (al menos no
inmediatamente) la mercancía, dado que no teníamos en almacén una cantidad suficiente para
ambos clientes. Si las dos instrucciones se hubieran incluido en una transacción, el problema
no se habría producido, dado que la transacción del segundo usuario no habría podido leer el
valor del almacenamiento hasta que no se hubiese completado la transacción del primer
usuario. En ese momento, el almacenamiento habría tenido valor 0 y el pedido no habría
estado erróneamente aprobado.
COMMIT
Se usa la sentencia COMMIT para terminar una transaccion salvando los
cambios que se han realizado. Mientras los cambios no estan guardados la
transaccion no finaliza y nadie puede acceder a los datos en la BD. La
sentencia COMMIT hace permanentes los cambios realizados, los hace visibles
a los otros usuarios permitiendo su manipulaciony finaliza la transaccion.
Existe una opcion en el preprocesador ecpg que permite no usar la instrucción
COMMIT y aun asi que se guarden los cambios producidos en las
transacciones realizadas en el programa. Escribiendo ecpg –t filename.sqc
permitimos que se guarden automaticamente las transacciones que se realizan.
La forma mas correcta de usar COMMIT es poniendo la instrucción justo despues de realizar la
transaccion habiendo comprovado que no se ha producido ningun error en la transaccion para
que asi la BD este el minimo tiempo ocupada y se guarden los cambios rapidamente.
EXEC SQL UPDATE <table> SET <instruction> WHERE <query>;
If (ERROR) EXEC SQL ROLLBACK;
ELSE EXEC SQL COMMIT;
EXEC SQL COMMIT;
ROLLBACK
Se usa ROLLBACK para deshacer los cambios que estan pendientes de salvar en la base de
datos. Por ejemplo si se produce un error en alguna instrucción de una transaccion se usa la
sentencia ROLLBACK para evitar que se guarden de forma permanente. Al escribir EXEC SQL
ROLLBACK se deshacen los cambios producidos y se finaliza la transaccion que esta activa
actualmente.
La forma mas correcta de usar ROLLBACK seria ponerlo despues de de una instrucción de
control de errores como WHENEVER o alguna sentencia de control de flujo como if usando la
variable sqlca.sqlcode para poder deshacer los cambios en el caso de que se produjese algun
tipo de error.
EXEC SQL UPDATE <table> SET <instruction> WHERE <query>;
If (ERROR) EXEC SQL ROLLBACK;
ELSE EXEC SQL COMMIT;
http://es.tldp.org/Postgresql-es/web/navegable/SQL_inmerso/SQL_inmerso.html
Transacciones anidadas
Otra de las posibilidades que nos ofrece el SQL Server es utilizar transacciones anidadas. Esto quiere
decir que podemos tener transacciones dentro de transacciones, es decir, podemos empezar una nueva
transacción sin haber terminado la anterior.
Asociada a esta idea de anidamiento existe una variable global @@TRANCOUNT que tiene valor 0 si no
existe ningún nivel de anidamiento, 1 si hay una transacción anidada, 2 si estamos en el segundo nivel de
anidamiento. y así sucesivamente.
La dificultad de trabajar con transacciones anidadas está en el comportamiento que tienen ahora las
sentencias 'COMMIT TRAN' y 'ROLLBACK TRAN'


ROLLBACK TRAN: Dentro de una transacción anidada esta sentencia deshace todas las
transacciones internas hasta la instrucción BEGIN TRANSACTION más externa.
COMMIT TRAN: Dentro de una transacción anidada esta sentencia únicamente reduce en 1 el
valor de @@TRANCOUNT, pero no "finaliza" ninguna transacción ni "guarda" los cambios. En el
caso en el que @@TRANCOUNT=1 (cuando estamos en la última transacción) COMMIT TRAN
hace que todas las modificaciones efectuadas sobre los datos desde el inicio de la transacción
sean parte permanente de la base de datos, libera los recursos mantenidos por la conexión y
reduce @@TRANCOUNT a 0.
Como siempre un ejemplo es lo mejor para entender como funciona.
CREATE TABLE Test (Columna int)
GO
BEGIN TRAN TranExterna -- @@TRANCOUNT ahora es 1
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
INSERT INTO Test VALUES (1)
BEGIN TRAN TranInterna1 -- @@TRANCOUNT ahora es 2.
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
INSERT INTO Test VALUES (2)
BEGIN TRAN TranInterna2 -- @@TRANCOUNT ahora es 3.
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
INSERT INTO Test VALUES (3)
COMMIT TRAN TranInterna2 -- Reduce @@TRANCOUNT a 2.
-- Pero no se guarda nada en la base de datos.
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
COMMIT TRAN TranInterna1 -- Reduce @@TRANCOUNT a 1.
-- Pero no se guarda nada en la base de datos.
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
COMMIT TRAN TranExterna -- Reduce @@TRANCOUNT a 0.
-- Se lleva a cabo la transacción externa y todo lo que conlleva.
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
SELECT * FROM Test
Por cierto que lo de usar nombre para las transacciones es por claridad, puesto que COMMIT TRAN como
ya hemos dicho solamente reduce en 1 el valor de @@TRANCOUNT.
Veamos ahora un ejemplo de transacción anidada con ROLLBACK TRAN
BEGIN TRAN TranExterna -- @@TRANCOUNT ahora es 1
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
INSERT INTO Test VALUES (1)
BEGIN TRAN TranInterna1 -- @@TRANCOUNT ahora es 2.
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
INSERT INTO Test VALUES (2)
BEGIN TRAN TranInterna2 -- @@TRANCOUNT ahora es 3.
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
INSERT INTO Test VALUES (3)
ROLLBACK TRAN --@@TRANCOUNT es 0 y se deshace
--la transacción externa y todas las internas
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
SELECT * FROM Test
En este caso no se inserta nada puesto que el ROLLBACK TRAN deshace todas las transacciones dentro
de nuestro anidamiento hasta la transacción más externa y además hace @@TRANCOUNT=0
¿Supone este funcionamiento asimétrico del COMMIT y del ROLLBACK un problema? Pues la verdad es
que no. La manera de tratar las transacciones por el SQL Server es la que nos permite programar de
manera natural los anidamientos. De todos modos, si queremos ir un poco más lejos hay una cuarta
sentencia para trabajar con transacciones: SAVE TRAN
Save Tran
Esta sentencia crea un punto de almacenamiento dentro de una transacción. Esta marca sirve para
deshacer una transacción en curso sólo hasta ese punto. Por supuesto nuestra transacción debe
continuar y terminar con un COMMIN TRAN (o los que hagan falta) para que todo se guarde o con un
ROLLBACK TRAN para volver al estado previo al primer BEGIN TRAN.
BEGIN TRAN TranExterna -- @@TRANCOUNT ahora es 1
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
INSERT INTO Test VALUES (1)
BEGIN TRAN TranInterna1 -- @@TRANCOUNT ahora es 2.
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
INSERT INTO Test VALUES (2)
SAVE TRAN Guadada
BEGIN TRAN TranInterna2 -- @@TRANCOUNT ahora es 3.
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
INSERT INTO Test VALUES (3)
ROLLBACK TRAN Guadada -- se deshace lo hecho el punto guardado.
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
--Ahora podemos decidir si la transacción se lleva a cabo
--o se deshace completamente
--Para deshacerla un ROLLBACK bastará como hemos visto
--Pero para guardar la transacción hace falta reducir @@TRANCOUNT a 0
COMMIT TRAN TranInterna1 -- Reduce @@TRANCOUNT a 2.
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
COMMIT TRAN TranInterna1 -- Reduce @@TRANCOUNT a 1.
-- Pero no se guarda nada en la base de datos.
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
COMMIT TRAN TranExterna -- Reduce @@TRANCOUNT a 0.
-- Se lleva a cabo la transacción externa y todo lo que conlleva.
SELECT 'El nivel de anidamiento es', @@TRANCOUNT
SELECT * FROM Test
Si no ponemos el nombre del punto salvado con SAVE TRAN al hacer un ROLLBACK TRAN se deshace
la transacción más externa y @@TRANCOUNT se pone a 0.
Como podemos ver el uso de transacciones no es complicado, e incluso las transacciones anidadas si se
tratan con cuidado son fáciles de manejar.
Un par de ejemplos más
Veamos otro par de ejemplos para dejar claro como funcionan las sentencias BEGIN, COMMIT y SAVE
BEGIN TRAN
-- Primer BEGIN TRAN y ahora @@TRANCOUNT = 1
BEGIN TRAN
-- Ahora @@TRANCOUNT = 2
COMMIT TRAN
-- Volvemos a @@TRANCOUNT = 1
-- Pero no se guarda nada ni se hacen efectivos los posibles
cambios
COMMIT TRAN
-- Por fin @@TRANCOUNT = 0
-- Si hubiera cambios pendientes se llevan a la base de datos
-- Y volvemos a un estado normal con la transacción acabada
Uso del COMMIT
BEGIN TRAN
-- Primer BEGIN TRAN y @@TRANCOUNT = 1
BEGIN TRAN
-- Ahora @@TRANCOUNT = 2
COMMIT TRAN
-- Como antes @@TRANCOUNT = 1
--Y como antes nada se guarda
ROLLBACK TRAN
-- Se cancela TODA la transacción. Recordemos que el COMMIT
-- de antes no guardo nada, solo redujo @@TRANCOUNT
-- Ahora @@TRANCOUNT = 0
COMMIT TRAN
-- No vale para nada porque @@TRANCOUNT es 0 por el efecto del ROLLBACK
Uso del ROLLBACK
En cuanto al SAVE TRAN podemos recordarlo con el siguiente ejemplo:
CREATE TABLE Tabla1 (Columna1 varchar(50))
GO
BEGIN TRAN
INSERT INTO Tabla1 VALUES ('Primer valor')
SAVE TRAN Punto1
INSERT INTO Tabla1 VALUES ('Segundo valor')
ROLLBACK TRAN Punto1
INSERT INTO Tabla1 VALUES ('Tercer valor')
COMMIT TRAN
SELECT * FROM Tabla1
Columna1
-------------------------------------------------Primer valor
Tercer valor
(2 filas afectadas)
Un ROLLBACK a un SAVE TRAN no deshace la transacción en curso ni modifica @@TRANCOUNT,
simplemente cancela lo ocurrido desde el 'SAVE TRAN nombre' hasta su 'ROLLBACK TRAN nombre'
Transacciones y procedimientos almacenados.
Cuando trabajamos con procedimientos almacenados debemos recordar que cada procedimiento
almacenado es una unidad. Cuando se ejecuta lo hace de manera independiente de quien lo llama. Sin
embargo si tenemos un ROLLBACK TRAN dentro de un procedimiento almacenado cancelaremos la
transacción en curso, pero si hay una transacción externa al procedimiento en el que estamos trabajando
se cancelará esa transacción externa.
Con esto no quiero decir que no se pueda usar, simplemente que hay que tener muy claras las 4 normas
sobre las sentencias BEGIN, ROLLBACK y COMMIT que comentamos al principio de este artículo.
Veamos como se comporta una transacción en un procedimiento almacenado llamado desde una
transacción.
CREATE PROCEDURE Inserta2
AS
BEGIN TRAN --Uno
INSERT INTO Tabla1 VALUES ('Valor2')
ROLLBACK TRAN --Uno
GO
CREATE PROCEDURE Inserta1
AS
BEGIN TRAN --Dos
INSERT INTO Tabla1 VALUES ('Valor 1')
EXEC Inserta2
INSERT INTO Tabla1 VALUES ('Valor3')
COMMIT TRAN --Dos
GO
En principio parece que si ejecutamos el procedimiento 'Inserta1' el resultado sería:
EXECUTE inserta1
SELECT * FROM tabla1
txt
-------------------------------------------------Valor1
Valor3
(2 filas afectadas)
Pero lo que obtenemos es:
EXECUTE inserta1
SELECT * FROM tabla1
(1 filas afectadas)
(1 filas afectadas)
Servidor: mensaje 266, nivel 16, estado 2, procedimiento Inserta2, línea 8
El recuento de transacciones después de EXECUTE
indica que falta una instrucción COMMIT o ROLLBACK TRANSACTION.
Recuento anterior = 1, recuento actual = 0.
(1 filas afectadas)
Servidor: mensaje 3902, nivel 16, estado 1, procedimiento Inserta1, línea
8
La petición COMMIT TRANSACTION no tiene la correspondiente BEGIN
TRANSACTION.
txt
-------------------------------------------------Valor3
(1 filas afectadas)
Si analizamos estos mensajes vemos que se inserta la primera fila, se salta al segundo procedimiento
almacenado y se inserta la segunda fila. Se ejecuta el 'ROLLBACK TRAN -Dos' del segundo
procedimiento almacenado y se deshacen las dos inserciones porque este ROLLBACK cancela la
transacción exterior, la del primer procedimiento almacenado. A continuación se termina el segundo
procedimiento almacenado y como este procedimiento tiene un 'BEGIN TRAN -Dos' y no tiene un
COMMIT o un ROLLBACK (recordemos que el 'ROLLBACK TRAN -Dos' termina el 'BEGIN TRAN -Uno')
se produce un error y nos avisa que el procedimiento almacenado termina con una transacción pendiente.
Al volver al procedimiento almacenado externo se ejecuta el INSERT que inserta la tercera fila y a
continuación el 'COMMIT TRAN --Uno'. Aquí aparece otro error puesto que este 'COMMIT TRAN -Uno'
estaba ahí para finalizar una transacción que ya ha sido cancelada anteriormente.
El modo correcto
Para que nuestras transacciones se comporten como se espera dentro de un procedimiento almacenado
podemos recurrir al SAVE TRAN.
Veamos como:
CREATE PROCEDURE Inserta2
AS
SAVE TRAN Guardado
INSERT INTO Tabla1 VALUES ('Valor2')
ROLLBACK TRAN Guardado
GO
CREATE PROCEDURE Inserta1
AS
BEGIN TRAN
INSERT INTO Tabla1 VALUES ('Valor 1')
EXEC Inserta2
INSERT INTO Tabla1 VALUES ('Valor 3')
COMMIT TRAN
GO
Ahora el 'ROLLBACK TRAN guardado' del segundo procedimiento almacenado deshace la transacción
sólo hasta el punto guardado. Además este ROLLBACK no decrementa el @@TRANCOUNT ni afecta a
las transacciones en curso.
El resultado obtenido al ejecutar este procedimiento almacenado es:
EXECUTE inserta1
SELECT * FROM tabla1
(1 filas afectadas)
(1 filas afectadas)
(1 filas afectadas)
txt
-------------------------------------------------Valor 1
Valor 3
(2 filas afectadas)
Una vez vistos estos ejemplos queda claro que no hay problema en utilizar transacciones dentro de
procedimientos almacenados siempre que tengamos en cuenta el comportamiento del ROLLBACK TRAN
y que utilicemos el SAVE TRAN de manera adecuada.
http://www.programacion.com/bbdd/articulo/man_transacciones/
Unidad 5. Vistas
5.1 Definición y objetivo de las vistas.
Vista.
Una vista es una tabla virtual definida lógicamente sobre las tablas de la base. Su
definición utiliza la orden de extracción de datos SELECT, que es la única
componente almacenada en la base. El objetivo de las vistas es permitir a los
usuarios manipular los subconjuntos de datos asegurando un máximo control de
integridad y de confidencialidad de los datos.
Una vista se nombra como una tabla y su identificador debe ser único en una base de
datos con respecto a las otras vistas y tablas
http://64.233.179.104/search?q=cache:WaxcUHzYKwcJ:alarcos.infcr.uclm.es/doc/bbddavanzadas/IntrORACLE.pdf+%22objetivo+de+las+vistas%22&hl=es
Vistas
Hasta ahora las únicas tablas de las que nos hemos ocupado han sido las definidas con la
orden CREATE TABLE. El lenguaje SQL también pone a disposición la posibilidad de definir
tablas "virtuales", las vistas, calculadas a partir de otras tablas. Son virtuales en el sentido que
no ocupan espacio en el disco, pero son el resultado de interrogaciones sobre otras tablas y,
por lo tanto, siempre están alineadas con los valores contenidos en dichas tablas.
La instrucción SQL para definir una vista es la siguiente:
CREATE VIEW nombre_vista [ ( lista_nombres_columnas ) ]
AS expresión_tabla
Crea una vista llamada nombre_vista definitda por la expresión_tabla. Típicamente,
expresión_tabla es una instrucción select que producirá la tabla que interesa. La
lista_nombres_columnas se puede usar para asignar nombres a las columnas de la vista. Esto
es útil en el caso en que las columnas que derivan de la expresión_tabla sean resultado de un
cálculo (por ejemplo COUNT(nombre_columna)) y por ello no tengan un nombre explícito. Una
vez creada, una vista se puede utilizar como una tabla normal. Las unicas limitaciones se
refieren a las operaciones que cambian los datos contenidos en ella. En efecto, no todas las
vistas pueden actualizarse. Las reglas que discriminan entre una vista actualizable y una no
actualizable son más bien complejas, y no es este el lugar para describirlas (véanse los libros
en la bibliografía, concretamente el de C.J. Date). Aquí vamos a limitarnos a intentar entender,
mediante un ejemplo, por qué sucede esto.
Hagamos la prueba usando la siguiente vista en nuestra base de datos bibliográfica:
CREATE VIEW book_publisher89
AS SELECT B.title, P.name
FROM Book B, Publisher P
WHERE B.publisher = P.ID
AND B.pub_year=1989
Ésta nos permite ejecutar la query que la define simplemente utilizando la instrucción:
SELECT * FROM book_publisher89
Podemos también introducir ulteriores condiciones (o hacer que el resultado se ordene según
una columna concreta de la vista, etc...):
SELECT title FROM book_publisher89
WHERE name = "ACM Press"
Esta última interrogación nos ofrece la lista de los títulos de los libros publicados por ACM
Press en 1989.
Como se ve, por lo que respecta a las operaciones de interrogación, una vista se comporta
como una tabla normal. Las diferencias aparecen cuando se intentan aplicar a una vista
operaciones de actualización. Por ejemplo, si intentamos ejecutar la siguiente instrucción:
INSERT INTO book_publisher89
VALUES( "Nuevo libro", "publisher")
La DBMS no conseguirá ejecutarla, devolviendo un error del tipo "No INSERT permission". El
motivo es que no es capaz de crear las líneas correspondientes a nuestro nuevo récord en las
dos tablas "reales" en las que se ha originado la vista (los problemas son varios: tiene que
crear sólo una línea en la tabla Book y conectarla a una línea concreta de la tabla Publisher, o
crear una línea en ambas tablas; cómo decidir qué valores darles a las llaves primarias de los
eventuales nuevos récords; qué valores darles a los otros campos de las dos tablas, etc...)
Gracias a las vistas (y a la asignación prudente de los permisos a los usuarios) es posible
conseguir que diferentes usuarios tengan una percepción de la estructura de la base de datos,
si bien muy diferentes de la que tiene realmente, e impedir que algunas categorías de usuarios
puedan acceder a informaciones que no les competen.
Por ejemplo, supongamos que contamos con una tabla en la que se han memorizado los datos
personales de los empleados de una empresa, así como las cantidades que conforman sus
respectivos sueldos. Obviamente, habría que evitar la consulta de los datos relativos a los
sueldos por parte de los usuarios, excepto quienes se tienen que ocupar de su
erogación/administración. Un sistema para hacerlo consiste en definir una vista que contenga
sólo las columnas de los datos personales. Así, todos los usuarios autorizados a acceder a
dichos datos, pero no a los de los sueldos, podrán entrar sólo a través de dicha vista. Ulteriores
particiones podrían hacerse en sentido horizontal, creando por ejemplo una vista que sólo
contenga las informaciones sobre los directivos y otra con los datos del resto de los
dependientes. Además, las vistas a menudo contribuyen a facilitar la independencia entre
aplicaciones y estructura de los datos, lo que hace que las bases de datos de los instrumentos
sean tan útiles. Efectivamente, si en un momento determinado fuese necesario cambiar la
estructura de la base de datos (descomponiendo, por ejemplo, una tabla en dos por motivos de
eficacia), no habría que modificar todas las aplicaciones adaptándolas a la nueva estructura,
sino que sería suficiente crear las vistas pertinentes, de modo que, desde el punto de vista de
las aplicaciones, nada haya cambiado.
http://www.htmlpoint.com/sql/sql_12.htm
Creación de vistas
Una vista es una tabla logica, que muestra una parte de la base de datos. Las vistas
permiten "almacenar" de manera logica los resultados de los queries.
La sintaxis para crear una vista es la siguiente:
CREATE [OR REPLACE] VIEW name [(alias1, alias2, . . . , aliasN)]
AS subquery
El uso de OR REPLACE permite sobreescribir una vista existente. Si se omite, y la vista
ya existe, se producirá, un error. El subquery representa un query escrito en SQL, a
partir del cual se obtendrá el contenido de la vista. Los aliases opcionales, permiten
asignarle nombres a las columnas de la vista. Si se omiten, las columnas tendrán el
mismo nombre que en las tablas originales (de donde se obtuvieron).
A continuación se presenta un ejemplo de creación de una vista
SQL> CREATE VIEW ComputerScience (employ_name, annual_salary)
1>
AS SELECT ename, sal*12
2>
FROM employee
3>
WHERE dpt_name = 'Computer Science'
4> ;
Esta vista mostrará el salario anual de todos los empleados del departamento de
Computer Science.
Si se modifica la información de alguna de las tablas base referenciadas por la vista, y
luego se ejecuta un query sobre la misma, la información que se obtendrá será la nueva.
Es decir, la información no se almacena en la vista, sino que se carga dinamicamente al
momento de efectuar alguna consulta.
Si se desea eliminar (borrar) una vista, se usa la instrucción:
SQL> DROP VIEW name;
http://www.bd.cesma.usb.ve/ci3391/manual/views.html
5.2 Instrucciones para la administración de vistas.
Unidad 6. Seguridad.
5.1 Esquemas de autorización.
5.2 Instrucciones GRANT y REVOKE.
REVOKE
La sentencia REVOKE permite que un usuario conectado y autentificado revoque los
privilegios de cifrado de un usuario existente.
Invocación
Esta sentencia puede utilizarse en un programa de aplicación utilizando las funciones de
CLI de DB2 o emitirse a través del CLP.
Sintaxis
>>-REVOKE--ENCRYPT ON DATABASE FROM--usuario-------------------><
Descripción
usuario
Identifica el usuario cuyos privilegios de cifrado se revocan.
Reglas



El parámetro de usuario debe ser un identificador delimitado. Tiene una longitud
limitada a 254 bytes.
Para caracteres de byte múltiple, internamente se utiliza la codificación UTF-8
para el almacenamiento. Por consiguiente, los nombres de usuario escritos
utilizando juegos de caracteres internacionales tienen una longitud limitada.
Si se eliminan todos los usuarios que tienen privilegios de cifrado, se puede
seguir accediendo a las tablas cifradas durante la sesión actual. Una vez que
finalice la sesión actual, las tablas cifradas dejarán de estar disponibles.
Notas



Para revocar privilegios de un usuario existente, un usuario debe estar conectado
y autentificado. Si es usted un usuario conectado y autentificado, puede revocar
privilegios de cualquier usuario, incluido usted mismo.
La sentencia REVOKE no se puede utilizar con marcadores de parámetros ni
con la función SQLPrepare().
Intentar conseguir los privilegios de REVOKE mientras se está conectado como
usuario no autorizado devuelve SQLSTATE 42502. Intentar revocar (REVOKE)
privilegios de un usuario inexistente da como resultado SQLSTATE 42501.
Ejemplo
El usuario conectado y autentificado actualmente elimina los privilegios de cifrado del
usuario "jsk":
REVOKE ENCRYPT ON DATABASE FROM "jsk"
http://www306.ibm.com/software/data/db2/everyplace/doc/infocenters/esp/dbeapr0811.ht
m
Garantizando Privilegios con GRANT
Para asignar un privilegio a un usuario o a un grupo, use el comando SQL GRANT. Aquí tiene la sintaxis de GRANT:
GRANT privilegio [, ...] ON objecto [, ...]
TO { PUBLIC | nombre_usuario | GROUP nombre_grupo }
En esta sintaxis, privilegio es cualquiera de los privilegios listados en la Tabla 10-2, objecto es el nombre del objeto de
base de datos (tabla, vista o secuencia) para el que es asignado el privilegio, y el elemento que sigue a la palabra clave
TO describe a quién es garantizado el privilegio. Se pueden indicar múltiples privilegios y objetos, separados los unos
de los otros mediante comas.
Sólo uno de los términos a continuación de TO pueden ser usados en un único estamento GRANT. El otorgamiento de
privilegios con la palabra clave PUBLIC indiscriminadamente garantiza el privilegio al objetivo especial "public". Los
privilegios PUBLIC son compartidos por todos los usuarios. Especificar un nombre de usuario garantiza el privilegio al
usuario especificado. Por el contrario, especificar un nombre de grupo garantiza el privilegio al grupo especificado.´
Supongamos, por ejemplo, que el usuario manager necesita todos los permisos para las tablas customers, books,
editions y publishers. El Ejemplo 10-17 da al usuario manager dichos privilegios, con un único estamento GRANT.
Ejemplo 10-17. Otorgando privilegios de usuario.
booktown=# GRANT ALL ON customers, books, editions, publishers
booktown-# TO manager;
CHANGE
El uso de la palabra clave ALL en el Ejemplo 10-17 otorga todos los posibles permisos ACL (SELECT, UPDATE, etc.) para
los objetos especificados al usuario manager. El mensaje CHANGE del servidor indica que los privilegios fueron
modificados con éxito. Recuerde que puede usar el comando rápido \z en psql para verificar los permisos establecidos
sobre un objeto de base de datos.
booktown=# \z publishers
Access permissions for database "booktown"
Relation
| Access permissions
------------+---------------------publishers | {"=","manager=arwR"}
(1 row)
Como otro ejemplo, veamos el uso de la palabra clave GROUP para otorgar privilegios a los miembros de un grupo. Por
ejemplo, todo el departamento de ventas (sales) Book Town debería tener permisos para ver la tabla customers, pero
no para modificarla. El Ejemplo 10-18 otorga privilegios SELECT sobre la tabla customers a cualquier miembro del grupo
sales.
Ejemplo 10-18. Otorgando privilegios de grupo.
booktown=# GRANT SELECT ON customers TO GROUP sales;
CHANGE
booktown=# \z customers
Access permissions for database "booktown"
Relation
| Access permissions
-----------+--------------------------------customers | {"=","manager=arwR","group sales=r"}
(1 row)
http://www.sobl.org/traducciones/practical-postgres/node74.html
Restringiendo Permisos con REVOKE
Por defecto, un usuario normal no tiene ningún privilegio sobre ningún objeto de la base de datos de la cual no es
propietario. Para revocar explícitamente un privilegio que actualmente está otorgado, el propietario del objeto (o un
superusuario) puede usar el comando REVOKE. Este comando es muy similar en formato al comando GRANT.
Aquí tiene su sintaxis:
REVOKE privilege [, ...] ON object [, ...]
FROM { PUBLIC | username | GROUP groupname }
La sintaxis de la estructura del comando REVOKE es idéntica a la del comando GRANT, con la excepción de que el
comando SQL es REVOKE en lugar de GRANT, y la palabra clave FROM es usada, en vez de la palabra clave TO.
Nota: La revocación de privilegios a PUBLIC sólo afecta al grupo especial ``public'', el cual incluye a todos los usuarios.
La revocación de privilegios para PUBLIC no afectará a ningún usuario a los que explícitamente se les hayan asignado
dichos privilegios.
Supongamos que los privilegios UPDATE sobre la tabla books han sido otorgados al usuario david. Cuando David es
transferido a otro departamento, y no necesita más la capacidad de modificar información en la tabla book, usted
debería revocar el privilegio UPDATE de David sobre la tabla de libros.
El Ejemplo 10-19 usa el comando rápido \z de psql para comprobar los permisos sobre la tabla de libros, revelando que
david tiene privilegios de escritura a dicha tabla. Un estamento REVOKE explícitamente revoca entonces los privilegios
UPDATE y DELETE sobre la tabla de libros para el usuario david. Finalmente, otra ejecución de \z es ejecutada para
verificar la revocación del privilegio.
Ejemplo 10-19. Revocando privilegios.
booktown=# \z books Access permissions for database "booktown"
Relation | Access permissions
----------+-------------------------------books
| {"=","manager=arwR","david=w"}
(1 row)
booktown=# REVOKE UPDATE, DELETE ON books
booktown-# FROM david;
CHANGE
booktown=# \z books
Access permissions for database "booktown"
Relation | Access permissions
----------+---------------------books
| {"=","manager=arwR"}
(1 row)
http://www.sobl.org/traducciones/practical-postgres/node75.html
Unidad 7. Introducción al SQL
Procedural.
7.1 Procedimientos almacenados.
Procedimientos almacenados
Un procedimiento almacenado es un conjunto de instrucciones en PL/SQL, que pueden
ser llamado usando el nombre que se le haya asignado.
La sintaxis para crear un procedimiento es la siguiente:
CREATE [OR REPLACE] PROCEDURE name [(param [IN|OUT|IN OUT|] datatype)
. . .]
[IS|AS] pl/sql_subprogram
El uso de OR REPLACE permite sobreescribir un procedimiento existente. Si se omite, y
el procedimiento ya existe, se producirá un error. Los modificadores IN, OUT, IN OUT
indican si el parametro es de entrada, salida o ambos.
A continuación se presenta un ejemplo de creación de un procedimiento:
SQL> CREATE PROCEDURE credit (acc_no IN NUMBER, amount IN NUMBER)
1>
AS BEGIN
2>
UPDATE accounts
3>
SET balance = balance + amount
4>
WHERE account_id = acc_no;
5>
END;
Este procedimiento actualizará la(s) tupla(s) con numero de cuenta igual al parámetro
acc_no con un incremento de amount en el balance de dicha cuenta.
Si se desea eliminar (borrar) un procedimiento almacenado, se usa la instrucción:
SQL> DROP PROCEDURE name;
http://www.bd.cesma.usb.ve/ci3391/manual/procedures.html
Procedimientos almacenados
Un procedimiento almacenado es un conjunto de instrucciones en PL/SQL, que pueden ser llamado
usando el nombre que se le haya asignado.
La sintaxis para crear un procedimiento es la siguiente:
CREATE [OR REPLACE] PROCEDURE name [(param [IN|OUT|IN OUT|] datatype) . . .]
[IS|AS] pl/sql_subprogram
El uso de OR REPLACE permite sobreescribir un procedimiento existente. Si se omite, y el procedimiento
ya existe, se producirá un error. Los modificadores IN, OUT, IN OUT indican si el parametro es de
entrada, salida o ambos.
A continuación se presenta un ejemplo de creación de un procedimiento:
SQL> CREATE PROCEDURE credit (acc_no IN NUMBER, amount IN NUMBER)
1> AS BEGIN
2> UPDATE accounts
3> SET balance = balance + amount
4> WHERE account_id = acc_no;
5> END;
Este procedimiento actualizará la(s) tupla(s) con numero de cuenta igual al parámetro acc_no con un
incremento de amount en el balance de dicha cuenta.
Si se desea eliminar (borrar) un procedimiento almacenado, se usa la instrucción:
SQL> DROP PROCEDURE name;
http://www.programatium.com/manuales/oracle/9.htm
Gestor de procedimientos almacenados
Por Pedro Pozo
CLIKEAR.COM
Normal
Calificar
Introducción
Mi Panorama
SOS
Los procedimientos almacenados es uno de las funcionalidades mas
Escribe para Nosostros
útiles y mas utilizadas de SQL Server, incluso para una aplicación
diseñada con N capas todas las consultas a la base de datos se suelen
hacer con procedimientos almacenados.
Para hacer una llamada a un procedimiento almacenado desde una aplicación .NET hay que escribir
bastante código especialmente si se trata de un procedimiento almacenado con muchos parámetros.
Para agilizar la programación y hacer más rápida la llamada a procedimientos almacenados de SQL he
realizado una clase a la que he llamado ClassExecSpSql que esta desarrollada en C#.
Esta clase sirve para ejecutar cualquier procedimiento almacenado, de forma que con tan solo poner el
nombre del procedimiento almacenado y los nombres de los parámetros ya se ejecutaran el mismo,
reduciendo así notablemente la cantidad de código a escribir.
Si tratamos de llamar a un procedimiento almacenado con C# deberemos de escribir bastantes líneas de
código dependiendo del numero de parámetros, por ejemplo:
SqlParameter workParm;
CommandSP = new SqlCommand(Procedure,myConnection);
CommandSP.CommandType= CommandType.StoredProcedure;
CommandSP.Parameters.Add(NombreParametro1,Valor1);
...
CommandSP.Parameters.Add(NombreParametroN,ValorN);
workParm.Direction = ParameterDirection.Output;
DataSet myDataSet = new DataSet();
mySqlDataAdapter = new SqlDataAdapter(CommandSP);
mySqlDataAdapter.Fill(myDataSet);
Si pensamos que en una aplicación puede haber cientos de llamadas a procedimientos almacenados, la
cantidad de código a escribir y mantener puede llegar a ser muy considerable.
Para reducir esta cantidad de código podemos escribir una clase que gestione la llamada a los
procedimientos almacenados, en este caso la clase ClassExecSpSql la cual tiene los siguientes métodos y
propiedades:

ConnectionString – Propiedad de lectura/escritura que contiene la cadena de conexión al
servidor de base de datos SQL Server.

ExecuteSpXml(string Procedure,params object[] Parameters) – Método que ejecuta un
procedimiento almacenado que contiene una consulta de selección. Se le deben pasar los
parámetros Procedure que es el nombre del procedimiento almacenado y Parameters que es un
numero indeterminado de parámetros del procedimiento almacenado y devuelve el resultado de la
consulta en XML.

ExecuteSpDataset(string Procedure,params object[] Parameters) – Método que ejecuta un
procedimiento almacenado que contiene una consulta de selección. Se le deben pasar los
parámetros Procedure que es el nombre del procedimiento almacenado y Parameters que es un
numero indeterminado de parámetros del procedimiento almacenado y devuelve el resultado de la
consulta en un dataset.

ExecuteSpNonQuery(string Procedure,params object[] Parameters) – Método que ejecuta un
procedimiento almacenado que contiene una consulta de actualización. Se le deben pasar los
parámetros Procedure que es el nombre del procedimiento almacenado y Parameters que es un
numero indeterminado de parámetros del procedimiento almacenado y devuelve true si el
procedimiento almacenado se ha ejecutado con éxito o false en caso contrario.
Utilizando esta clase para gestionar las llamadas a las procedimientos almacenados se conseguirá
ahorrar gran cantidad de código a escribir y mantener, y se tendrá centralizado en tan solo una clase la
llamadas a los procedimientos almacenados de toda la aplicación.
Podemos comprobar en este ejemplo como hemos pasado del código anterior a tan solo dos líneas para
llamar al procedimiento almacenado.
ClassExecSpSql miEjecutorSQL=new ClassExecSpSql();
myDataSet=miEjecutorSQL.ExecuteSpDataset(txtSpNameQuery.Text,txtParamQ
uery.Text);
Para conocer los parámetros del procedimiento almacenado se hace una consulta a las tablas de sistema
de SQL Server, estas tablas de sistema son una fuente completa de información sobre nuestra base de
datos SQL Server, son tablas intuitivas y fáciles de comprender pero que además vienen perfectamente
documentadas en la ayuda de SQL Server y que nos ayudaran muchísimo si queremos realizar clases
genéricas que nos sirvan para cualquier base de datos.
Consultando a las tablas del sistema podemos conocer las tablas de una base de datos, los campos de
cada tabla con sus tipos de datos, los procedimientos almacenados, los parámetros de los
procedimientos almacenados, etc ...
En estas tablas esta toda la información relativa a las bases de datos de SQL Server y puede ser
fácilmente utilizada para realizar procesos genéricos que pueden ser reutilizados para cualquier base de
datos de SQL Server.
Para la clase ClassExecSpSql se ha realizado una consulta a las tablas del sistema para conocer los
parámetros de un procedimiento almacenado y cual es el tipo de datos de cada uno de los parámetros.
La consulta es la siguiente:
Select
syscolumns.name,syscolumns.xtype,syscolumns.prec,syscolumns.isoutparam
from syscolumns,sysobjects where (sysobjects.id=syscolumns.id) and
(sysobjects.name='" + Procedure + "'
Además se ha incluido un control de errores que guardará las posibles incidencias en el visor de sucesos
de Windows, que gracias al lenguaje C# se realiza de forma sencilla con tan solo unas líneas de código
como por ejemplo
string comment="";
comment=e.Source;
comment+=". "+e.Message;
comment+=". "+e.StackTrace;
EventLog aLog = new EventLog();
aLog.Log="Application";
aLog.Source="ExecSpSql";
aLog.WriteEntry(comment,System.Diagnostics.EventLogEntryType.Error);
Este control de errores puede ser modificado o mejorado pero cabe destacar la facilidad que ofrece el
lenguaje C# para realizar este tipo de procesos con tan solo unas líneas de código.
http://www.microsoft.com/spanish/msdn/articulos/archivo/221102/voices/gestor.asp
7.2 Disparadores (Triggers).
Triggers
Un trigger es un bloque PL/SQL asociado a una tabla, que se ejecuta cuando una
determinada instrucción en SQL se va a ejecutar sobre dicha tabla.
La sintaxis para crear un trigger es la siguiente:
CREATE [OR REPLACE] TRIGGER
{BEFORE|AFTER} {DELETE|INSERT|UPDATE [OF col1, col2, . . ., colN]
[OR {DELETE|INSERT|UPDATE [OF col1, col2, . . ., colN].
. .]}
ON table
[REFERENCING OLD AS oldname, NEW as newname]
[FOR EACH ROW [WHEN (condition)]]
pl/sql_block
El uso de OR REPLACE permite sobreescribir un trigger existente. Si se omite, y el
trigger existe, se producirá, un error.
El modificador FOR EACH ROW indica que el trigger se disparará cada vez
que se desee hacer operaciones sobre una fila de la tabla. Si se
acompaña del modificador WHEN, se establece una restricción; el
trigger solo actuará, sobre las filas que satisfagan la restricción.
A continuación se presenta un ejemplo de creación de un trigger:
SQL> CREATE TRIGGER salary_check
1> BEFORE
2> INSERT OR UPDATE OF sal, job
3> ON employee
4> FOR EACH ROW
5> WHEN (new.job <> 'PRESIDENT')
6> DECLARE
7>
minsal
NUMBER
8>
maxsal
NUMBER
9> BEGIN
10>
/* Se obtienen los valores minimo y maximo para el salario de
*/
11>
/* un cargo determinado, usando la tabla sal_guide
*/
12>
SELECT minsal, maxsal
13>
INTO minsal, maxsal
14>
FROM sal_guide
15>
WHERE job = :new.job
16>
/* Si el salario del empleado a insertar/modificar esta por */
17>
/* debajo del minimo, o por encima del maximo, se genera
*/
19>
/* un error.
*/
20>
IF (:new.sal < minsal OR :new.sal > maxsal)
21>
THEN raise_application_error(-20601, 'Salary '||:new.sal||
22>
' out of range for job '||:new.job||' for employee '||
23>
:new.ename);
24>
END IF;
25 > END;
Este trigger impide que se agregue o modifique un empleado con el
sueldo mayor o menor que los valores maximo y minimo respectivamente
para su cargo. Se agrega la restricción de que el trigger no se
dispararán si el cargo es PRESIDENTE.
Si se desea eliminar (borrar) un trigger, se usa la instrucción:
SQL> DROP TRIGGER name;
http://www.bd.cesma.usb.ve/ci3391/manual/triggers.html
Triggers (disparadores)
Postgres tiene algunas interfaces cliente como Perl, Tcl, Python y C, así como dos
Lenguajes Procedurales (PL). También es posible llamar a funciones C como acciones
trigger. Notar que los eventos trigger a nivel STATEMENT no están soportados en la
versión actual. Actualmente es posible especificar BEFORE o AFTER en los INSERT,
DELETE o UPDATE de un registro como un evento trigger.
Creación de Triggers
Si un evento trigger ocurre, el administrador de triggers (llamado Ejecutor) inicializa la
estructura global TriggerData *CurrentTriggerData (descrita más abajo) y llama a la
función trigger para procesar el evento.
La función trigger debe ser creada antes que el trigger, y debe hacerse como una función
sin argumentos, y códigos de retorno opacos.
La sintaxis para la creación de triggers es la siguiente:
CREATE TRIGGER <trigger name> <BEFORE|AFTER> <INSERT|DELETE|UPDATE>
ON <relation name> FOR EACH <ROW|STATEMENT>
EXECUTE PROCEDURE <procedure name> (<function args>);
El nombre del trigger se usará si se desea eliminar el trigger. Se usa como argumento
del comando DROP TRIGGER.
La palabra siguiente determina si la función debe ser llamada antes (BEFORE) o
después (AFTER) del evento.
El siguiente elemento del comando determina en que evento/s será llamada la función.
Es posible especificar múltiples eventos utilizado el operador OR.
El nombre de la relación (relation name) determinará la tabla afectada por el evento.
La instrucción FOR EACH determina si el trigger se ejecutará para cada fila afectada o
bien antes (o después) de que la secuencia se haya completado.
El nombre del procedimiento (procedure name) es la función C llamada.
Los argumentos son pasados a la función en la estructura CurrentTriggerData. El
propósito de pasar los argumentos a la función es permitir a triggers diferentes con
requisitos similares llamar a la misma función.
Además, la función puede ser utilizada para disparar distintas relaciones (estas
funciones son llamadas "general trigger funcions").
Como ejemplo de utilización de lo descrito, se puede hacer una función general que
toma como argumentos dos nombres de campo e inserta el nombre del usuario y la
fecha (timestamp) actuales en ellos. Esto permite, por ejemplo, utilizar los triggers en
los eventos INSERT para realizar un seguimiento automático de la creación de registros
en una tabla de transacciones. Se podría utilizar también para registrar actualizaciones si
es utilizado en un evento UPDATE.
Las funciones trigger retornan un área de tuplas (HeapTuple) al ejecutor. Esto es
ignorado para trigger lanzados tras (AFTER) una operación INSERT, DELETE o
UPDATE, pero permite lo siguiente a los triggers BEFORE: - retornar NULL e ignorar
la operación para la tupla actual (y de este modo la tupla no será
insertada/actualizada/borrada); - devolver un puntero a otra tupla (solo en eventos
INSERT y UPDATE) que serán insertados (como la nueva versión de la tupla
actualizada en caso de UPDATE) en lugar de la tupla original.
Notar que no hay inicialización por parte del CREATE TRIGGER handler. Esto será
cambiado en el futuro. Además, si más de un trigger es definido para el mismo evento
en la misma relación, el orden de ejecución de los triggers es impredecible. Esto puede
ser cambiado en el futuro.
Si una función trigger ejecuta consultas SQL (utilizando SPI) entonces estas funciones
pueden disparar nuevos triggers. Esto es conocido como triggers en cascada. No hay
ninguna limitación explicita en cuanto al número de niveles de cascada.
Si un trigger es lanzado por un INSERT e inserta una nueva tupla en la misma relación,
el trigger será llamado de nuevo (por el nuevo INSERT). Actualmente, no se
proporciona ningún mecanismo de sincronización (etc) para estos casos pero esto puede
cambiar. Por el momento, existe una función llamada funny_dup17() en los tests de
regresión que utiliza algunas técnicas para parar la recursividad (cascada) en si misma...
http://www.guug.org/LuCAS/Postgresql-es/web/navegable/programmer/triggers.html
Interacción con el Trigger Manager
Como se ha mencionado, cuando una función es llamada por el administrador de
triggers (trigger manager), la estructura TriggerData *CurrentTriggerData no es NULL
y se inicializa. Por lo cual es mejor verificar que CurrentTriggerData no sea NULL al
principio y asignar el valor NULL justo después de obtener la información para evitar
llamadas a la función trigger que no procedan del administrador de triggers.
La estructura TriggerData se define en src/include/commands/trigger.h:
typedef struct TriggerData
{
TriggerEvent
tg_event;
Relation
tg_relation;
HeapTuple
tg_trigtuple;
HeapTuple
tg_newtuple;
Trigger
*tg_trigger;
} TriggerData;
tg_event
describe los eventos para los que la función es llamada. Puede
utilizar
las siguientes macros para examinar tg_event:
TRIGGER_FIRED_BEFORE(event) devuelve TRUE si el trigger se disparó
antes;
TRIGGER_FIRED_AFTER(event) devuelve TRUE si se disparó después;
TRIGGER_FIRED_FOR_ROW(event) devuelve TRUE si el trigger se disparó
para un
evento a nivel de fila;
TRIGGER_FIRED_FOR_STATEMENT(event) devuelve TRUE si el trigger se
disparó
para un evento a nivel de sentencia.
TRIGGER_FIRED_BY_INSERT(event) devuelve TRUE si fue disparado por
un INSERT;
TRIGGER_FIRED_BY_DELETE(event) devuelve TRUE si fue disparado por
un DELETE;
TRIGGER_FIRED_BY_UPDATE(event) devuelve TRUE si fue disparado por
un UPDATE.
tg_relation
es un puntero a una estructura que describe la relación
disparadora. Mirar
en src/include/utils/rel.h para ver detalles sobre esta estructura.
Lo más
interesante es tg_relation->rd_att (descriptor de las tuplas de la
relación)
y tg_relation->rd_rel->relname (nombre de la relación. No es un
char*, sino
NameData. Utilizar SPI_getrelname(tg_relation) para obtener char*
si se
necesita una copia del nombre).
tg_trigtuple
es un puntero a la tupla por la que
es, la
tupla que se está insertando (en un
actualizando (UPDATE).
En caso de un INSERT/DELETE esto es
Ejecutor si
no se desea reemplazar la tupla con
operación.
es disparado el trigger, esto
INSERT), borrando (DELETE) o
lo que se debe devolver al
otra (INSERT) o ignorar la
tg_newtuple
es un puntero a la nueva tupla en caso de UPDATE y NULL si es para
un INSERT
o un DELETE. Esto es lo que debe devolverse al Ejecutor en el caso
de un
UPDATE si no se desea reemplazar la tupla por otra o ignorar la
operación.
tg_trigger
es un puntero a la estructura Trigger definida en
src/include/utils/rel.h:
typedef struct Trigger
{
Oid
tgoid;
char
*tgname;
Oid
tgfoid;
FmgrInfo
tgfunc;
int16
tgtype;
bool
tgenabled;
bool
tgisconstraint;
bool
tgdeferrable;
bool
tginitdeferred;
int16
tgnargs;
int16
tgattr[FUNC_MAX_ARGS];
char
**tgargs;
} Trigger;
tgname es el nombre del trigger, tgnargs es el número de argumentos
en
tgargs,
tgargs es un array de punteros a los argumentos especificados en el
CREATE
TRIGGER. Otros miembros son exclusivamente para uso interno.
http://www.guug.org/LuCAS/Postgresql-es/web/navegable/programmer/x2014.html
Documentos relacionados
Descargar