在 Postgresql 数据库中存储递归结构

Store recursive go structs in Postgresql database

我有两个递归引用彼此的结构(Person 和 Tenant)。

我没有使用 'SQL' 的经验,我正在尝试使用 https://github.com/jmoiron/sqlx 库来存储这些结构,使它们保持相互引用,以便我可以再次将它们作为结构检索.

我不知道应该使用哪种类型创建表,或者我应该如何插入对象以使其正常工作。

此外,如果有任何其他 go 库可以轻松处理这种情况,我愿意接受任何建议。

提前致谢。

type Tenant struct {
    Id     int      `db:"id"`
    Name   string   `db:"name"`
    Person []Person `db:"person"`
}
type Person struct {
    Id       int       `db:"id"`
    Username string    `db:"username"`
    Tenants  *[]Tenant `db:"tenants"`
}
func main() {

    var schema = `
                       CREATE TABLE IF NOT EXISTS person (
                           id int,
                           username text
                           tenants []text //-> type????
                       );

                       CREATE TABLE IF NOT EXISTS tenant (
                           id int,
                           name text,
                           person []text //-> type????
                       )`

    psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
        "password=%s dbname=%s sslmode=%s",
        host, port, user, password, dbname, sslmode)

    db, err := sqlx.Open("postgres", psqlInfo)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer db.Close()

    err = db.Ping()
    if err != nil {
        panic(err)
    }

    fmt.Println("Successfully connected!")

    db.MustExec(schema)

    var tenant1 Tenant
    var person1 Person
    tenant1 = Tenant{1, "newtenant", []Person{person1}}
    person1 = Person{1, "newuser", &[]Tenant{tenant1}}

    tx := db.MustBegin()

    tx.NamedExec("INSERT INTO tenant (id,name,person) VALUES (:id,:name, :person)", &tenant1)
    tx.Commit()
    out := []Tenant{}
    db.Select(&out, "SELECT * FROM tenant ORDER BY name ASC")

    fmt.Println(out)
}

注意: 这不是真正的答案,只是对问题 SQL 部分的较长评论。不幸的是,我没有使用 sqlx 的经验,所以我无法帮助您。


你那里好像是多对多的关系。一个人可以属于多个租户,一个租户可以有多个人。

在 SQL 中,这通常由有时称为链接或联结的东西处理 table。

-- postgresql flavor of SQL

CREATE TABLE IF NOT EXISTS person (
    id serial PRIMARY KEY,
    username text NOT NULL
);

CREATE TABLE IF NOT EXISTS tenant (
    id serial PRIMARY KEY,
    name text NOT NULL
);

-- the linking table
CREATE TABLE IF NOT EXISTS person_tenant (
    person_id integer NOT NULL REFERENCES person (id),
    tenant_id integer NOT NULL REFERENCES tenant (id),
    PRIMARY KEY(person_id, tenant_id)
);