Gestión de valores predeterminados de claves principales

En esta página se describen las estrategias que puede usar para generar valores de clave principal en su tabla mediante expresiones de valor predeterminado. La información de esta página se aplica tanto a las bases de datos con dialecto de GoogleSQL como a las bases de datos con dialecto de PostgreSQL. Estas estrategias tienen las siguientes ventajas:

  • Evitar los puntos de acceso
  • Simplifica las migraciones desde otras bases de datos
  • Encapsula la lógica clave en la base de datos para no tener que preocuparte por gestionarla en tu aplicación.
  • En la mayoría de los casos, sustituye la necesidad de crear y gestionar tus propias secuencias.

Métodos para generar claves principales automáticamente

Para generar automáticamente valores de clave principal, puede usar las siguientes estrategias en una columna que tenga expresiones DEFAULT:

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

Métodos para generar claves principales automáticamente

En esta sección se describe cómo generar automáticamente UUIDs y secuencias invertidas de bits para usarlos como valores de clave principal.

Identificador único universal (UUID)

Spanner puede generar automáticamente una cadena UUID de la versión 4 para usarla como clave principal. Los UUIDs funcionan bien en aplicaciones y tablas nuevas con muchas filas. Se distribuyen de forma más o menos uniforme en el espacio de claves, lo que evita que se produzcan puntos de acceso a gran escala. La generación de UUIDs puede crear un gran número de valores (2122) y cada valor es único. Por ejemplo, necesitarías 2,71 × 1018 valores para tener una probabilidad del 50% de que se produzca una colisión, o bien 1000 millones por segundo durante 86 años. De esta forma, se asegura de que los valores sean únicos cuando la use en tablas grandes. Los UUIDs son únicos, tanto si los generas en la base de datos como en el cliente. Te recomendamos que uses UUIDs siempre que sea posible. Puedes combinar de forma segura UUIDs generados por el cliente y por Spanner en la misma tabla si los UUIDs generados por el cliente se serializan en minúsculas, de acuerdo con RFC 4122.

En el caso de las columnas que necesiten valores predeterminados, puede 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 clave FanId tiene GENERATE_UUID en la columna de valor como valor predeterminado. En el ejemplo se usan 36 caracteres para los atributos de GoogleSQL STRING y PostgreSQL varchar porque los UUIDs tienen 36 caracteres. Cuando usas la instrucción INSERT with THEN RETURN para insertar datos en la tabla Fans, GENERATE_UUID genera y devuelve un valor 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 instrucción devuelve 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.

IDENTITY columnas

Con las columnas IDENTITY, puede generar automáticamente valores enteros para columnas de clave y sin clave. Las columnas IDENTITY no requieren que los usuarios mantengan manualmente una secuencia subyacente ni que gestionen la relación entre la columna y la secuencia subyacente. Cuando se elimina una columna de identidad generada automáticamente, también se elimina automáticamente la secuencia subyacente.

Puede usar columnas IDENTITY proporcionando un valor entero inicial al generar la secuencia o dejando que Spanner genere la secuencia de enteros por usted. Para proporcionar un valor entero inicial, debes usar la opción START COUNTER WITH y un valor inicial INT64 positivo. Spanner usa este valor para definir el siguiente valor de su contador de secuencia interno generado automáticamente e invierte los bits del valor antes de insertarlo en esta columna.

En Spanner, las columnas IDENTITY se admiten tanto en GoogleSQL como en PostgreSQL.

GoogleSQL

En el siguiente ejemplo se muestra cómo usar columnas IDENTITY para crear una columna de clave principal entera generada automáticamente para SingerId al crear una tabla con el comando CREATE TABLE:

CREATE TABLE Singers (
  SingerId INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
  Name STRING(MAX),
  Rank INT64
) PRIMARY KEY (SingerId);

También puedes especificar el inicio del contador de la columna con la opción START_WITH_COUNTER. En el ejemplo siguiente, se crea una columna de números enteros generada automáticamente para SingerId que tiene valores positivos invertidos y un contador interno que empieza en 1000.

CREATE TABLE Singers (
  SingerId INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE START COUNTER WITH 1000),
  Name STRING(MAX),
  Rank INT64
) PRIMARY KEY (SingerId);

PostgreSQL

En el siguiente ejemplo se muestra cómo usar columnas IDENTITY para crear una columna de números enteros generada automáticamente para SingerId al crear una tabla con el comando CREATE TABLE:

CREATE TABLE Singers (
  SingerId bigint GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
  Name text,
  PRIMARY KEY (SingerId)
);

También puedes especificar el inicio del contador de la columna con la opción START COUNTER WITH. En el ejemplo siguiente, se crea una columna de números enteros generada automáticamente para SingerId, que genera valores positivos invertidos bit a bit. El contador interno, antes de invertir los bits,empieza en 1000.

CREATE TABLE Singers (
  SingerId bigint GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE START COUNTER WITH 1000),
  Name text,
  PRIMARY KEY (SingerId)
);

SERIAL y AUTO_INCREMENT

