【问题标题】:Gorm delete but keep ID increasingGorm删除但保持ID增加
【发布时间】:2021-10-14 10:57:32
【问题描述】:

我想在我的 gorm 数据库中拥有唯一且自动递增的 id,即使来自之前创建和删除的条目也是如此。

我的数据库中有这个模型:

type Books struct {
    ID            uint `json:"-" gorm:"autoIncrement"`
    Name          string `json:"name"`
    Author        uint `json:"author"`
}

假设我创建了 3 本书,如果我运行 db.Find(&Books{}),输出将是这样的:

[
  {
    id: 1,
    name: "name1",
    author: 123,
  },
  {
    id: 2,
    name: "name2",
    author: 123,
  },
  {
    id: 3,
    name: "name3",
    author: 123,
  },
]

如果我按 ID 删除书 3,执行以下操作:db.Delete(&Books{}, 3),如文档所述:https://gorm.io/docs/delete.html#Delete-with-primary-key,则删除书 3。

所以,如果我再次查找,我会得到这个:

[
  {
    id: 1,
    name: "name1",
    author: 123,
  },
  {
    id: 2,
    name: "name2",
    author: 123,
  },
]

当我再创建一本书时,问题就出现了,因为它的 ID 为 3。

我希望新创建的书的 ID 为 4,而不是 3,所以我的 ID 为 1、2 和 4。

我想要的 Find 的输出是:

[
  {
    id: 1,
    name: "name1",
    author: 123,
  },
  {
    id: 2,
    name: "name2",
    author: 123,
  },
  {
    id: 4,
    name: "name4",
    author: 123,
  },
]

所以这基本上是我的问题。

我也想过做类似的事情:

type Books struct {
    ID            uint `json:"-" gorm:"autoIncrement"`
    Name          string `json:"name"`
    Author        uint `json:"author"`
    Deleted       bool `json:"-"`
}

然后,当我进行查找时,我会过滤 deleted=true 的...但这会占用我的数据库文件太多空间,所以我想要另一个解决方案。

【问题讨论】:

  • 不是GORM的,是从数据库来的!
  • 你用的是什么数据库?
  • @mkopriva 我正在使用 sqlite

标签: database go go-gorm


【解决方案1】:

这是因为数据库在 book 表中的 id 上生成了一个新的序列生成器,每当您添加一本书时,它都会从 sequencer 中获取当前值,将其添加到行中并为下一个值递增。

没有办法返回并填充从行中删除的 id。这是不用担心的。将其呈现给用户时,不要显示顺序错误的数字,仅显示 1,2,3 并执行更新,删除等操作使用此 id。

或者你可以使用 UUID 代替整数

【讨论】:

  • 也许我误解了 OP 的问题,但您所描述的不正是 OP 所说的他想要发生但没有发生的事情吗?他不是说删除Book id=3然后进行插入后,新Book有id=3且not id=4,但是OP wants id= 4 而不是 id=3?
  • 嗯,是的,OP 想要 id = 4,这就是我试图回答的问题。序列生成器会不断增加,所以你会得到 4。但是现在再次阅读这个问题,他说他得到 id = 3,这是不可能得到的。
【解决方案2】:

考虑到您的 gorm 结构 是:

type Books struct {
    gorm.Model
    Name          string `json:"name"`
    Author        uint `json:"author"`
}

gorm.Model 为您提供字段:ID、CreatedAt、UpdatedAt、DeletedAt

当您执行 db.Delete(&Books, 3) 时,它将执行软删除,这意味着 DeletedAt 将从 null 更新为 timestamp。这不会从数据库中物理删除记录。您仍然可以通过db.Unscoped().Find(&Books) 获取此记录

为了永久删除记录:db.Unscoped().Delete(&Books,3)

我想(我还没有尝试过!)永久删除记录后,您的 ID 序列应该就位了。

【讨论】:

    猜你喜欢
    • 2021-01-07
    • 2014-02-03
    • 2022-08-14
    • 1970-01-01
    • 1970-01-01
    • 2015-05-20
    • 2021-07-09
    • 2018-01-06
    • 2013-01-23
    相关资源
    最近更新 更多