Motor de almacenamiento extensible - Extensible Storage Engine

Motor de almacenamiento extensible
Otros nombres JET Azul
Desarrollador (es) Microsoft
Versión inicial 1994 ; Hace 27 años  ( 1994 )
Repositorio github .com / microsoft / Extensible-Storage-Engine
Escrito en C ++
Sistema operativo Microsoft Windows
Plataforma IA-32 , x86-64 , ARM e Itanium (e históricamente DEC Alpha , MIPS y PowerPC )
Escribe Motor de base de datos
Licencia Licencia MIT
Sitio web docs .microsoft .com / es-es / windows / win32 / motor-de-almacenamiento- extensible / motor-de-almacenamiento- extensible  Edita esto en Wikidata

El motor de almacenamiento extensible ( ESE ), también conocido como JET Blue , es una tecnología de almacenamiento de datos ISAM (método de acceso secuencial indexado) de Microsoft . ESE es el núcleo de Microsoft Exchange Server , Active Directory y Windows Search . También lo utilizan varios componentes de Windows, incluido el cliente de Windows Update y el Centro de ayuda y soporte técnico . Su propósito es permitir que las aplicaciones almacenen y recuperen datos mediante acceso indexado y secuencial.

ESE proporciona actualización y recuperación de datos de transacciones . Se proporciona un mecanismo de recuperación de fallos para mantener la coherencia de los datos incluso en caso de fallo del sistema. Las transacciones en ESE son altamente concurrentes, lo que hace que ESE sea adecuado para aplicaciones de servidor. ESE almacena en caché los datos de forma inteligente para garantizar un acceso de alto rendimiento a los datos. Además, ESE es liviano, lo que lo hace adecuado para aplicaciones auxiliares.

El tiempo de ejecución de ESE (ESENT.DLL) se incluye en todas las versiones de Windows desde Windows 2000 , con la versión x64 nativa del tiempo de ejecución de ESE que se envía con las versiones x64 de Windows XP y Windows Server 2003 . Microsoft Exchange , hasta Exchange 2003, se envió solo con la edición de 32 bits, ya que era la única plataforma compatible. Con Exchange 2007 , se envía con la edición de 64 bits.

Bases de datos

Una base de datos es una agrupación de datos tanto física como lógica. Una base de datos ESE parece un solo archivo para Windows. Internamente, la base de datos es una colección de páginas de 2, 4, 8, 16 o 32 KB (las opciones de página de 16 y 32 KB solo están disponibles en Windows 7 y Exchange 2010), organizadas en una estructura de árbol B equilibrada . Estas páginas contienen metadatos para describir los datos contenidos dentro de la base de datos, los datos en sí, índices para conservar órdenes interesantes de datos y otra información. Esta información se mezcla dentro del archivo de la base de datos, pero se hacen esfuerzos para mantener los datos usados ​​juntos agrupados dentro de la base de datos. Una base de datos ESE puede contener hasta 2 32 páginas, o 16 terabytes de datos, para páginas de 8 kilobytes .

Las bases de datos de ESE están organizadas en grupos llamados instancias. La mayoría de las aplicaciones usan una sola instancia, pero todas las aplicaciones también pueden usar múltiples instancias. La importancia de la instancia es que asocia una única serie de registros de recuperación con una o más bases de datos. Actualmente, se pueden adjuntar hasta 6 bases de datos de usuarios a una instancia de ESE en cualquier momento. Cada proceso por separado que usa ESE puede tener hasta 1024 instancias de ESE.

Una base de datos es portátil en el sentido de que puede separarse de una instancia de ESE en ejecución y luego adjuntarse a la misma instancia en ejecución oa una diferente. Mientras está separada, una base de datos se puede copiar usando utilidades estándar de Windows. La base de datos no se puede copiar mientras se utiliza activamente, ya que ESE abre archivos de base de datos exclusivamente. Una base de datos puede residir físicamente en cualquier dispositivo compatible con operaciones de E / S direccionables directamente por Windows.

Mesas

Una tabla es una colección homogénea de registros, donde cada registro tiene el mismo conjunto de columnas. Cada tabla está identificada por un nombre de tabla, cuyo alcance es local a la base de datos en la que está contenida la tabla. La cantidad de espacio en disco asignado a una tabla dentro de una base de datos está determinada por un parámetro dado cuando la tabla se crea con la operación CreateTable. Las tablas crecen automáticamente en respuesta a la creación de datos.

