Cloud Spanner 最佳实践 INTERLEAVE 问题
Cloud spanner best practice INTERLEAVE questions
让我们采用文档中的 tables 定义:
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;
CREATE TABLE Songs (
SingerId INT64 NOT NULL,
AlbumId INT64 NOT NULL,
TrackId INT64 NOT NULL,
SongName STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId, TrackId),
INTERLEAVE IN PARENT Albums ON DELETE CASCADE;
所以我们有 3 tables 歌手, 专辑 和 歌曲。 Table专辑交织歌手和table歌曲交织歌手和专辑。
我的问题是,如果我们想要搜索有关特定歌手的所有信息,如果歌手有专辑但还没有任何歌曲,我们可以在 table 歌曲中搜索吗?如果不是,检索歌手的所有数据(所有专辑和歌曲(如果他有的话))的最佳做法是什么。如果我们在歌曲中找不到任何东西,我想在 table 歌曲中搜索(因为歌手可以有专辑,但歌曲正在开发中)在 table 专辑中搜索,然后在歌手中搜索(因为即使是专辑可以在开发中),但我认为这不是最好的解决方案。
在我的例子中,进行查询的用户不知道歌手是否有任何歌曲或专辑,但想检索有关歌手的所有信息(如果可能,一次拆分)。
我建议使用 JOINs,可能会避免 3 次单独读取(类似的东西..)
select singers.singerId, albums.albumId, songs.trackId
from singers left join albums ON singers.singerId = albums.singerid
left join songs ON songs.SingerId = singers.singerId
order by singerId, albumId;
从 child/interleaved table 中读取没有相应的行 return 空结果,因此需要 3 个单独的读取请求 -
select * from albums order by singerId, albumId;
SingerId AlbumId AlbumTitle
1 1 Total Junk
1 2 Go, Go, Go
.. more rows ..
虽然查询 child table - 这个 return 没有结果,因为 table 没有歌手 ID = 1 的歌曲:
select * from songs where singerId = 1 order by singerId, albumId;
没有结果。
查询没有 return 任何行。
PS - 不确定这里的 "split" 是什么意思 -
"to retrive all the info about singer(in one split if possible)."
我得出了两个解决方案:
在这种情况下,我们有 3 table 扫描:歌手、专辑、歌曲。
select singers.singerId, albums.albumId, songs.trackId
来自歌手
左加入相册开启 singers.singerId = albums.singerid
左加入歌曲 ON albums.albumid = songs.albumid
有一个table喜欢:
Table 架构:
CREATE TABLE Singers (
SingerId INT64 NOT NULL,
AlbumId INT64,
SongId INT64,
.
.(informations about Singer, Album and Song)
.
) PRIMARY KEY (SingerId);
所以我们会有这样的东西:
SingerId AlbumId SongId SingerName AlbumName SongName
1 Singer 1
1 1 Album 1
1 1 1 Song 1
1 1 2 Song 2
1 1 3 Song 3
1 1 Album 2
1 2 1 Song 1
1 2 2 Song 2
1 2 3 Song 3
通过 1 个查询,我们可以恢复所有关于 Singer 的数据。(我们有 1 个大 table 扫描,而不是 3 个,但我不知道这是否是最佳实践,因为服务器将再次将数据拆分为服务器,因此我们将在拆分之间以多个 select 结束。
您认为哪种解决方案效果最好,如果您有任何我遗漏的地方,请解释。
让我们采用文档中的 tables 定义:
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;
CREATE TABLE Songs (
SingerId INT64 NOT NULL,
AlbumId INT64 NOT NULL,
TrackId INT64 NOT NULL,
SongName STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId, TrackId),
INTERLEAVE IN PARENT Albums ON DELETE CASCADE;
所以我们有 3 tables 歌手, 专辑 和 歌曲。 Table专辑交织歌手和table歌曲交织歌手和专辑。
我的问题是,如果我们想要搜索有关特定歌手的所有信息,如果歌手有专辑但还没有任何歌曲,我们可以在 table 歌曲中搜索吗?如果不是,检索歌手的所有数据(所有专辑和歌曲(如果他有的话))的最佳做法是什么。如果我们在歌曲中找不到任何东西,我想在 table 歌曲中搜索(因为歌手可以有专辑,但歌曲正在开发中)在 table 专辑中搜索,然后在歌手中搜索(因为即使是专辑可以在开发中),但我认为这不是最好的解决方案。
在我的例子中,进行查询的用户不知道歌手是否有任何歌曲或专辑,但想检索有关歌手的所有信息(如果可能,一次拆分)。
我建议使用 JOINs,可能会避免 3 次单独读取(类似的东西..)
select singers.singerId, albums.albumId, songs.trackId
from singers left join albums ON singers.singerId = albums.singerid
left join songs ON songs.SingerId = singers.singerId
order by singerId, albumId;
从 child/interleaved table 中读取没有相应的行 return 空结果,因此需要 3 个单独的读取请求 -
select * from albums order by singerId, albumId;
SingerId AlbumId AlbumTitle
1 1 Total Junk
1 2 Go, Go, Go
.. more rows ..
虽然查询 child table - 这个 return 没有结果,因为 table 没有歌手 ID = 1 的歌曲:
select * from songs where singerId = 1 order by singerId, albumId;
没有结果。 查询没有 return 任何行。
PS - 不确定这里的 "split" 是什么意思 - "to retrive all the info about singer(in one split if possible)."
我得出了两个解决方案:
在这种情况下,我们有 3 table 扫描:歌手、专辑、歌曲。
select singers.singerId, albums.albumId, songs.trackId
来自歌手
左加入相册开启 singers.singerId = albums.singerid
左加入歌曲 ON albums.albumid = songs.albumid有一个table喜欢:
Table 架构:
CREATE TABLE Singers (
SingerId INT64 NOT NULL,
AlbumId INT64,
SongId INT64,
.
.(informations about Singer, Album and Song)
.
) PRIMARY KEY (SingerId);
所以我们会有这样的东西:
SingerId AlbumId SongId SingerName AlbumName SongName
1 Singer 1
1 1 Album 1
1 1 1 Song 1
1 1 2 Song 2
1 1 3 Song 3
1 1 Album 2
1 2 1 Song 1
1 2 2 Song 2
1 2 3 Song 3
通过 1 个查询,我们可以恢复所有关于 Singer 的数据。(我们有 1 个大 table 扫描,而不是 3 个,但我不知道这是否是最佳实践,因为服务器将再次将数据拆分为服务器,因此我们将在拆分之间以多个 select 结束。
您认为哪种解决方案效果最好,如果您有任何我遗漏的地方,请解释。