Instituto Tecnológico de Tuxtla Gutierez

BUSCADOR

en Web en Blog

lunes, 10 de octubre de 2011

2.3 Creación de Indices

INDICE:

Un indice es una estructura interna que el sistema puede usar para encontrar 1 o mas registros en una tabla de forma rapida,un indice de Base de Datos se crea para una columna o grupo de columnas, un indice de Base de Datos se crea para una columna o grupo de columnas. A un indice se le asigna un nombre de acuerdo con las mismas reglas que se aplican para los nombres de tablas[1].

Los índices son "estructuras" alternativa a la organización de los datos en una tabla. El propósito de los índices es acelerar el acceso a los datos mediante operaciones físicas más rápidas y efectivas. Para enterder mejor la importancia de un índice pongamos un ejemplo; imagínate que tienes delante las páginas amarillas, y deseas buscar el teléfono de Manuel Salazar que vive en Alicante. Lo que harás será buscar en ese pezado libro la población Alicante, y guiandote por la cabecera de las páginas buscarás los apellidos que empiezan por S de Salazar. De esa forma localizarás más rápido el apellido Salazar. Pues bien, enhorabuena, has estado usando un índice.
Pues el objetivo de definir índices en SQL Server es exáctamente para conseguir el mismo objetivo: acceder más rápido a los datos. Además SQL Server tiene dos tipos de índices que analizaremos a continuación[2].  

¿Por qué usar Índices?
  • Mayor velocidad para localizar datos
  • Reforzar la identificación única
Arquitectura de los Índices
  • Es un conjunto de páginas distribuidas en un árbol B.
  • Cada página mide 8kb = 8192 bytes, con un encabezado de 96b, dejando 8096b para datos.
  • SQL Server accesa al Disco Duro por pagina
  • En la Tabla “Sys indexes” se encuentra un puntero a la pagina raíz.

Sintaxis
Create índex nom_indice
On
nom_tabla (columnas(s))

Ejemplo
Create índex idxclave
On
clientes (Clave)[1]
Más informacion acerca de :

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:
índiceEs el nombre del índice a crear.
tablaEs el nombre de una tabla existente en la que se creará el índice.
campoEs el nombre del campo o lista de campos que constituyen el índice.
ASC|DESCIndica el orden de los valores de los campos ASC indica un orden ascendente (valor predeterminado) y DESC un orden descendente.
UNIQUEIndica que el índice no puede contener valores duplicados.
DISALLOW NULLProhibe valores nulos en el índice
IGNORE NULLExcluye del índice los valores nulos incluidos en los campos que lo componen.
PRIMARYAsigna 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[3].


Índices no-agrupados



  • Los índices no agrupados tienen la misma estructura de árbol b que los índices agrupados, con algunos matices; como hemos visto antes, en los índices agrupados, en el último nivel del índice (nivel de hoja) están los datos; en los índices no-agrupados, en el nivel de hoja del índice, hay un puntero a la localización física de la fila correspondiente en el índice agrupado. Además, la ordenación de las filas del índice está construida en base a la(s) columna(s) indexadas, lo cual no quiere decir (a diferencia de los índices agrupados), que la organización física de las páginas de datos corresponda con el índice.

    Consideraciones para usar índices agrupados

  • Columnas con datos muy selectivos
  • Consultas que no devuelven muchas filas.
  • Columnas en WHERE.
  • Evitar acceso a páginas de datos realizando el acceso sólo por el índice.
  • Covered queries (consultas cubiertas).
    En SQL Server 2005, son nuevos los índices INCLUDE que son índices no-agrupados que en el nivel de hoja del índice (donde está el puntero al índice agrupado), se puede incluir más columnas; el objetivo de este nuevo tipo de índices es beneficiar el uso de las consultar cubiertas para evitar que se acceda a la página de datos del índice agrupado[2].
Los índices -como los índices de los libros- sirven para agilizar las consultas a las tablas, evitando que mysql tenga que revisar todos los datos disponibles para devolver el resultado.
Podemos crear el índice a la vez que creamos la tabla, usando la palabra INDEX seguida del nombre del índice a crear y columnas a indexar (que pueden ser varias):
INDEX nombre_indice (columna_indexada, columna_indexada2...)


La sintaxis es ligeramente distinta segun la clase de índice: 
 
