Prepare and test your skills
Prepare and test your skills
Row key design in Cloud Bigtable (Bigtable) (opens in a new tab) controls how rows are sorted, split across nodes, and accessed by reads and writes. Each row is identified by a single row key, and Bigtable stores rows in sorted key order so nearby keys live together and range scans stay fast. Good key design spreads traffic evenly across nodes, while poor key design forces one node to do most of the work and creates a hotspot.
Data distribution in Bigtable means spreading rows and request load across the nodes in a cluster. Requests flow from applications through an app profile to one or more clusters, where single-cluster routing sends all requests to one cluster and multi-cluster routing sends each request to the nearest available cluster. Bigtable separates storage from compute, so you can add or remove nodes to match query demand and see improvement within minutes without downtime. The Key Visualizer tool shows traffic by key range at the instance, cluster, and table level, so you can see uneven access and adjust key design or node count.
Cluster size in Bigtable must cover both storage and compute needs for the chosen keys and access patterns. For storage planning, divide the total unreplicated data size by 3.5 TB, which is 5 TB per node times a 0.70 utilization target, to estimate nodes needed for SSD storage. For compute planning, divide sustained reads and writes per second by 10,000 to estimate the minimum SSD nodes for throughput, with more nodes needed for low-latency queries. The cluster needs the larger of the two estimates, and each cluster in a multi-cluster instance must store all instance data and handle the total insert rate across the instance.
Structured row keys in Bigtable are multi-column keys that work like composite keys in relational databases. Their type and encoding are defined by an optional row key schema (opens in a new tab) on the table, such as fields for user_id, purchase_date, and order_number joined with a delimitedBytes encoding. Data is still stored as bytes, but GoogleSQL for Bigtable (opens in a new tab) automatically applies the schema types when you run a SQL query. A continuous materialized view has a row key schema by default, while ordinary tables only have one if you add it.
You can view the row key schema for a Bigtable table from the console or from code. In the Google Cloud console, Bigtable Studio shows the schema in the Explorer pane for the selected table. In code, the gcloud CLI and AdminClient expose the same schema definition for automation:
Row key schema definitions list each field name, its type, and its byte encoding in order. You supply that definition as YAML or JSON when you create the schema with the gcloud CLI, including the delimiter used to join fields. The field order matters because it sets the sort order of the encoded keys and therefore which rows stay adjacent for scans.
Querying row keys with GoogleSQL for Bigtable means using SQL to read the special _key column and column-family data together. Each query result contains _key for the row key plus one column per column family, where each family column uses the MAP data type to hold qualifier-to-value pairs. By default each map entry holds the most recent cell value, while adding a temporal filter such as with_history returns all versions as timestamped entries. Because the Bigtable Data API ReadRows method ignores a row key schema, you must use SQL to query structured row-key columns by field.
Type handling in Bigtable affects how row keys and cell values are read back correctly. If no type information is provided, Bigtable treats each cell as bytes with unknown encoding, so data type enforcement (opens in a new tab) must be supplied at write time or with CAST functions at read time. Some operations assume a specific layout:
Exam tip: ReadRows ignores a row key schema, so query structured row-key fields with SQL, not with ReadRows.
Firestore in Native mode (opens in a new tab) is a flexible, scalable NoSQL document database for mobile, web, and server development. Firestore stores application data as documents organized for direct lookup, which makes the choice of how documents are grouped and how queries access them central to performance. Efficient strategies focus on matching the data layout to query patterns and using indexes to minimize read latency.
Firestore in Native mode provides a document model designed for application development across mobile, web, and server workloads. Documents hold the fields an application reads together, so a read can return a complete unit of data without assembling it from many tables. Because Firestore is scalable and flexible, the same database can serve small interactive lookups and larger operational workloads as the application grows. Modeling decisions therefore start from the queries the application will run, not from a normalized table layout.
Indexing in Firestore is the mechanism for making queries fast and efficient. When a query filters or sorts data, Firestore uses an index to locate matching documents directly instead of scanning unrelated data. Query Insights helps apply this in practice by identifying queries that can be optimized with an index. Pipeline operations provide additional ways to query data, and Firestore Enterprise edition provides dedicated guidance for optimizing query performance and understanding how reads and writes scale.
Exam tip: Use Query Insights to identify queries you can optimize with an index.
Managing document data efficiently in Firestore includes controlling data lifetime, recoverability, and operational safety. These capabilities reduce unnecessary reads and protect document-based data as it changes:
Together, TTL policies, backups, and PITR let an application keep the active document set lean for low-latency reads while retaining the ability to recover from deletion, corruption, or operational error.
Relational schema optimization for Cloud Spanner (opens in a new tab) and AlloyDB for PostgreSQL (opens in a new tab) is the practice of choosing keys, indexes, and table structures that distribute load and speed up queries. Cloud Spanner sorts and distributes table rows by primary key across many servers, so key choice directly controls write throughput and data locality. AlloyDB for PostgreSQL is a fully managed, PostgreSQL-compatible service designed for demanding hybrid transactional and analytical processing (HTAP) workloads, where live transactional data can be queried directly through BigQuery federation without change data capture pipelines.
Primary key design in Cloud Spanner determines how rows are sorted and spread across the distributed database. Every table that stores more than one row must have a primary key of one or more columns, and Spanner uses that key to sort rows and distribute them for scale. Sequential keys concentrate new writes on a single server range, creating hotspots that limit write throughput, especially for high-QPS applications. After a primary key is designated, a primary key column cannot be added or removed and a primary key value cannot be changed without deleting and recreating the table, so the choice must scale with future growth.
Cloud Spanner avoids hotspots with non-sequential key generation that spreads writes evenly across the key space. The default recommendation is UUID Version 4 generated with the GENERATE_UUID() function, which returns values stored as STRING type. When integer keys are required, Cloud Spanner supports bit-reversed positive sequences that distribute values evenly across the positive 64-bit number space:
| Key option | Value type | Distribution behavior |
|---|---|---|
UUID Version 4 with GENERATE_UUID() | STRING | Random values prevent concentration of new writes |
| Bit-reversed positive sequence | Integer | Reversed bits spread sequential inserts across the 64-bit space |
Exam tip: Choose UUID Version 4 or bit-reversed sequences for high-write Spanner tables; sequential integers or timestamps as the leading key cause hotspots.
Secondary indexes (opens in a new tab) in Cloud Spanner are structures that index commonly searched columns to speed up lookups without scanning full tables. PostgreSQL b-tree indexes are similar to secondary indexes in Cloud Spanner, which makes migration of indexing concepts straightforward. In a Spanner database, secondary indexes are used to index frequently filtered columns for better performance and to replace UNIQUE constraints from PostgreSQL table definitions, such as a UNIQUE email column in a customer table. Because inefficient schema design limits what query optimization can achieve, adding or changing an index is one of the first schema adjustments to consider during tuning.
Performance tuning in Cloud Spanner is an iterative process where metrics such as CPU utilization and latency are measured, the schema or application is adjusted, and the system is tested again. Tuning is most effective when the test setup is close to live production traffic in throughput and data size, especially for production workloads where surprises must be avoided. Schema changes during tuning include adding or changing an index or changing a primary key, while application changes include batching writes or merging and modifying queries.
Performance testing follows an ordered workflow from loading data to retesting after changes:
Suboptimal query performance during load tests is often caused by several related factors. The database depends on both schema design and application behavior, so all sides must be checked together.
Row key design controls how rows are sorted, split across nodes, and accessed because Cloud Bigtable (Bigtable) stores rows in sorted key order so nearby keys live together and range scans stay fast. Good key design spreads traffic evenly across nodes, while poor key design forces one node to do most of the work and creates a hotspot.
For storage planning, divide the total unreplicated data size by 3.5 TB, which is 5 TB per node times a 0.70 utilization target, to estimate nodes needed for SSD storage. For compute planning, divide sustained reads and writes per second by 10,000 to estimate the minimum SSD nodes for throughput, and the cluster needs the larger of the two estimates.
Cloud Spanner sorts and distributes table rows by primary key across many servers, so sequential keys concentrate new writes on a single server range and create hotspots that limit write throughput. UUID Version 4 generated with GENERATE_UUID() provides random values stored as STRING type and bit-reversed positive sequences spread sequential inserts across the positive 64-bit number space to distribute writes evenly.
Indexing minimizes read latency in Firestore in Native mode by using an index to locate matching documents directly instead of scanning unrelated data when a query filters or sorts data. Query Insights helps apply this in practice by identifying queries that can be optimized with an index.
Last updated