Administración de valores predeterminados de la clave primaria

En esta página, se analizan las estrategias que se deben usar para generar valores de clave primaria en la tabla con expresiones de valores predeterminadas. Estas estrategias tienen los siguientes beneficios:

  • Cómo evitar la generación de hotspots
  • Simplifica las migraciones desde otras bases de datos
  • Encapsula la lógica de la clave en la base de datos para que no tengas que preocuparte por administrarla en tu aplicación.

Puedes usar las siguientes estrategias en una columna que tenga expresiones DEFAULT:

  • Una función de UUID que genera valores de la versión 4 del UUID.
  • Un objeto de esquema, SEQUENCE, que tiene una opción bit_reversed_positive. SEQUENCE está disponible para GoogleSQL y PostgreSQL.

Métodos para generar claves primarias automáticamente

Identificador único universal (UUID)

Spanner puede generar de forma automática una string versión 4 de UUID para usarla como clave primaria. Los UUID funcionan bien para aplicaciones nuevas y tablas con muchas filas. Se distribuyen de manera más uniforme en el espacio de claves, lo que evita la generación de hotspots a gran escala. La generación de UUID puede crear una gran cantidad de valores (2122) y cada valor es único en efecto. Por ejemplo, necesitarías valores de 2.71 × 1018 para una probabilidad del 50% de colisión o 1, 000 millones por segundo durante 86 años. Esto garantiza valores únicos cuando lo usas en tablas grandes. Los UUID son únicos, ya sea que los generes en la base de datos o en el cliente. Te recomendamos que uses UUID siempre que sea posible. Puedes mezclar de forma segura los UUID generados por el cliente y por Spanner en la misma tabla si los UUID generados por el cliente se serializan en minúsculas, de acuerdo con RFC 4122.

Si una columna necesita valores predeterminados, puedes usar la función GENERATE_UUID para generarlos. En el siguiente ejemplo, se muestra cómo crear una tabla en la que la columna de claves FanId tiene GENERATE_UUID en la columna de valor como su valor predeterminado. En el ejemplo, se usan 36 caracteres para los atributos STRING de GoogleSQL y varchar de PostgreSQL porque los UUID tienen 36 caracteres. Cuando usas la declaración INSERT with THEN RETURN para insertar en la tabla Fans, GENERATE_UUID genera y muestra un valor de UUID para FanId.

GoogleSQL

CREATE TABLE Fans (
  FanId STRING(36) DEFAULT (GENERATE_UUID()),
  Name STRING(MAX),
) PRIMARY KEY (FanId);

PostgreSQL

CREATE TABLE Fans (
  FanId varchar(36) DEFAULT spanner.generate_uuid(),
  Name text,
  PRIMARY KEY (FanId)
);

GoogleSQL

INSERT INTO Fans (Name) VALUES ('Melissa Garcia')
THEN RETURN FanId;

PostgreSQL

INSERT INTO fans (name) VALUES ('Melissa Garcia')
RETURNING (fanid);

Esta declaración muestra un resultado similar al siguiente:

FanId
6af91072-f009-4c15-8c42-ebe38ae83751

Para obtener más información sobre la función GENERATE_UUID(), consulta la página de referencia de GoogleSQL o PostgreSQL.

Secuencia de bits inversa

Una secuencia inversa de bits es un objeto de esquema que produce una secuencia de números enteros y los revierte los bits. Este objeto usa la reversión de bits en un contador de Spanner interno y privado para garantizar la exclusividad. Los valores invertidos en bits resultantes ayudan a evitar la generación de hotspots a gran escala cuando se usan en una clave primaria.

En Spanner, usa declaraciones DDL SEQUENCE junto con el atributo bit_reversed_positive para crear, modificar o descartar una secuencia que produce valores positivos invertidos en los bits (GoogleSQL o PostgreSQL).

Cada secuencia mantiene un conjunto de contadores internos y los usa para generar un valor. El contador de secuencias proporciona la entrada al algoritmo de reversión de bits.

Cuando defines una columna con una expresión DEFAULT que usa la función GET-NEXT-SEQUENCE-VALUE de GoogleSQL o la función nextval de PostgreSQL como su valor predeterminado, Spanner llama de forma automática a la función y coloca los valores de resultado invertidos en los bits en la columna. Las secuencias invertidas de bits son especialmente útiles para las claves primarias, ya que los valores invertidos de bits se distribuyen de manera uniforme en el espacio de claves para que no causen generación de hotspots.

En el siguiente ejemplo, se muestra cómo crear una secuencia con inversión de bits y una tabla en la que su columna de clave usa la secuencia como valor predeterminado:

GoogleSQL

CREATE SEQUENCE SingerIdSequence OPTIONS (
  sequence_kind="bit_reversed_positive"
);

CREATE TABLE Singers (
  SingerId INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE SingerIdSequence)),
  Name STRING(MAX),
  Rank INT64,
) PRIMARY KEY (SingerId);

PostgreSQL

CREATE SEQUENCE SingerIdSequence bit_reversed_positive;

CREATE TABLE Singers (
  SingerId bigint DEFAULT nextval('SingerIdSequence'),
  Name text,
  PRIMARY KEY (SingerId)
);

Luego, puedes usar la siguiente instrucción de SQL para insertar y mostrar el valor de la clave primaria:

GoogleSQL

INSERT INTO Singers (Name) VALUES ('Melissa Garcia')
THEN RETURN SingerId;

PostgreSQL

INSERT INTO Singers (name) VALUES ('Melissa Garcia')
RETURNING (SingerId);

Esta declaración muestra un resultado similar al siguiente:

SingerId
3458764513820540928

Situaciones en las que se usan UUID y secuencias como valores predeterminados para claves primarias

Los casos de UUID y secuencias incluyen los siguientes:

  • Aplicaciones nuevas
  • Migraciones

En las siguientes secciones, se describe cada situación.

Aplicaciones nuevas

Si tu aplicación existente requiere claves INT64 en GoogleSQL o claves bigint en PostgreSQL, Spanner ofrece el objeto de esquema de secuencia positivo invertido en bits (PostgreSQL o GoogleSQL). De lo contrario, para aplicaciones nuevas, te recomendamos que uses el identificador único universal (UUID). Para obtener más información, consulta Usa un identificador único universal (UUID).

Migraciones

Para las migraciones de tablas a Spanner, tienes algunas opciones:

¿Qué sigue?