dpw63348 2018-08-27 06:50
浏览 56

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

I have a react app that fetches data from golang api which queries data from postgres database. One of my models is deeply nested JSON so I used JSONB datatype in postgres.

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

In golang, I have the structure

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

And in the SPA I have the model

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

To create a new Rule object in the SPA, I assign 0 to id. The newly created rule is sent to golang rest api. Then in the api, I first ask the postgres database for the next value for the serial id (using POSTGRES nextval), assign that acquired id into the Rule struct ID field,

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

JSON marshal the rule object then insert to db

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

This way I avoided duplicate ids which may happen if an SPA is handling the Id generation. However, I find my method somewhat complicated already. I know I can generate ids from SPA too but how do I avoid duplicated ids without using the method I used above? or am I overthinking things?

Update1: I also thought about adding another Rule struct in golang without the ID field so that I don't have to use nextval just to put the id inside the JSON, but is it a good programming design to have multiple models for inserting and retrieving from db and another model for response to the SPA?

  • 写回答

1条回答 默认 最新

  • douqujin2767 2018-08-27 15:42
    关注

    Let the database generate the new id since that's exactly SERIAL types are for in PostgreSQL.

    In golang, you can insert a new record and retrieve the generated id by using sql.DB.QueryRow(...) and .Scan() using an insert statement with a RETURNING clause, e.g.:

    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)
    
    评论

报告相同问题?

悬赏问题

  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c