Las tablas tienen uno o más índices. Debe haber al menos un índice agrupado para los datos de registro. Cuando la aplicación no define ningún índice agrupado, se utiliza un índice artificial que ordena y agrupa los registros según el orden cronológico de inserción del registro. Los índices se definen para conservar órdenes interesantes de datos y permitir tanto el acceso secuencial a los registros en orden de índice como el acceso directo a los registros por valores de columna de índice. Los índices agrupados en ESE también deben ser primarios, lo que significa que la clave de índice debe ser única.

Los índices agrupados y no agrupados se representan mediante árboles B + . Si una operación de inserción o actualización hace que una página se desborde, la página se divide: se asigna una nueva página y se encadena lógicamente entre las dos páginas previamente adyacentes. Dado que esta nueva página no está físicamente adyacente a sus vecinos lógicos, el acceso a ella no es tan eficiente. ESE tiene una función de compactación en línea que vuelve a compactar los datos. Si se espera que una tabla se actualice con frecuencia, se puede reservar espacio para futuras inserciones especificando una densidad de página adecuada al crear una tabla o índice. Esto permite evitar o posponer operaciones divididas.

Registros y columnas

Un registro es un conjunto asociado de valores de columna. Los registros se insertan y actualizan mediante operaciones de actualización y se pueden eliminar mediante operaciones de eliminación. Las columnas se establecen y recuperan mediante las operaciones SetColumns y RetrieveColumns, respectivamente. El tamaño máximo de un registro es 8110 bytes para páginas de 8 kilobytes con la excepción de las columnas de valor largo. Los tipos de columna de LongText y LongBinary no contribuyen significativamente a esta limitación de tamaño, y los registros pueden contener datos mucho más grandes que el tamaño de una página de base de datos cuando los datos se almacenan en columnas de valores largos. Cuando se almacena una referencia de valor largo en un registro, solo se requieren 9 bytes de datos en el registro. Estos valores largos pueden tener un tamaño de hasta 2 gigabytes (GB).

Los registros suelen ser uniformes en el sentido de que cada registro tiene un conjunto de valores para el mismo conjunto de columnas. En ESE, también es posible definir muchas columnas para una tabla y, sin embargo, hacer que un registro determinado contenga solo una pequeña cantidad de valores de columna no NULL. En este sentido, una tabla también puede ser una colección de registros heterogéneos.

ESE admite una amplia gama de valores de columnas, que varían en tamaño de 1 bit a 2 GB. La elección del tipo de columna correcto es importante porque el tipo de columna determina muchas de sus propiedades, incluido el orden de los índices. ESE admite los siguientes tipos de datos:

Tipos de columnas

Nombre Descripción
Un poco valor ternario (NULL, 0 o 1)
Byte sin firmar Entero sin signo de 1 byte
Pequeño Entero de 2 bytes con signo
Corto sin firmar Entero sin signo de 2 bytes
Largo Entero de 4 bytes con signo
Largo sin firmar Entero sin signo de 4 bytes
Largo largo Entero de 8 bytes con signo
UnsignedLongLong Entero sin signo de 8 bytes
Divisa Entero de 8 bytes con signo
IEEE individual Número de coma flotante de 4 bytes
IEEE doble Número de coma flotante de 8 bytes
Fecha y hora Fecha y hora de 8 bytes (fecha integral, tiempo fraccionario)
GUID Identificador único de 16 bytes
Binario Cadena binaria, longitud <= 255 bytes
Texto Cadena ANSI o Unicode, longitud <= 255 bytes
Binario largo Cadena binaria grande, longitud <2 GB
Texto largo Cadena grande ANSI o Unicode, longitud <2 GB

Columnas fijas, variables y etiquetadas

Cada tabla ESE puede definir hasta 127 columnas de longitud fija, 128 columnas de longitud variable y 64.993 columnas etiquetadas.

  • Las columnas fijas son esencialmente columnas que ocupan la misma cantidad de espacio en cada registro, independientemente de su valor. Las columnas fijas ocupan un bit para representar la NULIDAD del valor de la columna y una cantidad fija de espacio en cada registro en el que se establece esa columna, o una columna fija definida posteriormente.
  • Las columnas variables son esencialmente columnas que ocupan una cantidad variable de espacio en cada registro en el que se establecen, según el tamaño del valor de columna en particular. Las columnas variables ocupan 2 bytes para determinar la NULLidad y el tamaño, y una cantidad variable de espacio en cada registro en el que se establece esa columna.
  • Las columnas etiquetadas son columnas que no ocupan espacio alguno si no se establecen en un registro. Pueden tener un solo valor, pero también pueden tener varios valores. La misma columna etiquetada puede tener varios valores en un solo registro. Cuando se establecen columnas etiquetadas en un registro, cada instancia de una columna etiquetada ocupa aproximadamente 4 bytes de espacio además del tamaño del valor de instancia de la columna etiquetada. Cuando el número de instancias de una sola columna etiquetada es grande, la sobrecarga por instancia de columna etiquetada es de aproximadamente 2 bytes. Las columnas etiquetadas son ideales para columnas dispersas porque no ocupan ningún espacio si no están configuradas. Si se indexa una columna etiquetada de varios valores, el índice contendrá una entrada para el registro para cada valor de la columna etiquetada.

