

# Diferencias entre una base de datos relacional (SQL) y DynamoDB al administrar índices
<a name="SQLtoNoSQL.Indexes"></a>

Los índices permiten obtener acceso a patrones de consulta alternativos y agilizar las consultas. En esta sección se compara y contrasta la creación y el uso de índices entre SQL y Amazon DynamoDB.

Tanto si está utilizando una base de datos relacional o DynamoDB, la creación de índices debe realizarse con cautela. Cada vez que se produce una escritura en una tabla, es preciso actualizar todos los índices de esa tabla. En un entorno con uso intensivo de escrituras y grandes tablas, esto puede consumir gran cantidad de recursos del sistema. Esto no es motivo de preocupación en entornos de solo lectura o principalmente de lectura. Sin embargo, hay que asegurarse de que la aplicación utilice los índices realmente, de tal forma que estos no se limiten a consumir espacio.

**Topics**
+ [Diferencias entre una base de datos relacional (SQL) y DynamoDB al crear un índice](#SQLtoNoSQL.Indexes.Creating)
+ [Diferencias entre una base de datos relacional (SQL) y DynamoDB al consultar y analizar un índice](#SQLtoNoSQL.Indexes.QueryAndScan)

## Diferencias entre una base de datos relacional (SQL) y DynamoDB al crear un índice
<a name="SQLtoNoSQL.Indexes.Creating"></a>

Compare la instrucción `CREATE INDEX` en SQL con la operación `UpdateTable` en Amazon DynamoDB.

**Topics**
+ [Creación de un índice con SQL](#SQLtoNoSQL.Indexes.Creating.SQL)
+ [Creación de un índice en DynamoDB](#SQLtoNoSQL.Indexes.Creating.DynamoDB)

### Creación de un índice con SQL
<a name="SQLtoNoSQL.Indexes.Creating.SQL"></a>

En las bases de datos relacionales, los índices son estructuras de datos que permiten realizar consultas rápidas en diferentes columnas de una tabla. Puede usar la instrucción `CREATE INDEX` de SQL para agregar un índice a una tabla existente y especificar las columnas que se van a indexar. Una vez que se ha creado el índice, puede consultar los datos de la tabla como de costumbre, si bien ahora la base de datos podrá utilizar el índice para encontrar rápidamente las filas especificadas de la tabla, en lugar de tener que examinar la tabla completa.

Después de crear un índice, la base de datos lo mantiene automáticamente. Cada vez que se modifica algún dato de la tabla, el índice se modifica automáticamente para reflejar los cambios de la tabla.

En MySQL, se crearía un índice como se indica a continuación.

```
CREATE INDEX GenreAndPriceIndex
ON Music (genre, price);
```

### Creación de un índice en DynamoDB
<a name="SQLtoNoSQL.Indexes.Creating.DynamoDB"></a>

En DynamoDB puede crear y usar *un índice secundario* con fines semejantes.

Los índices de DynamoDB son diferentes de sus homólogos relacionales. Al crear un índice secundario, hay que especificar sus atributos de clave: una clave de partición y una clave de ordenación. Una vez creado el índice secundario, puede utilizar las operaciones `Query` o `Scan` para consultarlo o examinarlo, respectivamente, como si se tratase de una tabla. DynamoDB no tiene un optimizador de consultas, de modo que el índice secundario solamente se utiliza cuando se utilizan las operaciones `Query` o `Scan` con él.

DynamoDB admite dos tipos distintos de índices:
+ Los índices secundarios globales: la clave principal del índice puede constar de dos atributos cualesquiera de la tabla a la que pertenece. 
+ Los índices secundarios locales: la clave de partición del índice debe ser igual que la clave de partición de la tabla a la que pertenece. Sin embargo, la clave de ordenación puede ser cualquier otro atributo.

DynamoDB se asegura de que los datos de un índice secundario presenten consistencia final con la tabla a la que pertenece. Puede solicitar operaciones `Query` o `Scan` de consistencia alta en una tabla o un índice. No obstante, los índices secundarios globales solo admiten la consistencia final.

Puede agregar un índice secundario global a una tabla existente; para ello, utilice la operación `UpdateTable` y especifique `GlobalSecondaryIndexUpdates`.

```
{
    TableName: "Music",
    AttributeDefinitions:[
        {AttributeName: "Genre", AttributeType: "S"},
        {AttributeName: "Price", AttributeType: "N"}
    ],
    GlobalSecondaryIndexUpdates: [
        {
            Create: {
                IndexName: "GenreAndPriceIndex",
                KeySchema: [
                    {AttributeName: "Genre", KeyType: "HASH"}, //Partition key
                    {AttributeName: "Price", KeyType: "RANGE"}, //Sort key
                ],
                Projection: {
                    "ProjectionType": "ALL"
                },
                ProvisionedThroughput: {                                // Only specified if using provisioned mode
                    "ReadCapacityUnits": 1,"WriteCapacityUnits": 1
                }
            }
        }
    ]
}
```

Debe proporcionar los siguientes parámetros a `UpdateTable`:
+ `TableName`: tabla a la que se asociará el índice.
+ `AttributeDefinitions`: tipos de datos de los atributos de esquema de claves del índice.
+ `GlobalSecondaryIndexUpdates`: detalles sobre el índice que se desea crear.
  + `IndexName`: nombre del índice.
  + `KeySchema`: atributos utilizados para la clave principal del índice.
  + `Projection`: atributos de la tabla que se copian en el índice. En este caso, `ALL` significa que se copian todos los atributos.
  + `ProvisionedThroughput (for provisioned tables)`: número de lecturas y escrituras por segundo que se requieren para este índice. Este valor es independiente de los ajustes de rendimiento aprovisionado de la tabla. 

Parte de esta operación implica reponer datos de la tabla en el nuevo índice. Durante la reposición, la tabla permanece disponible. Sin embargo, el índice no está preparado hasta que el atributo `Backfilling` cambia de true a false. Puede utilizar la operación `DescribeTable` para ver este atributo.

## Diferencias entre una base de datos relacional (SQL) y DynamoDB al consultar y analizar un índice
<a name="SQLtoNoSQL.Indexes.QueryAndScan"></a>

Compare la realización de consultas y análisis de un índice mediante la instrucción SELECT de SQL con las operaciones `Query` y `Scan` en Amazon DynamoDB.

**Topics**
+ [Consulta y análisis de un índice con SQL](#SQLtoNoSQL.Indexes.QueryAndScan.SQL)
+ [Consulta y análisis de un índice en DynamoDB](#SQLtoNoSQL.Indexes.QueryAndScan.DynamoDB)

### Consulta y análisis de un índice con SQL
<a name="SQLtoNoSQL.Indexes.QueryAndScan.SQL"></a>

En una base de datos relacional, no se trabajar directamente con los índices. En lugar de ello, se consultan las tablas mediante instrucciones `SELECT` y el optimizador de consultas utiliza los índices, si los hay.

Un *optimizador de consultas* es un componente del sistema de administración de bases de datos relacionales (RDBMS) que se encarga de evaluar los índices disponibles y determinar si se pueden utilizar para agilizar consultas. Si los índices pueden utilizarse para agilizar una consulta, el RDBMS obtiene acceso al índice en primer lugar y, a continuación, lo utiliza para localizar los datos en la tabla.

A continuación se muestran algunas instrucciones SQL en las que se puede utilizar *GenreAndPriceIndex* para mejorar el rendimiento. Damos por hecho que la tabla *Music* contiene suficientes datos para que el optimizador de consultas decida utilizar el índice en lugar de examinar la tabla completa.

```
/* All of the rock songs */

SELECT * FROM Music
WHERE Genre = 'Rock';
```

```
/* All of the cheap country songs */

SELECT Artist, SongTitle, Price FROM Music
WHERE Genre = 'Country' AND Price < 0.50;
```

### Consulta y análisis de un índice en DynamoDB
<a name="SQLtoNoSQL.Indexes.QueryAndScan.DynamoDB"></a>

En DynamoDB, se llevan a cabo las operaciones `Query` y `Scan` que consultan el índice directamente, de la misma manera en la que se haría en una tabla. Puede utilizar la API de DynamoDB o [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) (un lenguaje de consulta compatible con SQL) para consultar o analizar el índice. Debe especificar tanto `TableName` como `IndexName`.

A continuación se muestran algunas consultas sobre *GenreAndPriceIndex* en DynamoDB. El esquema de claves de este índice consta de *Genre* y *Price*.

------
#### [ DynamoDB API ]

```
// All of the rock songs

{
    TableName: "Music",
    IndexName: "GenreAndPriceIndex",
    KeyConditionExpression: "Genre = :genre",
    ExpressionAttributeValues: {
        ":genre": "Rock"
    },
};
```

En este ejemplo se utiliza una expresión `ProjectionExpression` para indicar que solamente deseamos que aparezcan en los resultados algunos de los atributos y no todos ellos.

```
// All of the cheap country songs

{
    TableName: "Music",
    IndexName: "GenreAndPriceIndex",
    KeyConditionExpression: "Genre = :genre and Price < :price",
    ExpressionAttributeValues: {
        ":genre": "Country",
        ":price": 0.50
    },
    ProjectionExpression: "Artist, SongTitle, Price"
};
```

A continuación se muestra un examen de *GenreAndPriceIndex*.

```
// Return all of the data in the index

{
    TableName:  "Music",
    IndexName: "GenreAndPriceIndex"
}
```

------
#### [ PartiQL for DynamoDB ]

Con PartiQL, se utiliza la instrucción `Select` de PartiQL para hacer consultas y análisis en el índice.

```
// All of the rock songs

SELECT * 
FROM Music.GenreAndPriceIndex
WHERE Genre = 'Rock'
```

```
// All of the cheap country songs

SELECT * 
FROM Music.GenreAndPriceIndex
WHERE Genre = 'Rock' AND Price < 0.50
```

A continuación se muestra un examen de *GenreAndPriceIndex*.

```
// Return all of the data in the index

SELECT *
FROM Music.GenreAndPriceIndex
```

**nota**  
Para obtener ejemplos de código en los que se utiliza `Select`, consulte [Instrucciones de selección de PartiQL para DynamoDB](ql-reference.select.md).

------