英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论