Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

increment field in BigQuery for an Appsheet app which uses as Data Source bigquery tables

Hello!

I have an app created in Appsheet, using as Data Source Bigquery's tables. I need a field in order to have an incremental series for user reports.

Appsheet doesn't have an autoincrementing field; if I use Max() +1 , it is not ok because, if several users click on "Save" button at the same time, we will have duplicates of number, for example, if the last number is 5 and 3 users save their report at the same time, we will have 3 new records with the number =6 instead of 3 new records number 6,7,8.

Could anyone help me by giving me an idea what should I do in Bigquery in order to obtain an incremental field when a new record is created in the bq table?

Thank you!

Regards!

Ruxandra

p.s. I am not allowed to use a Sql Db.

 

 

1 1 721
1 REPLY 1

Ensuring reliable auto-incrementing fields in BigQuery for use with Appsheet requires a combination of BigQuery's powerful capabilities and strategic adjustments within the Appsheet app. The challenge of creating a unique, incrementing identifier for each record is especially pronounced when dealing with concurrent user actions, such as multiple users saving records simultaneously. This essay outlines an effective solution that leverages BigQuery's GENERATE_UUID() function and Appsheet's virtual columns, alongside additional considerations for high throughput scenarios.

To begin with, BigQuery offers robust functionality for generating unique identifiers through the GENERATE_UUID() function. By incorporating a unique identifier column in your BigQuery table, you can ensure that each new row has a unique and non-repeating value. This column should be defined with a STRING data type and a unique constraint to prevent duplicates. The following SQL statement illustrates the creation of such a table:

CREATE TABLE your_dataset.your_table (
  other_columns STRING,
  unique_identifier STRING NOT NULL DEFAULT GENERATE_UUID(),
  CONSTRAINT unique_identifier_unique UNIQUE (unique_identifier)
);

In addition to creating the table, adding an index on the unique_identifier column can significantly enhance performance, particularly for large datasets. This can be achieved with the following SQL command:

CREATE INDEX idx_unique_identifier ON your_dataset.your_table(unique_identifier);

Within Appsheet, the next step involves creating a virtual column to generate the sequential report numbers based on the unique identifiers. The virtual column, referred to as ReportNumber, can be created using an Appsheet expression that counts the number of rows with unique identifier values less than or equal to the current row's identifier. The expression is as follows:

COUNT(
  SELECT(YourTable[unique_identifier], 
         [unique_identifier] <= [_THISROW].[unique_identifier])
)

This approach leverages the ordering of UUIDs, which are generated in a manner that correlates roughly with time, to provide a sequential report number.

The benefits of this method are twofold. First, the use of BigQuery's GENERATE_UUID() function guarantees uniqueness, thereby eliminating the risk of collisions even when multiple users save records simultaneously. Second, the virtual column in Appsheet creates a sequential ordering based on the UUIDs, ensuring that each report number is unique and incremented correctly.

However, there are additional considerations to ensure optimal performance and functionality. For instance, displaying the actual UUIDs in your app can be useful for reference or debugging purposes, and this can be accomplished by creating another virtual column. Performance can be further enhanced by adding an index on the unique_identifier column, which is particularly beneficial as the table grows in size.

For scenarios requiring extremely high write throughput and absolute precision in sequence management, an alternative approach involving a stored procedure or a Cloud Function can be explored. This method involves creating a sequence table to maintain the current maximum value of the report number and a stored procedure to handle the insertion of records and incrementing logic within a transaction. The following SQL commands outline the creation and initialization of the sequence table:

CREATE TABLE your_dataset.sequence_table (
  sequence_name STRING NOT NULL,
  current_value INT64 NOT NULL
);

INSERT INTO your_dataset.sequence_table (sequence_name, current_value) VALUES ('report_number', 0);

The stored procedure can then be defined as follows:

CREATE OR REPLACE PROCEDURE your_dataset.insert_with_increment(
  id STRING,
  other_fields STRING
)
BEGIN
  DECLARE new_report_number INT64;

  -- Start a transaction
  BEGIN TRANSACTION;

  -- Get the current max value and increment it
  SET new_report_number = (
    SELECT current_value + 1
    FROM your_dataset.sequence_table
    WHERE sequence_name = 'report_number'
    FOR UPDATE
  );

  -- Update the sequence table with the new max value
  UPDATE your_dataset.sequence_table
  SET current_value = new_report_number
  WHERE sequence_name = 'report_number';

  -- Insert the new record with the incremented value
  INSERT INTO your_dataset.your_table (id, unique_identifier, report_number, other_fields)
  VALUES (GENERATE_UUID(), new_report_number, other_fields);

  -- Commit the transaction
  COMMIT TRANSACTION;
END;

The proposed solution combines the unique identifier capabilities of BigQuery with the virtual column functionality of Appsheet to create a reliable auto-incrementing system. For high throughput scenarios, a stored procedure or Cloud Function can provide precise sequence management. It is crucial to ensure that the Appsheet app has the necessary permissions to read and write to the BigQuery table, including any stored procedures used.