PRIMARY KEY (nombre_columna_1 [,nombre_columna2...])
UNIQUE INDEX nombre_indice (columna_indexada1 [,columna_indexada2 ...])
INDEX nombre_index (columna_indexada1 [,columna_indexada2...]) 
Podemos también añadirlos a una tabla después de creada:
ALTER TABLE nombre_tabla ADD INDEX nombre_indice (columna_indexada);

Si queremos eliminar un índice: ALTER TABLE tabla_nombre DROP INDEX nombre_indice¿para que sirven ?
LOs index permiten mayor rápidez en la ejecución de las consultas a la base de datos tipo SELECT ... WHERE

La regla básica es pues crear tus índices sobre aquellas columnas que vayas a usar con una cláusula WHERE, y no crearlos con aquellas columnas que vayan a ser objeto de un SELECT: SELECT texto from tabla_libros WHERE autor = Vazquez; En este ejemplo, la de autor es una columna buena candidata a un indice; la de texto, no.

Otra regla básica es que son mejores candidatas a indexar aquellas columnas que presentan muchos valores distintos, mientras que no son buenas candidatas las que tienen muchos valores idénticos, como por ejemplo sexo (masculino y femenino) porque cada consulta implicará siempre recorrer practicamente la mitad del indice.
La regla de la izquierda Si necesitamos un select del tipo SELECT ... WHERE columna_1 = X AND columna_2 = Y y ya tenemos un INDEX con la columna_1, podemos crear un segundo indice con la columna 2, o mejor todavía, crear un único indice combinado con las columnas 1 y 2. Estos son los índices multicolumna, o compuestos.
No obstante si tienes indices multicolumna y los utilizas en las clausulas WHERE, debes incluir siempre de izquierda a derecha las columnas indexadas; o el indice NO se usará:
Supongamos un INDEX usuario (id, name, adress), y una cláusula SELECT ... WHERE NAME = x. Este Select no aprovechará el índice. Tampoco lo haría un SELECT ... WHERE ID =X AND ADRESS = Y. Cualquier consulta que incluya una columna parte del index sin incluir además las columnas a su izquierda, no usará el indice.

Por tanto en nuestro ejemplo solo sacarian provecho del indice las consultas SELECT ... WHERE ID = x, o WHERE ID = X AND NAME = y o WHERE ID = x AND NAME = y AND ADRESS = Z
Cuando un índice contiene mas de una columna, cada columna es leida por el orden que ocupa de izquierda a derecha, y a efectos prácticos, cada columna (por ese orden) es como si constituyera su propio índice. Esto significa que en el ejemplo anterior, no haría falta crear otro INDEX ID (id) ya que podríamos usar nuestro INDEX USUARIO simplemente con la cláusula SELECT ... WHERE ID = X;
Puedes ver si tu llamada sql usa o no los índices correctos anteponiendo a select la orden explain:
EXPLAIN SELECT * FROM mitable WHERE ....
Y para ser sinceros, usando explain para comprobar el uso de indices en distintos selects con indices multicolumna, he obtenido resultados poco consistentes con la 'regla de la izquierda' ya que en muchos casos parece que se usaban indices que teóricamente no debian estar disponibles ... posiblemente un caso de mala configuracion en mi tabla-test.


Tipos de indice

En algunas bases de datos existen diferencias entre KEY e INDEX. No así en MySQL donde son sinónimos.
 
Un índice que sí es especial es el llamado PRIMARY KEY. Se trata de un índice diseñado para consultas especialmente rápidas. Todos sus campos deben ser UNICOS y no admite NULL.
Un indice UNIQUE es aquel que no permite almacenar dos valores iguales.

Los indices FULL TEXT permiten realizar búsquedas de palabras. Puedes crear indices FULLTEXT sobre columnas tipo CHAR, VARCHAR o TEXT.

Una vez creado puedes hacer búsquedas del tipo:

SELECT * FROM nombre_tabla WHERE MATCH(nombre_indice_fulltext) AGAINST('palabra_a_buscar');