Para una tabla dada, las columnas caen en una de dos categorías: aquellas que ocurren exactamente una vez en cada uno de los registros, posiblemente con algunos valores NULL; y aquellos que ocurren raramente, o que pueden tener múltiples ocurrencias en un solo registro. Las columnas fijas y variables pertenecen a la primera categoría, mientras que las columnas etiquetadas pertenecen a la última. La representación interna de las dos categorías de columnas es diferente y es importante comprender las compensaciones entre las categorías de columnas. Las columnas fijas y variables se representan normalmente en todos los registros, incluso cuando la ocurrencia tiene un valor NULL. Estas columnas se pueden abordar rápidamente a través de una tabla de compensación. Las ocurrencias de columnas etiquetadas están precedidas por un identificador de columna y la columna se ubica mediante una búsqueda binaria en el conjunto de columnas etiquetadas.

Valores largos

Los tipos de columna de texto largo y binario largo son objetos binarios grandes. Se almacenan en un árbol B + separado del índice agrupado codificado por ID de valor largo y desplazamiento de bytes. ESE admite agregar, sobrescribir el rango de bytes y establecer el tamaño para estas columnas. Además, ESE tiene una función de almacenamiento de instancia única donde varios registros pueden hacer referencia al mismo objeto binario grande, como si cada registro tuviera su propia copia de la información, es decir, sin conflictos de bloqueo entre registros. El tamaño máximo de un valor de columna de texto largo o binario largo es de 2 GB.

Columnas de versión, incremento automático y depósito en garantía

ESE incrementa automáticamente las columnas de versión cada vez que se modifica un registro que contiene esta columna mediante una operación de actualización. La aplicación no puede establecer esta columna, solo se puede leer. Las aplicaciones de las columnas de versión incluyen su uso para determinar si es necesario actualizar una copia en memoria de un registro dado. Si el valor en un registro de tabla es mayor que el valor en una copia en caché, se sabe que la copia en caché está desactualizada. Las columnas de versión deben ser de tipo Long.

ESE establece automáticamente las columnas de incremento automático de modo que el valor contenido en la columna sea único para cada registro de la tabla. La aplicación no puede establecer estas columnas, como las columnas de versión. Las columnas de incremento automático son de solo lectura y se configuran automáticamente cuando se inserta un nuevo registro en una tabla mediante una operación de actualización. El valor de la columna permanece constante durante la vida útil del registro y solo se permite una columna de incremento automático por tabla. Las columnas de incremento automático pueden ser de tipo Long o de tipo Moneda.

Las columnas de depósito en garantía se pueden modificar mediante una operación EscrowUpdate. Las actualizaciones en custodia son operaciones delta numéricas. Las columnas de depósito en garantía deben ser de tipo Long. Los ejemplos de operaciones delta numéricas incluyen sumar 2 a un valor o restar 1 de un valor. ESE rastrea el cambio en un valor en lugar del valor final de una actualización. Varias sesiones pueden tener cambios pendientes realizados a través de EscrowUpdate al mismo valor porque ESE puede determinar el valor final real independientemente de qué transacciones se confirmen y qué transacciones se deshagan. Esto permite que varios usuarios actualicen simultáneamente una columna realizando cambios delta numéricos. Opcionalmente, el motor de la base de datos puede borrar registros con valor cero de la columna. Un uso común de dicha columna de depósito en garantía es el contador de referencias: muchos subprocesos incrementan / reducen el valor sin bloqueos, y cuando el contador llega a cero, el registro se elimina automáticamente.

Índices

Un índice es un orden persistente de registros en una tabla. Los índices se utilizan tanto para el acceso secuencial a las filas en el orden definido como para la navegación directa de registros basada en los valores de las columnas indexadas. El orden definido por un índice se describe en términos de una matriz de columnas, en orden de precedencia. Esta matriz de columnas también se denomina clave de índice. Cada columna se denomina segmento de índice. Cada segmento de índice puede ser ascendente o descendente, en términos de su contribución al ordenamiento. Se puede definir cualquier número de índices para una tabla. ESE proporciona un amplio conjunto de funciones de indexación.

Índices agrupados

