En este tema, se describe cómo escribir una marca de tiempo de confirmación para cada inserción y actualización.
que realizas con Spanner. Para usar esta función, configura la opción allow_commit_timestamp
en una columna TIMESTAMP
y, luego, escribe la marca de tiempo como parte de cada transacción.
Descripción general
La marca de tiempo de confirmación, según TrueTime
tecnología, es el momento en que un
que la transacción se confirme en la base de datos. La columna allow_commit_timestamp
te permite almacenar, de forma atómica, la marca de tiempo de confirmación en una columna.
Con las marcas de tiempo de confirmación almacenadas en las tablas, puedes determinar el orden exacto de las mutaciones y compilar funciones como los registros de cambios.
Para insertar marcas de tiempo de confirmación en tu base de datos, completa los siguientes pasos:
Crea una columna con el tipo
TIMESTAMP
con la opciónallow_commit_timestamp
de columna configurada comotrue
en la definición del esquema. Por ejemplo:CREATE TABLE Performances ( ... LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true) ... ) PRIMARY KEY (...);
Si realizas inserciones o actualizaciones con DML, usa la función
PENDING_COMMIT_TIMESTAMP
para escribir la marca de tiempo de confirmación.Si realizas inserciones o actualizaciones con mutaciones usa la cadena de marcador de posición
spanner.commit_timestamp()
en las inserciones o actualizaciones de tu confirmación marca de tiempo. También puedes usar de confirmación de la marca de tiempo que proporciona la biblioteca cliente. Por ejemplo, esta en el cliente de Java esValue.COMMIT_TIMESTAMP
.
Cuando Spanner confirma la transacción con estos marcadores de posición como columna
valores, la marca de tiempo de confirmación real se escribe en la columna especificada (para
ejemplo: la columna LastUpdateTime
). Luego, puedes usar este valor de columna para crear un historial de actualizaciones de la tabla.
No se garantiza que los valores de marca de tiempo de confirmación sean únicos. Las transacciones que escriben en conjuntos de campos que no se superponen podrían tener la misma marca de tiempo. Las transacciones que escriben en conjuntos de campos que se superponen tienen marcas de tiempo únicas.
Las marcas de tiempo de confirmación de Spanner tienen un nivel de detalle de microsegundos
y se convierten a nanosegundos cuando se almacenan en columnas TIMESTAMP
.
Crea y borra una columna de marcas de tiempo de confirmación
Usa la opción allow_commit_timestamp
para agregar y quitar la asistencia de las marcas de tiempo de confirmación:
- Cuando creas una tabla nueva para especificar que una columna admite marcas de tiempo de confirmación
- Cuando modificas una tabla existente:
- para agregar una columna nueva que admita marcas de tiempo de confirmación
- para modificar una columna
TIMESTAMP
existente a fin de que admita marcas de tiempo de confirmación - Para modificar una columna
TIMESTAMP
existente a fin de quitar la compatibilidad de la marca de tiempo de confirmación
Claves e índices
Puedes usar una columna de marcas de tiempo de confirmación como una columna de clave principal o como una columna sin clave. Las claves principales se pueden definir como ASC
o DESC
.
ASC
(predeterminado): Las claves ascendentes son ideales para responder consultas de un tiempo específico.DESC
: Las claves descendentes mantienen las filas más recientes en la parte superior de la tabla. Proporcionan acceso rápido a los registros más recientes.
La opción allow_commit_timestamp
debe ser coherente en todas las claves principales de las tablas superiores y secundarias. Si la opción no es coherente en todas las claves primarias, Spanner muestra un error. El único momento en que la opción puede ser incoherente es el momento en que se crea o actualiza el esquema.
El uso de marcas de tiempo de confirmación en las siguientes situaciones crea hotspots que reducen el rendimiento de los datos:
En una columna de marca de tiempo de confirmación que funciona como la primera parte de la clave primaria de una tabla:
CREATE TABLE Users ( LastAccess TIMESTAMP NOT NULL, UserId INT64 NOT NULL, ... ) PRIMARY KEY (LastAccess, UserId);
En la primera parte de la clave primaria de un índice secundario:
CREATE INDEX UsersByLastAccess ON Users(LastAccess)
o
CREATE INDEX UsersByLastAccessAndName ON Users(LastAccess, FirstName)
Los hotspots reducen el rendimiento de los datos, incluso con tasas de escritura bajas. No se produce una sobrecarga de rendimiento si las marcas de tiempo de confirmación se habilitan en columnas sin clave que no estén indexadas.
Crea una columna de marcas de tiempo de confirmación
Con el siguiente DDL, se crea una tabla con una columna que admite marcas de tiempo de confirmación.
CREATE TABLE Performances (
SingerId INT64 NOT NULL,
VenueId INT64 NOT NULL,
EventDate Date,
Revenue INT64,
LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true)
) PRIMARY KEY (SingerId, VenueId, EventDate),
INTERLEAVE IN PARENT Singers ON DELETE CASCADE
Cuando se agrega la opción, se modifica la columna de marcas de tiempo de la siguiente manera:
- Puedes usar la string del marcador de posición
spanner.commit_timestamp()
(o una constante que proporcione la biblioteca cliente) para realizar inserciones y actualizaciones. - La columna solo puede contener valores anteriores. Si quieres obtener más información, consulta la sección sobre cómo proporcionar tu propio valor para la marca de tiempo.
La opción allow_commit_timestamp
distingue entre mayúsculas y minúsculas.
Agrega una columna de marcas de tiempo de confirmación a una tabla existente
Para agregar una columna de marcas de tiempo de confirmación a una tabla existente, usa la declaración ALTER TABLE
. Por ejemplo, para agregar una columna LastUpdateTime
a la tabla Performances
, usa la siguiente instrucción:
ALTER TABLE Performances ADD COLUMN LastUpdateTime TIMESTAMP
NOT NULL OPTIONS (allow_commit_timestamp=true)
Convierte una columna de marcas de tiempo en una columna de marcas de tiempo de confirmación
Puedes convertir una columna de marca de tiempo existente en una columna de marca de tiempo de confirmación. pero, para ello, Spanner debe validar que la configuración valores de marca de tiempo son del pasado. Por ejemplo:
ALTER TABLE Performances ALTER COLUMN LastUpdateTime
SET OPTIONS (allow_commit_timestamp=true)
No puedes cambiar el tipo de datos o la anotación NULL
de una columna en una declaración ALTER TABLE
que incluya SET OPTIONS
. Para obtener más detalles, consulta Lenguaje de definición de datos.
Quita la opción de marca de tiempo de confirmación
Si deseas quitar la asistencia de marca de tiempo de confirmación de una columna, usa la opción allow_commit_timestamp=null
en una declaración ALTER TABLE
. Se quita el comportamiento de la marca de tiempo de confirmación, pero la columna sigue siendo una marca de tiempo. El cambio de la opción no altera otras características de la columna, como el tipo o la capacidad de nulidad (NOT NULL
). Por ejemplo:
ALTER TABLE Performances ALTER COLUMN LastUpdateTime
SET OPTIONS (allow_commit_timestamp=null)
Escribe una marca de tiempo de confirmación con una declaración DML
Usa la función PENDING_COMMIT_TIMESTAMP
para escribir la marca de tiempo de confirmación en una declaración DML. Spanner selecciona la marca de tiempo de confirmación cuando la transacción
confirmaciones.
La siguiente declaración DML actualiza la columna LastUpdateTime
en el
Tabla Performances
con la marca de tiempo de confirmación:
UPDATE Performances SET LastUpdateTime = PENDING_COMMIT_TIMESTAMP()
WHERE SingerId=1 AND VenueId=2 AND EventDate="2015-10-21"
En el siguiente ejemplo de código, se usa la función PENDING_COMMIT_TIMESTAMP
para escribir la marca de tiempo de confirmación en la columna LastUpdateTime
.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Ruby
Las marcas de tiempo de confirmación solo se pueden escribir en columnas anotadas con la opción allow_commit_timestamp=true
.
Si tienes mutaciones en filas de varias tablas, debes especificar spanner.commit_timestamp()
(o la constante de la biblioteca cliente) en la columna de marcas de tiempo de confirmación de cada tabla.
Consulta una columna de marcas de tiempo de confirmación
En el siguiente ejemplo, se consulta la columna de marcas de tiempo de confirmación de la tabla.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Proporciona tu propio valor para la columna de marca de tiempo de confirmación
Puedes proporcionar tu propio valor para la columna de marcas de tiempo de confirmación, en lugar de pasar spanner.commit_timestamp()
(o la constante de la biblioteca cliente) como el valor de la columna. El valor debe ser una marca de tiempo anterior. Esta restricción garantiza que la escritura de marcas de tiempo sea una operación rápida y económica. El servidor
muestra un error FailedPrecondition
si se especifica una marca de tiempo futura.
Crear un registro de cambios
Supongamos que deseas crear un registro de cambios de todas las mutaciones que se producen en una tabla y, luego, usarlo para realizar auditorías. Un ejemplo sería una tabla que almacena el historial de cambios de los documentos de procesamiento de texto. Las marcas de tiempo de confirmación facilitan la creación del registro de cambios, ya que pueden aplicar de forma forzosa el orden de las entradas del registro de cambios. Puedes crear un registro de cambios que almacene el historial de cambios de un documento determinado mediante un esquema como se muestra en el siguiente ejemplo:
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocumentId INT64 NOT NULL,
Contents STRING(MAX) NOT NULL,
) PRIMARY KEY (UserId, DocumentId);
CREATE TABLE DocumentHistory (
UserId INT64 NOT NULL,
DocumentId INT64 NOT NULL,
Ts TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true),
Delta STRING(MAX),
) PRIMARY KEY (UserId, DocumentId, Ts),
INTERLEAVE IN PARENT Documents ON DELETE NO ACTION;
Para crear un registro de cambios, inserta una fila nueva en el DocumentHistory
en la misma transacción en la que insertas o actualizas una fila en el Document
. En la sección
de la fila nueva en DocumentHistory
, usa el marcador de posición
spanner.commit_timestamp()
(o constante de la biblioteca cliente) para decirle
Spanner escribe la marca de tiempo de confirmación en la columna Ts
. Intercalar la tabla DocumentsHistory
con la tabla Documents
permitirá la ubicación de datos y la realización de inserciones y actualizaciones más eficientes. Sin embargo, también agrega la restricción de que las filas superiores y secundarias se deben borrar juntas. Para mantener las filas de DocumentHistory
después de que se borren las filas de Documents
, no intercales las tablas.
Optimiza las consultas de datos recientes con marcas de tiempo de confirmación
Las marcas de tiempo de confirmación habilitan una optimización de Spanner que puede reducir la E/S de consulta cuando se recuperan datos escritos después de un tiempo.
Para activar esta optimización, la cláusula WHERE
de una consulta debe incluir un
comparación entre la columna de marca de tiempo de confirmación de una tabla y una hora específica
que proporcionas con los siguientes atributos:
Proporciona la hora específica como una expresión constante: un literal, una parámetro o una función cuyos propios argumentos se evalúan como constantes.
Compara si la marca de tiempo de confirmación es más reciente que la en un momento determinado, a través de los operadores
>
o>=
.De manera opcional, agrega más restricciones a la cláusula
WHERE
conAND
. Si extiendes la cláusula conOR
, la consulta no se beneficia de esta optimización.
Por ejemplo, considera la siguiente tabla Performances
, que incluye
en una columna de marcas de tiempo de confirmación:
CREATE TABLE Performances (
SingerId INT64 NOT NULL,
VenueId INT64 NOT NULL,
EventDate DATE,
Revenue INT64,
LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true)
) PRIMARY KEY (SingerId, VenueId, EventDate);
Esta consulta se beneficia de la optimización de la marca de tiempo de confirmación que se describe anteriormente, ya que tiene una comparación mayor o igual entre la columna de marca de tiempo de confirmación de la tabla y una expresión constante, en este Caso, literal:
SELECT * FROM Performances WHERE LastUpdateTime >= "2022-05-01";
La siguiente consulta también califica para la optimización, ya que tiene un comparación mayor que entre la marca de tiempo de confirmación y una función cuyos argumentos se evalúan como constantes durante la ejecución de la consulta:
SELECT * FROM Performances
WHERE LastUpdateTime > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY);
¿Qué sigue?
- Usa las marcas de tiempo de confirmación para crear un registro de cambios con Go.