Cloud spanner 最佳实践 INTERLEAVE 问题
Posted
技术标签:
【中文标题】Cloud spanner 最佳实践 INTERLEAVE 问题【英文标题】:Cloud spanner best practice INTERLEAVE questions 【发布时间】:2018-02-25 00:14:52 【问题描述】:让我们以文档中定义的表格为例:
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 个表格 Singers、Albums 和 Songs。 专辑 INTERLEAVE 歌手表和歌曲 INTERLEAVE 歌手表> 和专辑。
我的问题是,如果我们想要搜索有关特定歌手的所有信息,如果歌手有专辑但还没有任何歌曲,我们可以在表 Songs 中搜索吗?如果不是,那么检索歌手的所有数据(所有专辑和歌曲(如果有的话))的最佳做法是什么。如果我们在歌曲中找不到任何内容,我想在表歌曲中搜索(因为歌手可以有一张专辑,但歌曲正在开发中)在表专辑中搜索,然后在歌手中搜索(因为即使专辑也可以在开发中)但我没有'认为这不是最好的解决方案。
在我的情况下,进行查询的用户不知道歌手是否有任何歌曲或专辑,但想检索有关歌手的所有信息(如果可能的话,一次拆分)。
【问题讨论】:
【参考方案1】:我想到了两个解决方案:
在这种情况下,我们有 3 个表扫描:歌手、专辑、歌曲。
选择singer.singerId、albums.albumId、songs.trackId 来自歌手左加入专辑 ONsingers.singerId = albums.singerid 左加入歌曲 ON albums.albumid = song.albumid
有一张像这样的表:
表架构:
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 次大表扫描而不是 3 次,但我不知道这是否最好,因为服务器将在服务器之间拆分数据,所以我们将结束在拆分之间进行多项选择)。
您认为哪种解决方案效果最好,如果您有什么我想念的,请解释一下。
【讨论】:
【参考方案2】:我建议使用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;
从没有相应行的子表/交错表读取返回空结果,因此需要 3 个单独的读取请求 -
select * from albums order by singerId, albumId;
SingerId AlbumId AlbumTitle
1 1 Total Junk
1 2 Go, Go, Go
.. more rows ..
虽然查询子表 - 这不会返回任何结果,因为该表没有 SingerId = 1 的歌曲:
select * from songs where singerId = 1 order by singerId, albumId;
没有结果。 查询未返回任何行。
PS - 不知道你在这里所说的“分裂”是什么意思 - “检索有关歌手的所有信息(如果可能,一次拆分)。”
【讨论】:
以上是关于Cloud spanner 最佳实践 INTERLEAVE 问题的主要内容,如果未能解决你的问题,请参考以下文章
Cloud Spanner 读取与 Cloud Spanner SQL API
Cloud Spanner - `SHOW TABLES` 的等效语法?
如何有效地与多个线程并行查询 google-cloud-spanner?