Un índice puede especificarse como índice agrupado o primario. En ESE, el índice agrupado debe ser único y se denomina índice principal. Otros índices se describen como índices no agrupados o secundarios. Los índices primarios se diferencian de los índices secundarios en que la entrada del índice es el registro en sí y no un puntero lógico al registro. Los índices secundarios tienen claves primarias en sus hojas para vincular lógicamente al registro en el índice primario. En otras palabras, la tabla está agrupada físicamente en el orden del índice principal. La recuperación de datos de registros no indexados en el orden de índice primario es generalmente mucho más rápida que en el orden de índice secundario. Esto se debe a que un solo acceso al disco puede traer a la memoria varios registros a los que se podrá acceder muy juntos en el tiempo. El mismo acceso al disco satisface múltiples operaciones de acceso a registros. Sin embargo, la inserción de un registro en medio de un índice, según lo determinado por el orden del índice principal, puede ser mucho más lenta que agregarlo al final de un índice. La frecuencia de actualización debe considerarse cuidadosamente en comparación con los patrones de recuperación al realizar el diseño de la tabla. Si no se define un índice primario para una tabla, se crea un índice primario implícito, llamado índice de clave de base de datos (DBK). El DBK es simplemente un número ascendente único que se incrementa cada vez que se inserta un registro. Como resultado, el orden físico de los registros en un índice DBK es el orden de inserción cronológico y siempre se agregan nuevos registros al final de la tabla. Si una aplicación desea agrupar datos en un índice no exclusivo, esto es posible agregando una columna de autoincremento al final de la definición de índice no exclusivo.

Indexación sobre columnas de varios valores

Los índices se pueden definir en columnas de varios valores. Pueden existir múltiples entradas en estos índices para registros con múltiples valores para la columna indexada. Las columnas de varios valores se pueden indexar junto con las columnas de un solo valor. Cuando dos o más columnas de valores múltiples se indexan juntas, la propiedad de valores múltiples solo se respeta para la primera columna de valores múltiples en el índice. Las columnas de menor precedencia se tratan como si tuvieran un solo valor.

Índices dispersos

Los índices también se pueden definir como escasos. Los índices dispersos no tienen al menos una entrada para cada registro de la tabla. Hay varias opciones para definir un índice disperso. Existen opciones para excluir registros de los índices cuando una clave de índice completa es NULL, cuando cualquier segmento de clave es NULL o cuando solo el primer segmento de clave es NULL. Los índices también pueden tener columnas condicionales. Estas columnas nunca aparecen dentro de un índice, pero pueden hacer que un registro no se indexe cuando la columna condicional es NULL o no NULL.

Índices de tupla

Los índices también se pueden definir para incluir una entrada para cada subcadena de una columna de texto o texto largo. Estos índices se denominan índices de tupla. Se utilizan para acelerar las consultas con predicados coincidentes de subcadena. Los índices de tupla solo se pueden definir para columnas de texto. Por ejemplo, si el valor de una columna de texto es "Me encanta JET Blue" y el índice está configurado para tener un tamaño de tupla mínimo de 4 caracteres y una longitud de tupla máxima de 10 caracteres, se indexarán las siguientes subcadenas:

"Me encanta JET"

“Love JET”
“love JET B”
“ove JET Bl”
“ve JET Blu”
“e JET Blue”
“JET Blue”
“JET Blue”
“ET Blue”
“T Blue”
“Blue”
“Blue”

Aunque los índices de tupla pueden ser muy grandes, pueden acelerar significativamente las consultas del tipo: busque todos los registros que contengan "JET Blue" . Se pueden utilizar para subcadenas más largas que la longitud máxima de tupla dividiendo la subcadena de búsqueda en cadenas de búsqueda de longitud máxima de tupla e intersecando los resultados. Se pueden usar para coincidencias exactas de cadenas siempre que la longitud máxima de la tupla o tan corta como la longitud mínima de la tupla, sin intersección de índice. Para obtener más información sobre cómo realizar la intersección de índices en ESE, consulte Intersección de índices . Los índices de tupla no pueden acelerar las consultas en las que la cadena de búsqueda es más corta que la longitud mínima de la tupla.

Actas

Una transacción es una unidad lógica de procesamiento delimitada por las operaciones BeginTransaction y CommitTransaction, o Rollback. Todas las actualizaciones realizadas durante una transacción son atómicas; aparecen todos en la base de datos al mismo tiempo o no aparece ninguno. Cualquier actualización posterior de otras transacciones es invisible para una transacción. Sin embargo, una transacción puede actualizar solo los datos que no han cambiado mientras tanto; de lo contrario, la operación falla de inmediato sin esperar. Las transacciones de solo lectura nunca necesitan esperar, y las transacciones de actualización solo pueden interferir entre sí. Las transacciones que se terminan por Rollback, o por un bloqueo del sistema, no dejan rastro en la base de datos. En general, el estado de los datos se restaura en Rollback a lo que era antes de BeginTransaction.

