Let's say I have a "Dashboard" object that contains various "Pages". The "Pages" table looks like this:
Page
- ID (PK)
- DashboardID (FK)
- Name (VARCHAR)
- DeletedAt (TIMESTAMP)
I want to ensure that each dashboard has uniquely-named (non-deleted) pages. For example, a dashboard with the following pages is fine:
Pages: [(1, 1, "Sales", NULL), (1, 2, "Product", NULL)
Pages: [(1, 1, "Sales", NULL), (1, 2, "Sales", "2014-01-01T00:00:00")
But this is not:
Pages: [(1, 1, "Sales", NULL), (1, 2, "Sales", NULL)
What would be the proper way to create an index on this? Essentially I'd want something like:
CREATE UNIQUE INDEX ON Page(DashboardID, Name) # WHERE DeletedAt IS NOT NULL
What would be the proper way to do this in Spanner? I believe this is the concept of a "Partial Index" in Postgres: https://www.postgresql.org/docs/8.0/indexes-partial.html.
Perhaps this is the correct approach? https://cloud.google.com/spanner/docs/generated-column/how-to#create_a_partial_index_using_a_generated_column.
Yes, the approach that you are suggesting yourself is the right approach. So in your specific case that would mean using the following schema (Dashboard column left out for simplicity):
The unique null-filtered index will only contain the entries where the column that is indexed is not null, and the uniqueness will therefore also only be applied to the actual values in that index.
Source: https://cloud.google.com/spanner/docs/generated-column/how-to#create_a_partial_index_using_a_generated_column.