2017-09-15 108 views
0

让我们以表定义了文档:云扳手最佳实践交错问题

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个表歌手相册歌曲。表专辑交错歌手和表歌曲交错歌手相册

我的问题是,如果我们想这样搜索关于某个歌手的所有信息,我们可以在表歌曲中搜索,如果歌手有专辑但没有任何歌曲吗?如果不是最好的做法是检索歌手的所有数据(所有专辑和歌曲(如果有的话))。如果我们没有在歌曲中找到任何东西(因为歌手可以有一个专辑,但歌曲正在开发中),我想在表歌曲中搜索,然后在歌手中搜索(因为即使专辑可以在开发中),但我不会不认为这是最好的解决方案。

在我的情况下,查询的用户不知道歌手是否有歌曲或专辑,但想要回顾关于歌手的所有信息(如果可能,在一个分割中)。

回答

0

我得出两个解决方案:

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

    选择 singers.singerId,albums.albumId,songs.trackId
    从歌手
    左加入专辑ON singers.singerId = albums.singerid
    左加入歌曲albums.albumid =歌曲。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个查询,我们可以收回所有关于歌手的数据(我们有1张大表扫描不是3,但我不知道它是否最好因为再一次,服务器将在服务器之间分割数据,所以我们将以分割之间的多个选择结束)。

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

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 - 不确定你是什么意思的“拆分”在这里 - “检索关于歌手的所有信息(如果可能,在一个分割中)”。