Las transacciones se pueden anidar hasta en 7 niveles, con un nivel adicional reservado para uso interno de ESE. Esto significa que una parte de una transacción se puede revertir, sin necesidad de revertir toda la transacción; un CommitTransaction de una transacción anidada simplemente significa el éxito de una fase de procesamiento, y la transacción externa aún puede fallar. Los cambios se confirman en la base de datos solo cuando se confirma la transacción más externa. Esto se conoce como compromiso con el nivel de transacción 0. Cuando la transacción se confirma con el nivel de transacción 0, los datos que describen la transacción se descargan sincrónicamente en el registro para garantizar que la transacción se complete incluso en el caso de una falla posterior del sistema. El vaciado sincronizado del registro hace que las transacciones de ESE sean duraderas. Sin embargo, en algunos casos, la aplicación desea solicitar sus actualizaciones, pero no garantiza de inmediato que se realizarán los cambios. Aquí, las aplicaciones pueden realizar cambios con JET_bitIndexLazyFlush.

ESE admite un mecanismo de control de simultaneidad llamado control de versiones múltiples. En las versiones múltiples, cada transacción consulta una vista coherente de toda la base de datos tal como estaba en el momento en que comenzó la transacción. Las únicas actualizaciones que encuentra son las realizadas por él. De esta manera, cada transacción opera como si fuera la única transacción activa que se ejecuta en el sistema, excepto en el caso de conflictos de escritura. Dado que una transacción puede realizar cambios en función de los datos leídos que ya se han actualizado en otra transacción, el control de versiones múltiples por sí mismo no garantiza transacciones serializables . Sin embargo, la serialización se puede lograr cuando se desee simplemente utilizando bloqueos de lectura de registros explícitos para bloquear los datos de lectura en los que se basan las actualizaciones. Tanto los bloqueos de lectura como los de escritura pueden solicitarse explícitamente con la operación GetLock.

Además, ESE admite una función avanzada de control de concurrencia conocida como bloqueo de custodia. El bloqueo del fideicomiso es una actualización extremadamente simultánea en la que un valor numérico se cambia de manera relativa, es decir, sumando o restando otro valor numérico. Las actualizaciones de fideicomiso no entran en conflicto incluso con otras actualizaciones de fideicomiso simultáneas del mismo dato. Esto es posible porque las operaciones admitidas son conmutables y se pueden confirmar o deshacer de forma independiente. Como resultado, no interfieren con las transacciones de actualización simultáneas. Esta función se utiliza a menudo para agregaciones mantenidas.

ESE también extiende la semántica de transacciones desde operaciones de manipulación de datos hasta operaciones de definición de datos. Es posible agregar un índice a una tabla y hacer que las transacciones que se ejecutan simultáneamente actualicen la misma tabla sin ningún tipo de contención de bloqueo de transacción. Más tarde, cuando estas transacciones se completan, el índice recién creado está disponible para todas las transacciones y tiene entradas para las actualizaciones de registros realizadas por otras transacciones que no pudieron percibir la presencia del índice cuando se realizaron las actualizaciones. Las operaciones de definición de datos se pueden realizar con todas las características que se esperan del mecanismo de transacción para las actualizaciones de registros. Las operaciones de definición de datos admitidas de esta manera incluyen AddColumn, DeleteColumn, CreateIndex, DeleteIndex, CreateTable y DeleteTable.

Navegación del cursor y el búfer de copia

Un cursor es un puntero lógico dentro de un índice de tabla. El cursor puede estar posicionado en un registro, antes del primer registro, después del último registro o incluso entre registros. Si un cursor se coloca antes o después de un registro, no hay ningún registro actual. Es posible tener varios cursores en el mismo índice de tabla. Muchas operaciones de registros y columnas se basan en la posición del cursor. La posición del cursor se puede mover secuencialmente mediante operaciones de movimiento o directamente usando teclas de índice con operaciones de búsqueda. Los cursores también se pueden mover a una posición fraccionaria dentro de un índice. De esta forma, el cursor se puede mover rápidamente a la posición de la barra del pulgar. Esta operación se realiza con la misma velocidad que una operación de búsqueda. No se debe acceder a los datos intermedios.

