Cloud spanner最佳实践INTERLEAVE问题

时间:2017-09-15 18:43:06

标签: google-cloud-platform google-cloud-spanner

让我们在docs中定义表格:

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 相册 歌曲 即可。表 相册 INTERLEAVE 歌手和表 歌曲 INTERLEAVE 歌手相册

我的问题是,如果我们想搜索关于某位歌手的所有信息,我们可以搜索表歌曲,如果歌手有专辑但没有任何歌曲吗?如果不是,那么回顾歌手所有数据的最佳做法是什么(所有专辑和歌曲(如果他有的话))。如果我们在歌曲中找不到任何内容(因为歌手可以有一张专辑但歌曲正在开发中),我想在桌上搜索歌曲(在歌曲中可以找到专辑,然后在歌词中搜索)(因为即使是专辑也可以在开发中)我认为这不是最佳解决方案。

在我的情况下,提出查询的用户并不知道歌手是否有任何歌曲或专辑,但想要回复有关歌手的所有信息(如果可能,请在一次分组中)。

2 个答案:

答案 0 :(得分:0)

我建议使用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 - 不确定你的意思" split"这里 - "检索有关歌手的所有信息(如果可能的话,在一次分割中)。"

答案 1 :(得分:0)

我已经找到了两个解决方案:

  1. 在这种情况下,我们有3个表扫描:歌手,专辑,歌曲。

    选择 singers.singerId,albums.albumId,songs.trackId
    来自歌手 左连接专辑ON singers.singerId = albums.singerid
    左连接歌曲ON albums.albumid = songs.albumid

  2. 有一个表格如下:

  3. 表架构:

    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,但我不知道它是否最好,因为服务器将在服务器之间分割数据,所以我们将结束在拆分之间进行多次选择。)

    你认为什么样的解决方案效果最好,如果你有什么我想念的东西请解释。