Algunas limitaciones de los indices fulltext: solo busca por palabras completas. indice no encontrará indices. No se indexan las palabras de menos de cuatro letras. No se indexan columnas que contengan menos de tres filas, ni palabras que aparezcan en la mitad o mas de las filas. Las palabras separadas por guiones se cuentan como dos palabras.
Los indices ordinarios no tienen restricciones en cuanto a la existencia de valores idénticos o nulos. Una posibilidad interesante, si pensamos crear un índice sobre columnas CHAR y VARCHAR es la de limitar el campo a indexar. Por ejemplo, cada entrada en la columna puede ser de hasta 40 caracteres y nosotros indexar unicamente los primeros 10 de cada una. Para crear estos índices basta con indicar entre paréntesis el numero de caracteres a indexar despues del nombre de la columna:
ALTER TABLE libros ADD INDEX idx_autor(nombre(10), apellidos(10));
 
 Desventajas de los indices Los índices se actualizan cada vez que se modifica la columna o columnas que utiliza. Por ello no es aconsejable usar como indices columnas en las que serán frecuentes operaciones de escritura (INSERT, UPDATE, DELETE).

Tampoco tendría sentido crear indices sobre columnas cuando cualquier select sobre ellos va a devolver una gran cantidad de resultados; por ejemplo una columna booleana que admita los valores Y/N. En fin, tampoco es necesario usar indices en tablas demasiado pequeñas, ya que en estos casos no hay ganancia de rapidez frente a una consulta normal.
Finalmente, los índices ocupan espacio. A veces, incluso mas que la tabla de datos[4].




Referencias

[1]  http://sistemas.itlp.edu.mx/tutoriales/tallerdebasesdedatos/t23.htm
[2] http://www.zonacodigos.com/index.php/sql/59-creacion-de-indices 
[3] http://www.mailxmail.com/curso-sql/creacion-indices
[4] http://www.webtaller.com/construccion/lenguajes/mysql/lecciones/indices-mysql-2.php



2.3 Resumen Creacion de índices

Indice:

Una estructura de datos que permite localizar registros dentro de un archivo.

Indice de una Base de Datos: 
Es una estructura secundaria  usada para aumentar la velocidad en la recuperación
de los datos bajo ciertas condiciones de búsqueda.

Existen 3 tipos de índices:
*Índices de luster: almacenan los valores de clave de cluster en clusters.
Cluster:
Es un objeto que contiene datos de una o más tablas, de las cuales tienen una o más columnas comunes.
 
*Índices de Tabla: almacena los valores de las filas de una tabla junto con la ubicación física de la fila, es decir, su RowId (valor clave).
*Índices de Mapa de Bits: tipo especial de índice de tabla diseñado para dar soporte a consultas de tablas de gran tamaño.
 
Elementos de un índice
Cada elemento del índice, es denominado entrada de datos del índice. Consta de un valor clave de  un identificador de fila.   
El valor clave, es el valor de una columna o la combinación de varias columnas.
Las entradas de datos del índice se almacenan mediante un mecanismo de árbol B+.
 Una estructura de árbol-B+ consiste en repartir los valores del índice sobre un bloque raíz, unos bloques intermedios y unos bloques hojas. 
El bloque raíz y los intermedios contienen las direcciones de los otros bloques y los valores del índice.
Los bloques hoja contienen todos los valores del índice, y con cada valor del índice el Rowld (valor clave)de la línea que contiene el valor del índice.