Cada cursor tiene un búfer de copia para crear un nuevo registro o modificar un registro existente, columna por columna. Este es un búfer interno cuyo contenido se puede cambiar con operaciones SetColumns. Las modificaciones del búfer de copia no cambian automáticamente los datos almacenados. El contenido del registro actual se puede copiar en el búfer de copia mediante la operación PrepareUpdate, y las operaciones de actualización almacenan el contenido del búfer de copia como un registro. El búfer de copia se borra implícitamente en la confirmación o reversión de una transacción, así como en las operaciones de navegación. RetrieveColumns se puede utilizar para recuperar datos de columna del registro o del búfer de copia, si existe.

Procesamiento de consultas

Las aplicaciones de ESE invariablemente consultan sus datos. Esta sección del documento describe características y técnicas para que las aplicaciones escriban lógica de procesamiento de consultas en ESE.

Clasificaciones y tablas temporales

ESE proporciona una capacidad de clasificación en forma de tablas temporales. La aplicación inserta registros de datos en el proceso de clasificación un registro a la vez y luego los recupera un registro a la vez en orden clasificado. En realidad, la clasificación se realiza entre la última inserción de registro y la primera recuperación de registro. Las tablas temporales también se pueden utilizar para conjuntos de resultados parciales y completos. Estas tablas pueden ofrecer las mismas características que las tablas base, incluida la capacidad de navegar secuencialmente o directamente a filas utilizando claves de índice que coincidan con la definición de clasificación. Las tablas temporales también se pueden actualizar para el cálculo de agregados complejos. Los agregados simples se pueden calcular automáticamente con una característica similar a la clasificación donde el agregado deseado es un resultado natural del proceso de clasificación.

Cubriendo índices

Recuperar datos de columna directamente de índices secundarios es una importante optimización del rendimiento. Las columnas se pueden recuperar directamente de los índices secundarios, sin acceder a los registros de datos, mediante el indicador RetrieveFromIndex en la operación RetrieveColumns. Es mucho más eficiente recuperar columnas de un índice secundario que del registro cuando se navega por el índice. Si los datos de la columna se recuperaron del registro, entonces es necesaria una navegación adicional para ubicar el registro por la clave principal. Esto puede resultar en accesos adicionales al disco. Cuando un índice proporciona todas las columnas necesarias, se denomina índice de cobertura. Tenga en cuenta que las columnas definidas en el índice primario de la tabla también se encuentran en índices secundarios y se pueden recuperar de manera similar usando JET_bitRetrieveFromPrimaryBookmark.

Las claves de índice se almacenan en forma normalizada que, en muchos casos, se puede desnormalizar al valor de la columna original. La normalización no siempre es reversible. Por ejemplo, los tipos de columna Texto y Texto largo no se pueden desnormalizar. Además, las claves de índice se pueden truncar cuando los datos de la columna son muy largos. En los casos en los que las columnas no se pueden recuperar directamente de los índices secundarios, siempre se puede acceder al registro para recuperar los datos necesarios.

Intersección del índice

Las consultas a menudo implican una combinación de restricciones sobre los datos. Un medio eficaz de procesar una restricción es utilizar un índice disponible. Sin embargo, si una consulta implica múltiples restricciones, las aplicaciones a menudo procesan las restricciones recorriendo el rango de índice completo del predicado más restrictivo satisfecho por un solo índice. Cualquier predicado restante, llamado predicado residual, se procesa aplicando el predicado al registro mismo. Este es un método simple pero tiene la desventaja de tener que realizar muchos accesos al disco para traer registros a la memoria para aplicar el predicado residual.

La intersección de índices es un mecanismo de consulta importante en el que se utilizan varios índices juntos para procesar de manera más eficiente una restricción compleja. En lugar de usar un solo índice, los rangos de índices en múltiples índices se combinan para dar como resultado un número mucho menor de registros en los que se puede aplicar cualquier predicado residual. ESE facilita esto al proporcionar una operación IntersectIndexes. Esta operación acepta una serie de rangos de índices en índices de la misma tabla y devuelve una tabla temporal de claves primarias que se puede usar para navegar a los registros de la tabla base que satisfacen todos los predicados de índice.

Mesas preunidas

Una combinación es una operación común en un diseño de tabla normalizado, donde los datos relacionados lógicamente se vuelven a reunir para su uso en una aplicación. Las uniones pueden ser operaciones costosas porque pueden ser necesarios muchos accesos a datos para traer datos relacionados a la memoria. Este esfuerzo se puede optimizar en algunos casos definiendo una única tabla base que contenga datos para dos o más tablas lógicas. El conjunto de columnas de la tabla base es la unión de los conjuntos de columnas de estas tablas lógicas. Las columnas etiquetadas hacen esto posible debido a su buen manejo de datos de valor múltiple y de valor escaso. Dado que los datos relacionados se almacenan juntos en el mismo registro, se accede a ellos juntos minimizando así el número de accesos al disco para realizar la unión. Este proceso se puede extender a una gran cantidad de tablas lógicas ya que ESE puede admitir hasta 64.993 columnas etiquetadas. Dado que los índices se pueden definir en columnas de valores múltiples, aún es posible indexar tablas 'interiores'. Sin embargo, existen algunas limitaciones y las aplicaciones deben considerar la unión previa cuidadosamente antes de emplear esta técnica.

