Для отношения 1-много при использовании чередующихся таблиц первичный ключ дочерней строки уже содержит первичный ключ своего родителя, поэтому получить родительский элемент тривиальнострока.
CREATE TABLE parent (
parent_key INT64 NOT NULL,
...
) PRIMARY KEY (parent_key);
CREATE TABLE child (
parent_key INT64 NOT NULL,
child_key INT64 NOT NULL,
...
) PRIMARY KEY (parent_key, child_key),
INTERLEAVE IN PARENT parent ON DELETE CASCADE;
Если по какой-то причине у вас нет ключа родителя, а есть только ключ дочернего элемента, то для эффективности вам потребуется создать индекс для обратного просмотра:
CREATE INDEX child_to_parent_index
ON child (
child_key
);
и принудительное использование этого индекса при выполнении запроса для родителя:
SELECT
p.*
FROM
parent as p
JOIN
child@{FORCE_INDEX=child_by_id_index} AS c ON p.parent_key = c.parent_key
WHERE
c.child_key = @CHILD_KEY_VALUE;
Многие-многие отношения должны были бы быть реализованы с использованием связывания таблицы 'mapping'table1-key
до table2-key
.Вам также понадобится индекс верхнего уровня, чтобы получить эффективный обратный поиск, и использовать в своих запросах директиву FORCE_INDEX
, как указано выше.
И, как упоминалось @adi, ограничения внешнего ключа должны будут выполняться с помощьюприложение.
CREATE TABLE table1 (
table1_key INT64 NOT NULL,
...
) PRIMARY KEY (table1_key);
CREATE TABLE table2 (
table2_key INT64 NOT NULL,
...
) PRIMARY KEY (table2_key);
CREATE TABLE table1_table2_map (
table1_key INT64 NOT NULL,
table2_key INT64 NOT NULL,
) PRIMARY KEY (table1_key, table2_key);
CREATE INDEX table2_table1_map_index
ON table1_table2_map (
table2_key
) STORING (
table1_key
);
Ваше приложение будет отвечать за сохранение ссылочной целостности таблицы сопоставления - удаление строк сопоставления при удалении строк в table1
или table2
Есливы хотите использовать таблицы с чередованием, тогда, если вашему приложению необходимо выполнить двунаправленный поиск, вам, возможно, придется создать 2 таблицы сопоставления - как дочерний элемент каждого родителя, так что поиск сопоставлений в обоих направлениях одинаково эффективен.
CREATE TABLE table1 (
table1_key INT64 NOT NULL,
...
) PRIMARY KEY (table1_key);
CREATE TABLE table2 (
table2_key INT64 NOT NULL,
...
) PRIMARY KEY (table2_key);
CREATE TABLE table1_table2_map (
table1_key INT64 NOT NULL,
table2_key INT64 NOT NULL,
) PRIMARY KEY (table1_key, table2_key),
INTERLEAVE IN PARENT table1 ON DELETE CASCADE;
CREATE TABLE table2_table1_map (
table2_key INT64 NOT NULL,
table1_key INT64 NOT NULL,
) PRIMARY KEY (table2_key, table1_key),
INTERLEAVE IN PARENT table2 ON DELETE CASCADE;
Обратите внимание, что приложению необходимо поддерживать обе этих таблиц сопоставления в актуальном состоянии - т.е. при удалении строки из таблицы1 приложение должно получить ссылочные значения table2_key
и удалитьсопоставления из table2_table1_map
(и наоборот).