Как предотвратить дублирование идентификатора при создании объектов из SPA?Или я должен остаться с БД? - PullRequest
0 голосов
/ 27 августа 2018

У меня есть приложение реагирования, которое выбирает данные из golang api, которые запрашивают данные из базы данных postgres.Одна из моих моделей - глубоко вложенный JSON, поэтому я использовал тип данных JSONB в postgres.

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
}

Чтобы создать новый объект Rule в SPA, я присваиваю 0 id.Вновь созданное правило отправляется в golang rest api.Затем в API я сначала запрашиваю в базе данных postgres следующее значение для серийного идентификатора (используя POSTGRES nextval), присваиваем полученный идентификатор в поле идентификатора структуры правила,

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

JSON маршалЗатем объект правила вставьте в db

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

Таким образом, я избежал дублирования идентификаторов, которые могут произойти, если SPA обрабатывает генерацию идентификатора.Однако я уже нахожу свой метод несколько сложным.Я знаю, что могу также генерировать идентификаторы из SPA, но как избежать дублирования идентификаторов, не используя метод, который я использовал выше?или я обдумываю вещи?

Update1: я также подумал о добавлении еще одной структуры правил в golang без поля ID, чтобы мне не приходилось использовать nextval только для помещения идентификатора в JSON, но это хорошопрограммирование дизайна, чтобы иметь несколько моделей для вставки и извлечения из базы данных и другой модели для ответа на SPA?

1 Ответ

0 голосов
/ 27 августа 2018

Позвольте базе данных сгенерировать новый идентификатор, так как это точно SERIAL типы для PostgreSQL .

В golang вы можете вставить новую запись и получить сгенерированный идентификатор, используяsql.DB.QueryRow(...) и .Scan() с использованием оператора вставки с предложением RETURNING , например:

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)
...