Запрос по чередующимся полям таблицы с помощью ключа для обработки данных Spring

# #google-cloud-spanner #spring-cloud-gcp #interleave

Вопрос:

Я пытаюсь выполнить запрос по полю чередующейся таблицы с помощью ключа Spring Data. Сравнение идентификаторов автоматически выполняется Spring Data Spanner, когда он выполняет внутреннее соединение СТРУКТУРЫ МАССИВА, но я не могу добавить предложение WHERE в запрос чередующейся таблицы.

Рассматривая приведенный ниже пример:

 CREATE TABLE Singers (
  Id   INT64 NOT NULL,
  FirstName  STRING(1024),
  LastName   STRING(1024),
  SingerInfo BYTES(MAX),
) PRIMARY KEY (Id);

CREATE TABLE Albums (
  SingerId     INT64 NOT NULL,
  Id           INT64 NOT NULL,
  AlbumTitle   STRING(MAX),
) PRIMARY KEY (SingerId, Id),
  INTERLEAVE IN PARENT Singers ON DELETE CASCADE;
 

Предположим, я хочу запросить всех певцов, где AlbumTitle есть «Страх темноты», как я могу написать метод репозитория для достижения этой цели с помощью Spring Data Spanner?

Ответ №1:

Ваш пример, похоже, либо содержит пару опечаток, либо в остальном не совсем корректен:

  1. Во второй таблице есть столбец, который является первичным ключом. Id Это само по себе прекрасно, но при создании иерархии чередующихся таблиц рекомендуется префиксовать столбец первичного ключа именем таблицы. Так что было бы лучше назвать его SingerId .
  2. В Albums таблице есть SingerId столбец и Id столбец. Эти два столбца образуют первичный ключ Albums таблицы. Это технически неверно (и сбивает с толку), а также причина, по которой я думаю, что ваш пример не совсем верен. Поскольку Albums он чередуется Singers , Albums должен содержать те же столбцы первичного ключа Singers , что и таблица, в дополнение к любым дополнительным столбцам, которые образуют первичный ключ Albums . В этом случае Id ссылается на Singers таблицу, и SingerId это дополнительный столбец в Albums таблице, который не имеет ничего общего с Singers таблицей. Столбцы первичного ключа родительской таблицы также должны отображаться в том же порядке, что и в родительской таблице.

Поэтому пример модели данных следует изменить на:

 CREATE TABLE Singers (
  SingerId   INT64 NOT NULL,
  FirstName  STRING(1024),
  LastName   STRING(1024),
  SingerInfo BYTES(MAX),
) PRIMARY KEY (SingerId);

CREATE TABLE Albums (
  SingerId     INT64 NOT NULL,
  AlbumId      INT64 NOT NULL,
  AlbumTitle   STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId),
  INTERLEAVE IN PARENT Singers ON DELETE CASCADE;
 

С этого момента вы можете рассматривать SingerId столбец в Albums таблице как отношение внешнего ключа к a Singer и относиться к нему так же, как к любой другой системе баз данных. Обратите также внимание, что для каждого певца может быть несколько альбомов, поэтому запрос …Я хочу опросить всех певцов, у которых название альбома «Страх темноты» несколько двусмысленно. Я бы скорее сказал:

Дайте мне всех певцов, у которых есть хотя бы один альбом с названием «Страх темноты».

Допустимым запросом для этого был бы:

 SELECT *
FROM Singers
WHERE SingerId IN (
  SELECT SingerId
  FROM Albums
  WHERE AlbumTitle='Fear of the Dark'
)
 

Комментарии:

1. Я понял твою точку зрения, и ты прав. Но моя проблема заключается в выполнении этого запроса с помощью Spring Data Spanner, потому что, по-видимому, я не могу добавить предложение WHERE в запрос чередующейся таблицы (все запросы репозитория автоматически генерируются Spring).

2. Я не совсем уверен, что вы имеете в виду под «запросом к чередующейся таблице». Для Spring Data Spanner отношения между Певцом и Альбомом должны быть во многом такими же, как и обычные отношения с внешним ключом. Кроме того, вы должны иметь возможность просто использовать обычный SQL-запрос для достижения желаемого. Видишь docs.spring.io/spring-cloud-gcp/docs/1.1.0.M1/reference/html/… для примера о том, как выполнить запрос. Если бы вы вставили в него запрос из моего ответа, он (теоретически) должен был бы вернуть именно то, что вы ищете.