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.
Descripción general de las marcas de tiempo de confirmación
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. Puedes almacenar la confirmación de forma atómica marca de tiempo de una transacció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 de tipo
SPANNER.COMMIT_TIMESTAMP
. Por ejemplo:CREATE TABLE Performances ( ... LastUpdateTime SPANNER.COMMIT_TIMESTAMP NOT NULL, ... PRIMARY KEY (...) ) ;
Si realizas inserciones o actualizaciones con DML, usa la función
SPANNER.PENDING_COMMIT_TIMESTAMP()
para escribir la marca de tiempo de confirmación.Si realiza inserciones o actualizaciones con declaraciones preparadas o mutaciones, usa la cadena de marcador de posición
SPANNER.COMMIT_TIMESTAMP()
para tu marca de tiempo de confirmación. También puedes usar de confirmación de la marca de tiempo que proporciona la biblioteca cliente. Por ejemplo, este en el cliente de Java esValue.COMMIT_TIMESTAMP
.
Cuando Spanner confirma la transacción usando estos marcadores de posición como valores de columna, la marca de tiempo de confirmación real se escribe en la columna especificada. 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 SPANNER.COMMIT_TIMESTAMP
.
columnas.
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.
Evita los hotspots
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 SPANNER.COMMIT_TIMESTAMP NOT NULL, UserId bigint NOT NULL, ... PRIMARY KEY (LastAccess, UserId) ) ;
La columna de clave primaria de la marca de tiempo de confirmación como la primera parte 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.
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 SPANNER.COMMIT_TIMESTAMP;
Escribe una marca de tiempo de confirmación con una declaración DML
Usa la función SPANNER.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 la tabla Performances
con la marca de tiempo de confirmación:
UPDATE Performances SET LastUpdateTime = SPANNER.PENDING_COMMIT_TIMESTAMP()
WHERE SingerId=1 AND VenueId=2 AND EventDate="2015-10-21"
Inserta una fila con una mutación
Cuando insertas una fila, Spanner escribe el valor de la marca de tiempo de confirmación solo si incluyes la columna en la lista de columnas y pasas la cadena del marcador de posición spanner.commit_timestamp()
(o la constante de la biblioteca cliente) como su valor. Por ejemplo:
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
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.
Actualiza una fila con una mutación
Cuando actualizas una fila, Spanner escribe el valor de la marca de tiempo de confirmación solo si incluyes la columna en la lista de columnas y pasas la cadena del marcador de posición spanner.commit_timestamp()
(o la constante de la biblioteca cliente) como su valor. No puedes actualizar la clave primaria de una fila. Si quieres actualizar la clave principal, borra la fila existente y crea una nueva.
Por ejemplo, para actualizar una columna de marcas de tiempo de confirmación llamada LastUpdateTime
, realiza lo siguiente:
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
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
En tu código, 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 disponible) 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. Una forma fácil de confirmar que un valor es anterior es compararlo con el valor que muestra la función de SQL CURRENT_TIMESTAMP
.
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 int8 NOT NULL,
DocumentId int8 NOT NULL,
Contents text NOT NULL,
PRIMARY KEY (UserId, DocumentId)
);
CREATE TABLE DocumentHistory (
UserId int8 NOT NULL,
DocumentId int8 NOT NULL,
Ts SPANNER.COMMIT_TIMESTAMP NOT NULL,
Delta text,
PRIMARY KEY (UserId, DocumentId, Ts)
) INTERLEAVE IN PARENT Documents;
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 inserción de la fila nueva en DocumentHistory
, usa el marcador de posición spanner.commit_timestamp()
(o la constante de la biblioteca cliente) para indicar a Spanner que escriba 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 momento determinado.
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, un 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 una columna de marca de tiempo de confirmación:
CREATE TABLE Performances (
SingerId bigint NOT NULL,
VenueId bigint NOT NULL,
EventDate timestamp with time zone NOT NULL,
Revenue bigint,
LastUpdateTime spanner.commit_timestamp,
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-01-01';