【问题标题】:Database Inheritance in GoGo 中的数据库继承
【发布时间】:2017-07-13 19:12:58
【问题描述】:

我有一种情况,我有一个基本类型,我们称之为Pet 类型(不是真正的类型,而是一个恰当的例子),以及这种类型的 6 个底层变体,它们都可以有自己的单独字段。假设它们是不同类型的宠物,例如DogCatBird 等。现在它们都组织在同一个名为pets 的表中,但我认为我会从打破每种类型中受益输出到他们自己的表中(dogscatsbirds 等),然后从主pets 表中继承字段。需要明确的是,我的每个子表都有独特的字段,不适用于任何其他子类型。

我正在使用database/sql,我查询数据如下:

var getPetsQuery = fmt.Sprintf(`SELECT %v FROM pets`)

func (tx *Tx) GetPets() (pets []*model.Pet, err error) {
    return tx.petQueryRow(getPetsQuery)
}

func (tx *Tx) petQueryRow(query string, args ...interface{}) (pets []*model.Pet, err error) {
    rows, err := tx.Query(query, args...)
    if err != nil {
        return nil, errors.Stacktrace(PetQueryFailedErr(err))
    }
    defer rows.Close()

    for rows.Next() {
        pet := &model.Pet{}
        err = rows.Scan(
            &pet.Id,
            &pet.Uid,
            &pet.Created,
            &pet.Type,
            &pet.LegCount,
        )
        results = append(results, pet)
    }

    err = rows.Err()
    if err != nil {
        return nil, errors.Stacktrace(PetQueryFailedErr(err))
    }
    return results, err
}

我的问题是,使用这个系统,如果我想查询所有类型的宠物列表,我将如何在单个查询中从每个单独的子类型表中加载额外数据?还是我需要先加载宠物列表,然后单独查询其他数据?

【问题讨论】:

    标签: database postgresql go database-design


    【解决方案1】:

    这不是关于 Go 的问题,而是关于 Postgres 的问题。好消息是,Postgres 应该让你使用UNION 做你想做的事。您只需将UNION所有表合并到一个查询中。

    SELECT id,
           uid,
           created,
           legcount,
           wingcount,
           NULL AS fincount
    FROM snakes
    UNION
    SELECT id,
           uid,
           created,
           legcount,
           NULL AS wingcount,
           NULL AS fincount
    FROM dogs
    SELECT id,
           uid,
           created,
           NULL AS legcount,
           NULL AS wingcount,
           fincount
    FROM fish
    

    关键是要使 UNION 工作,每个子查询必须具有完全相同的列,因此您需要填写 NULL 列(如 NULL AS fincount 等所示)。

    如果要对此执行查询,可以将其全部包装在子查询中以方便:

    SELECT * FROM (
        SELECT id,
        <snip>
        UNION
        SELECT id,
        <snip>
    )
    WHERE legcount = 3;
    

    【讨论】:

    • 我认为这是一个问题的原因是,我正在专门寻找一种在database/sql 范围内执行此操作的方法,我可以有条件地将其加载到不同的类中。感谢您的解释,我仍然可以使用这种策略,但我只需要弄清楚如何有条件地将它返回的内容加载到不同的类中。
    • @JayD3e Go 没有课程。但是您要将其加载到不同的结构类型中,使用单个查询,您将需要一些包含所有字段的类型,然后遍历所有结果,手动对它们进行排序。使用单独的查询可能要简单得多。此外,sqlx 之类的库可能会派上用场。
    猜你喜欢
    • 2010-09-05
    • 1970-01-01
    • 2011-03-03
    • 2010-11-19
    • 1970-01-01
    • 2014-04-30
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多