在SPA中创建对象时,如何防止重复的ID?还是应该留在数据库?

时间:2018-08-27 06:50:52

标签: postgresql go single-page-application

我有一个React应用,该应用从golang api中获取数据,该API从postgres数据库中查询数据。我的模型之一是深度嵌套的JSON,因此我在postgres中使用了JSONB数据类型。

CREATE table rules (
    id serial primary key,
    rule jsonb
);

在golang中,我有结构

type Rule struct {
    ID int `json:"id"`
    Name string `json:"name"`
    ...succeeding fields are deeply nested data
}

在SPA中,我有模型

interface Rule {
    id number
    name string
    ....same as from the golang api model
}

要在SPA中创建新的Rule对象,我将0分配给id。新创建的规则将发送到golang rest api。然后在api中,我首先向postgres数据库询问序列ID的下一个值(使用POSTGRES nextval),将获取的ID分配给Rule struct ID ID,

nextValidId := <result of nextval>
rule.ID = nextValidId

JSON将规则对象编组,然后插入db

ruleBytes, _ := json.Marshal(rule)
INSERT INTO rules_table VALUES (<nextValidId>, <ruleBytes>);

这样,我避免了SPA处理ID生成时可能发生的重复ID。但是,我发现我的方法已经有些复杂了。我知道我也可以从SPA生成ID,但是如何不使用上面使用的方法避免重复的ID?还是我想得太多?

Update1: 我还考虑过在golang中添加另一个没有ID字段的Rule结构,这样我就不必使用nextval来将id放入JSON,但这是一个好的编程设计吗?是用于从db插入和检索的多个模型,还是用于响应SPA的另一个模型?

1 个答案:

答案 0 :(得分:0)

让数据库生成新的ID,因为它恰好是SERIAL types are for in PostgreSQL

在golang中,您可以插入新记录并通过使用sql.DB.QueryRow(...)insert statement with a RETURNING clause使用Char.Empty like there is a String.Empty.Scan()来检索生成的ID,例如:

var newId int
query := "INSERT INTO rules (rule) VALUES ($1) RETURNING id"
err := db.QueryRow(query, newRule).Scan(&newId)
// TODO: check err
log.Printf("newId=%d", newId)