Registro y recuperación de fallos

La función de registro y recuperación de ESE admite la integridad y la coherencia de los datos garantizados en caso de una falla del sistema. El registro es el proceso de registrar de forma redundante las operaciones de actualización de la base de datos en un archivo de registro. La estructura del archivo de registro es muy sólida contra fallas del sistema. La recuperación es el proceso de utilizar este registro para restaurar las bases de datos a un estado coherente después de una caída del sistema.

Las operaciones de transacción se registran y el registro se descarga en el disco durante cada confirmación al nivel de transacción 0. Esto permite que el proceso de recuperación rehaga las actualizaciones realizadas por las transacciones que se comprometen al nivel de transacción 0 y deshaga los cambios realizados por las transacciones que no se comprometieron al nivel de transacción. 0. Este tipo de esquema de recuperación a menudo se denomina esquema de recuperación de "avance / retroceso". Los registros se pueden conservar hasta que los datos se copien de forma segura a través de un proceso de copia de seguridad que se describe a continuación, o los registros se pueden reutilizar de forma circular tan pronto como ya no sean necesarios para la recuperación de un fallo del sistema. El registro circular minimiza la cantidad de espacio en disco necesario para el registro, pero tiene implicaciones en la capacidad de recrear un estado de datos en caso de una falla en el medio.

Copia de seguridad y restaurar

El registro y la recuperación también juegan un papel en la protección de los datos contra fallas en los medios. ESE admite la copia de seguridad en línea donde se copian una o más bases de datos, junto con los archivos de registro de una manera que no afecta las operaciones de la base de datos. Las bases de datos pueden seguir siendo consultadas y actualizadas mientras se realiza la copia de seguridad. La copia de seguridad se denomina "copia de seguridad difusa" porque el proceso de recuperación debe ejecutarse como parte de la restauración de la copia de seguridad para restaurar un conjunto coherente de bases de datos. Se admiten tanto la copia de seguridad en streaming como en la instantánea.

La copia de seguridad en streaming es un método de copia de seguridad en el que se realizan copias de todos los archivos de base de datos deseados y los archivos de registro necesarios durante el proceso de copia de seguridad. Las copias de archivos se pueden guardar directamente en cinta o se pueden hacer en cualquier otro dispositivo de almacenamiento. No se requiere inactividad de la actividad de ningún tipo con las copias de seguridad transmitidas. Tanto la base de datos como los archivos de registro se suman para garantizar que no existan daños en los datos dentro del conjunto de datos durante el proceso de copia de seguridad. Las copias de seguridad de transmisión también pueden ser copias de seguridad incrementales. Las copias de seguridad incrementales son aquellas en las que solo se copian los archivos de registro y que se pueden restaurar junto con una copia de seguridad completa anterior para llevar todas las bases de datos a un estado reciente.

Las copias de seguridad de instantáneas son un nuevo método de copia de seguridad de alta velocidad. Las copias de seguridad de instantáneas son dramáticamente más rápidas porque la copia se realiza virtualmente después de un breve período de inactividad de una aplicación. A medida que se realizan actualizaciones posteriores a los datos, se materializa la copia virtual. En algunos casos, el soporte de hardware para copias de seguridad de instantáneas significa que realmente no es necesario guardar las copias virtuales. Las copias de seguridad de instantáneas son siempre copias de seguridad completas.

Restaurar se puede utilizar para aplicar una única copia de seguridad o se puede utilizar para aplicar una combinación de una única copia de seguridad completa con una o más copias de seguridad incrementales. Además, cualquier archivo de registro existente también se puede reproducir para recrear un conjunto de datos completo hasta la última transacción registrada como comprometida en el nivel de transacción 0. Se puede restaurar una copia de seguridad en cualquier sistema que admita la aplicación original. No es necesario que sea la misma máquina, ni siquiera la misma configuración de máquina. La ubicación de los archivos se puede cambiar como parte del proceso de restauración.

Copia de seguridad y restauración en hardware diferente

Cuando se crea una base de datos ESENT, el tamaño del sector del disco físico se almacena con la base de datos. Se espera que el tamaño del sector físico se mantenga constante entre sesiones; de lo contrario, se informa de un error. Cuando una unidad física se clona o restaura desde una imagen de unidad a una unidad que usa un tamaño de sector físico diferente ( unidades de formato avanzado ), ESENT informará errores.