Spanner admite SERIAL en PostgreSQL y AUTO_INCREMENT en GoogleSQL, que son alias de DDL de las columnas IDENTITY y se usan para crear columnas de números enteros únicos. Primero debes definir la opción de base de datos default_sequence_kind antes de usar SERIAL o AUTO_INCREMENT. Puedes usar la siguiente instrucción SQL para definir la opción default_squence_kind de la base de datos:

GoogleSQL

ALTER DATABASE db SET OPTIONS (default_sequence_kind = 'bit_reversed_positive');

CREATE TABLE Singers (
  id INT64 AUTO_INCREMENT PRIMARY KEY,
  name STRING(MAX),
)

PostgreSQL

ALTER DATABASE db SET spanner.default_sequence_kind = 'bit_reversed_positive';

CREATE TABLE Singers (
  id serial PRIMARY KEY,
  name text
);

Ten en cuenta que, como SERIAL y AUTO_INCREMENT se asignan a columnas IDENTITY, no los verás cuando serialices tu esquema. En este esquema, el resultado de GetDatabaseDDL sería el siguiente:

GoogleSQL

ALTER DATABASE db SET OPTIONS (default_sequence_kind = 'bit_reversed_positive');

CREATE TABLE Singers (
  id INT64 GENERATED BY DEFAULT AS IDENTITY,
  name STRING(MAX),
) PRIMARY KEY (id);

PostgreSQL

ALTER DATABASE db SET spanner.default_sequence_kind = 'bit_reversed_positive';

CREATE TABLE Singers (
  id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
  name character varying,
  PRIMARY KEY(id)
);

Secuencia invertida por bits

Una secuencia invertida de bits es un objeto de esquema que genera una secuencia de números enteros y los invierte. Este objeto usa la inversión de bits en un contador interno privado de Spanner para asegurar la unicidad. Los valores invertidos en bits resultantes ayudan a evitar los puntos de acceso a gran escala cuando se usan en una clave principal.

En Spanner, se usan instrucciones DDL SEQUENCE junto con el atributo bit_reversed_positive para crear, modificar o eliminar una secuencia que produce valores positivos invertidos en bits (GoogleSQL o PostgreSQL).

Cada secuencia mantiene un conjunto de contadores internos y los usa para generar un valor. El contador de secuencia proporciona la entrada al algoritmo de inversió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 valor predeterminado, Spanner llama automáticamente a la función y coloca los valores de salida invertidos en bits en la columna. Las secuencias invertidas por bits son especialmente útiles para las claves principales, ya que los valores invertidos por bits se distribuyen de forma uniforme en el espacio de claves, por lo que no provocan puntos de acceso.

En el siguiente ejemplo se muestra cómo crear una secuencia invertida de bits y una tabla en la que la 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)
);

A continuación, puede usar la siguiente instrucción SQL para insertar y devolver el valor de la clave principal:

GoogleSQL

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

PostgreSQL

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

Esta instrucción devuelve un resultado similar al siguiente:

SingerId
3458764513820540928

Situaciones en las que se usan UUIDs y secuencias como valores predeterminados de claves principales

Los casos de uso de UUIDs y secuencias incluyen los siguientes:

  • Nuevas aplicaciones
  • Migraciones

En las siguientes secciones se describe cada uno de estos casos.

Nuevas aplicaciones

Si tu aplicación requiere claves INT64 en GoogleSQL o claves bigint en PostgreSQL, Spanner ofrece el objeto de esquema de secuencia positiva invertida en bits (PostgreSQL o GoogleSQL). De lo contrario, en las aplicaciones nuevas, te recomendamos que uses identificadores únicos universales (UUID). Para obtener más información, consulta Utilizar un identificador único universal (UUID).

Migraciones

Para migrar tablas a Spanner, tienes varias opciones:

  • Si usas UUIDs en tu base de datos de origen, en Spanner puedes usar una columna de clave del tipo STRING y la función GENERATE_UUID() (GoogleSQL o PostgreSQL) como valor predeterminado.
  • Si usas una clave principal entera y tu aplicación solo necesita que la clave sea única, puedes usar una columna de clave en INT64 y usar una secuencia positiva invertida por bits para el valor predeterminado de la clave principal. Consulta Migrar columnas de claves invertidas por bits.
  • Spanner no admite ninguna forma de generar valores monotónicos.

    Si usas una clave monotónica, como el tipo SERIAL de PostgreSQL o el atributo AUTO_INCREMENT de MySQL, y necesitas claves monotónicas nuevas en Spanner, puedes usar una clave compuesta. Para obtener más información, consulta Cambiar el orden de las claves y Aplicar un hash a la clave única y distribuir las escrituras en fragmentos lógicos.

  • Si tu aplicación invierte manualmente los bits de tu clave INT64 en GoogleSQL o de tu clave bigint en PostgreSQL, puedes usar una secuencia positiva invertida por bits (GoogleSQL o PostgreSQL) para generar nuevos valores de clave. Para obtener más información, consulta Migrar columnas de clave con bits invertidos.

Siguientes pasos