Gorm删除但保持ID递增。

huangapple go评论86阅读模式
英文:

Gorm delete but keep ID increasing

问题

我想在我的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的条目... 但这会占用我数据库文件太多的空间,所以我希望有另一种解决方案。

英文:

I want have unique and autoincremental ids on my gorm database, even from previously created and deleted entries.

I have this model in my database:

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

Lets say I create 3 books, if I run db.Find(&Books{}) the output will be something like this:

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

If I delete Book 3 by ID, doing this: db.Delete(&Books{}, 3), as the documentation says: https://gorm.io/docs/delete.html#Delete-with-primary-key, the book 3 is deleted.

So, if I make another Find, I will get this:

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

The problem comes out when I create one more book, because it will have 3 as ID.

I would like that the new created book would have ID 4, instead of 3, so I will have ids 1, 2, and 4.

The output from Find I would like to have is:

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

So that's basically my problem.

I also thought of doing something like:

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

And then, when I make a Find, i would filter the deleted=true ones... But that would take too much space on my database file, so I would like another solution.

答案1

得分: 2

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

无法回溯并填充从行中删除的id。这不是什么需要担心的事情。在向用户展示时,不要显示错序的数字,只显示1、2、3,并在执行更新、删除等操作时使用这个id。

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

英文:

This is because the database generates a new sequence generator on id in book table and whenever you add a book, it will take the current value from sequencer , add it to the row and increment it for next value.

There is no way to go back and fill the id deleted from row. And this is something not to worry about. when presenting it to the user, dont show the misordered numbers just display 1,2,3 and for performing operations like update, delete use this id.

Or you can use UUID instead of integer

答案2

得分: 1

考虑到你的gorm struct如下所示:

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序列应该会恢复正常。

英文:

Considering your gorm struct is:

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

Where gorm.Model gives you fields: ID, CreatedAt, UpdatedAt, DeletedAt

When you do a db.Delete(&Books, 3) it will do a soft-delete, which means the DeletedAt will be updated from null to a timestamp. This does not physically removes the record from the DB. You can still fetch this record by db.Unscoped().Find(&Books)

In order to permanently delete the record: db.Unscoped().Delete(&Books,3)

I guess (I haven't tried this yet!) after permanently deleting the record, your ID sequence should fall in place.

huangapple
  • 本文由 发表于 2021年8月11日 06:53:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/68734244.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定