Este es un problema conocido y Microsoft tiene soluciones disponibles. Para Windows Vista o Windows Server 2008, consulte KB2470478. Para Windows 7 o Windows Server 2008 R2, consulte KB982018.

Historia

JET Blue fue desarrollado originalmente por Microsoft como una posible actualización para el motor de base de datos JET Red en Microsoft Access , pero nunca se usó en esta función. En cambio, pasó a ser utilizado por Exchange Server, Active Directory, Servicio de replicación de archivos (FRS), Editor de configuración de seguridad, Servicios de certificados, Servicio de nombres de Internet de Windows (WINS) y una gran cantidad de otros servicios, aplicaciones y componentes de Windows de Microsoft. Durante años, fue una API privada utilizada solo por Microsoft, pero desde entonces se ha convertido en una API publicada que cualquiera puede usar.

El trabajo en Data Access Engine (DAE) comenzó en marzo de 1989 cuando Allen Reiter se unió a Microsoft. Durante el año siguiente, un equipo de cuatro desarrolladores trabajó para Allen para completar en gran medida el ISAM. Microsoft ya tenía BC7 ISAM (JET Red) pero comenzó el esfuerzo de Data Access Engine (DAE) para construir un motor de base de datos más robusto como una entrada en el entonces nuevo reino de arquitectura cliente-servidor. En la primavera de 1990, los equipos BC7 ISAM y DAE se unieron para convertirse en el esfuerzo de Joint Engine Technology (JET); responsable de producir dos motores, un v1 ( JET Red ) y un v2 (JET Blue) que cumplirían con la misma especificación API (JET API). DAE se convirtió en JET Blue por el color de la bandera de Israel. BC7 ISAM se convirtió en JET Red por el color de la bandera de Rusia. Si bien JET Blue y JET Red se escribieron con la misma especificación de API, no compartieron ningún código ISAM. Ambos admitían un procesador de consultas común, QJET, que más tarde, junto con el BC7 ISAM, se convirtió en sinónimo de JET Red.

JET Blue se envió por primera vez en 1994 como ISAM para WINS, DHCP y los servicios RPL ahora desaparecidos en Windows NT 3.5. Se envió nuevamente como el motor de almacenamiento para Microsoft Exchange en 1996. Los servicios adicionales de Windows eligieron JET Blue como su tecnología de almacenamiento y para el año 2000 todas las versiones de Windows comenzaron a distribuirse con JET Blue. JET Blue fue utilizado por Active Directory y se convirtió en parte de un conjunto especial de código de Windows llamado Trusted Computing Base (TCB). El número de aplicaciones de Microsoft que utilizan JET Blue sigue creciendo y la API de JET Blue se publicó en 2005 para facilitar el uso de un número cada vez mayor de aplicaciones y servicios tanto dentro como fuera de Windows.

Una entrada del blog web de Microsoft Exchange indicó que los desarrolladores que han contribuido a JET Blue incluyen a Cheen Liao, Stephen Hecht, Matthew Bellew, Ian Jose, Edward "Eddie" Gilbert, Kenneth Kin Lum, Balasubramanian Sriram, Jonathan Liem, Andrew Goodsell, Laurion Burchall, Andrei Marinescu, Adam Foxman, Ivan Trindev, Spencer Low y Brett Shirley.

En enero de 2021 Microsoft ESE de código abierto. Se publicó en GitHub con la licencia MIT permisiva .

Comparación con JET Red

Si bien comparten un linaje común, existen grandes diferencias entre JET Red y ESE.

  • JET Red es una tecnología para compartir archivos, mientras que ESE está diseñado para integrarse en una aplicación de servidor y no comparte archivos.
  • JET Red hace el mejor esfuerzo en la recuperación de archivos, mientras que ESE tiene registro de escritura anticipada y aislamiento de instantáneas para una recuperación de fallas garantizada.
  • JET Red antes de la versión 4.0 solo admite el bloqueo de nivel de página, mientras que ESE y JET Red versión 4.0 admiten el bloqueo de nivel de registro.
  • JET Red admite una amplia variedad de interfaces de consulta, incluidas ODBC y OLE DB . ESE no incluye un motor de consultas, sino que se basa en aplicaciones para escribir sus propias consultas como código C ISAM.
  • JET Red tiene un tamaño de archivo de base de datos máximo de 2 GiB , mientras que ESE tiene un tamaño de archivo de base de datos máximo de 8 TiB con páginas de 4 KiB y 16 TiB con páginas de 8 KiB.

Referencias

enlaces externos