CREATE [ UNIQUE ] INDEX índice
  ON tabla (campo [ASC|DESC][, campo [ASC|DESC], ...])
  [WITH { PRIMARY | DISALLOW NULL | IGNORE NULL }

 
UNIQUE: indica que se trata de un índice único, no admite más de una tupla con el mismo valor en los atributos que forman el índice.
Cuando se crea una tabla con clave primaria, automáticamente se crea un índice  único.

 
 
 
 
 
 
 
 


 

martes, 4 de octubre de 2011

2.2.1 Integridad, Integridad Refencial declarativa

2.2.1 Integridad.
Se refiere a las medidas de salvaguardar, que se incluyen en un sistema de información para evitar la pérdida accidental de los datos.

Primero repasemos un poco los tipos de relaciones.

Tipos de relaciones.
 
Entre dos tablas de cualquier base de datos relacional pueden haber dos tipos de relaciones, relaciones uno a uno y relaciones uno a muchos:
Relación Uno a Uno: Cuando un registro de una tabla sólo puede estar relacionado con un único registro de la otra tabla y viceversa.
Por ejemplo: tenemos dos tablas una de profesores y otra de departamentos y queremos saber qué profesor es jefe de qué departamento, tenemos una relación uno a uno entre las dos tablas ya que un departamento tiene un solo jefe y un profesor puede ser jefe de un solo departamento.
Relación Uno a Varios: Cuando un registro de una tabla (tabla secundaria) sólo puede estar relacionado con un único registro de la otra tabla (tabla principal) y un registro de la tabla principal puede tener más de un registro relacionado en la tabla secundaria, en este caso se suele hacer referencia a la tabla principal como tabla 'padre' y a la tabla secundaria como tabla 'hijo', entonces la regla se convierte en 'un padre puede tener varios hijos pero un hijo solo tiene un padre (regla más fácil de recordar).
Por ejemplo: tenemos dos tablas una con los datos de diferentes poblaciones y otra con los habitantes, una población puede tener más de un habitante, pero un habitante pertenecerá (estará empadronado) en una única población. En este caso la tabla principal será la de poblaciones y la tabla secundaria será la de habitantes. Una población puede tener varios habitantes pero un habitante pertenece a una sola población. Esta relación se representa incluyendo en la tabla 'hijo' una columna que se corresponde con la clave principal de la tabla 'padre', esta columna es lo denominamos clave foránea (o clave ajena o clave externa).
Una clave foránea es pues un campo de una tabla que contiene una referencia a un registro de otra tabla. Siguiendo nuestro ejemplo en la tabla habitantes tenemos una columna población que contiene el código de la población en la que está empadronado el habitante, esta columna es clave ajena de la tabla habitantes, y en la tabla poblaciones tenemos una columna codigo de poblacion clave principal de la tabla.

 
  Relación Varios a Varios: Cuando un registro de una tabla puede estar relacionado con más de un registro de la otra tabla y viceversa. En este caso las dos tablas no pueden estar relacionadas directamente, se tiene que añadir una tabla entre las dos que incluya los pares de valores relacionados entre sí.
Por ejemplo: tenemos dos tablas una con los datos de clientes y otra con los artículos que se venden en la empresa, un cliente podrá realizar un pedido con varios artículos, y un artículo podrá ser vendido a más de un cliente.
No se puede definir entre clientes y artículos, hace falta otra tabla (por ejemplo una tabla de pedidos) relacionada con clientes y con artículos. La tabla pedidos estará relacionada con cliente por una relación uno a muchos y también estará relacionada con artículos por un relación uno a muchos.

Cuando se define una columna como clave foránea, las filas de la tabla pueden contener en esa columna o bien el valor nulo (ningún valor), o bien un valor que existe en la otra tabla, un error sería asignar a un habitante una población que no está en la tabla de poblaciones. Eso es lo que se denomina integridad referencial y consiste en que los datos que referencian otros (claves foráneas) deben ser correctos. La integridad referencial hace que el sistema gestor de la base de datos se asegure de que no hayan en las claves foráneas valores que no estén en la tabla principal.
La integridad referencial se activa en cuanto creamos una clave foránea y a partir de ese momento se comprueba cada vez que se modifiquen datos que puedan alterarla.[1]









 
2.2.2 Integridad referencial declarativa.

La integridad referencial es un sistema de reglas que utilizan la mayoría de las bases de datos relacionales para asegurarse que los registros de tablas relacionadas son válidos y que no se borren o cambien datos relacionados de forma accidental produciendo errores de integridad. [1]

La integridad de los datos es la propiedad que asegura que información dada es correcta, al cumplir ciertas aserciones.
Las restricciones de integridad aseguran que la información contenida en una base de datos es correcta.
Las restricciones de integridad son propiedades de la base de datos que se deben satisfacer en cualquier momento.
Oracle es un sistema de gestión de base de datos (SGBD) relacional que permite la definición de restricciones de integridad dentro del diseño de su base de datos al ser creada.
Las restricciones de integridad aseguran que la información contenida en la base de datos cumple ciertas restricciones para los diferentes estados.
Existen dos tipos de restricciones:
  • Estáticas: limitan los estados permitidos de la Base de Datos.
  • Dinámicas:  restringen las posibles transiciones de estados de la base datos.
Para incorporar el tratamiento de las restricciones de integridad en el sistema pueden realizarse:
  • Añadiendo código adicional para verificar y asegurar que se cumplen las restricciones.
  • Declarando las restricciones como parte del esquema de la base de datos.
La definición en la fase de diseño de las restricciones de integridad proporciona mayor número de ventajas, ya que:
  • Reduce el costo de desarrollo de software.
  • Es más confiable al ser centralizado y uniforme.
  • Mantenimiento más fácil.
De acuerdo con la forma de especificación del comando CREATE TABLE dada anteriormente, la cláusula <table_constraint> puede entonces tener las siguientes formas:
CONSTRAINT <constraint_name> PRIMARY KEY (>[,>])
CONSTRAINT <constraint_name> UNIQUE ([,])
CONSTRAINT <constraint_name> FOREIGN KEY (<column_name>[,<column_name>]) REFERENCES <table_name>
CONSTRAINT <constraint_name> CHECK (<condition>)
Donde:
es el nombre con el que se designará al “constraint" en el esquema donde se crea la tabla que lo incluye.
es el nombre de una columna de la tabla en la que se define el “constraint"
1
<table_name> es el nombre de una tabla definida en el esquema donde existe la tabla que incluye el “constraint".
<condition> es una expresión lógica de SQL.[2]


Referencias 
[1] http://www.aulaclic.es/sql/b_8_1_1.htm
[2] http://www.paginasprodigy.com.mx/evaristopacheco/taller/integridadReferencialDeclarativa.html

2.2.1,2 Resumen -- Integridad , Integridad referencial declarativa

2.2.1 Integridad


Se refiere a las medidas de salvaguardar, que se  incluyen en un sistema de información para evitar la pérdida accidental de los datos.
Asegurar que la información no es alterada sin autorización



Integridad de datos en bases de datos: Integridad de datos se refiere al estado de corrrección y completidud de los datos ingreados en una base de datos.
La SGBD relacional deben encargarse de mantener la integridad de los datos almacenados en una base de datos con respecto a las reglas predefinidas o restricciones. La integridad también puede verificarse inmediatamente antes del momento de introducir los datos a la base de datos (por ejemplo, en un formulario empleando validación de datos).
Un claro ejemplo de error de integridad es el ingreso de un tipo de dato incorrecto dentro de un campo.
Por ejemplo, ingresar un texto cuando se espera un número entero.


Tipos de restricciones.
 
*Estáticas: limitan los estados permitidos de la Base de Datos.
-las más importantes son las que afectan a las claves primarias.
“Ninguna de las partes que componen una clave primaria puede ser NULL
-Las modificaciones de claves primarias deben estar muy bien controladas.
*Dinámicas:  restringen las posibles transiciones de estados de la base datos.
 
 
2.2.1. Integridad referencial declarativa
La integridad referencial declarativa (DRI) y las relaciones entre tablas vienen a garantizar algo importantísimo en los sistemas relacionales, en este caso la consistencia de los datos. No es de recibo que exista en una base de datos una entrega al  cliente 50, y que el cliente 50 no exista!!, y eso es lo que nos garantiza la DRI, que esas cosas no sucedan.
 
Ejemplo :
Puede existir una cabecera que no tenga líneas, aunque la DRI garantiza que si existe una línea su cabecera si existe. Esto puede llevarnos a situaciones a veces difíciles de entender, sobre todo al principio. Si se construye una sentencia select que devuelve los registros de la cabecera, aparecen X registros, si la sentencia se completa con las unión con las líneas aparecen Y, pero Y puede ser hasta menor que X, sería ‘normal’ que fuese mayor, pero ¿menor?
/* Siempre nos basamos en una bd que exista en el sistema y que se llame pruebas */
 pruebas go create table cabecera( id int identity (1,1) primary key not null,
fecha datetime default getdate()) go create table lineas (id int not null, orden int not null,
Descripcion varchar(100) not null, constraint pk_lineas primary key (id,orden), constraint fk_lineas foreign key (id) references cabecera) go
/* además metemos 100 cabeceras */
declare @i int
set @i=0
while @i<100
begin
insert into cabecera default values
select @i=@i+1
end
go
/* y dos lineas *//
insert into lineas values (1,1,’Esto es una prueba’)
insert into lineas values (1,2,’Esto es una prueba linea 2′)
go
select * from cabecera
— 100 filas
Esto es normal, el sistema nos devuelve las 100 filas de la cabecera,
 .
.
El resultado serán las 101 filas, siendo todos los valores de la tabla líneas null, en aquellas que no tienen registros relacionados. Aparece una fila más que cabeceras por que una cabecera tiene dos líneas, por tanto esa cabecera aparecerá dos veces.
go
select * from cabecera left join lineas on cabecera.id=lineas.id where lineas.id is null
— 99 filas = 101 −2 filas.