【问题标题】:Cloud spanner best practice INTERLEAVE questionsCloud spanner 最佳实践 INTERLEAVE 问题
【发布时间】: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 个表格 SingersAlbumsSongs专辑 INTERLEAVE 歌手表和歌曲 INTERLEAVE 歌手表> 和专辑

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

在我的情况下,进行查询的用户不知道歌手是否有任何歌曲或专辑,但想检索有关歌手的所有信息(如果可能的话,一次拆分)。

【问题讨论】:

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


    【解决方案1】:

    我想到了两个解决方案:

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

      选择singer.singerId、albums.albumId、songs.trackId
      来自歌手
      左加入专辑 ONsingers.singerId = albums.singerid
      左加入歌曲 ON albums.albumid = song.albumid

    2. 有一张像这样的表:

    表架构:

    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 - 不知道你在这里所说的“分裂”是什么意思 - “检索有关歌手的所有信息(如果可能,一次拆分)。”

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-05
        • 2011-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多