英文:
How to void (soft delete) a record in database in a scalable fashion
问题
目前我有一个名为 units
的表,包含以下列:
id
:主键 整数name
:字符串serial_id
:字符串- ...
还有一个名为 statuses
的表。此单元的数据从我们的服务器发送到服务器。statuses
表包含以下列:
id
:主键 整数internal_temp
:浮点数battery_level
:整数unit_id
:外键 整数serial_id
:字符串- ...
目前,我想要作废旧的单元,这样我就可以保存具有重复/相同 serial_id
的新单元。 但是,我仍然希望保持_作废的_ units
和 statuses
之间的关系,并以有组织、可扩展的方式维护关系/数据。
我的第一个想法是简单地在 units
表中添加 is_void
,然后执行类似以下的操作:
Unit.where(serial_id: serial).find_by_is_void(false).statuses
但是,我不确定这是否会扩展得好。目前,每天一个 unit
大约生成2000条 status
记录。
我考虑过创建一个关联 unit
和 status
之间关系的联接表,但我不确定,所以想寻求一些建议。
英文:
Currently I have a units
table with the following columns:
id
: PRIMARY Integername
: Stringserial_id
: String- . . .
As well as a statuses
table. This Unit's data is sent to the server from our server. The statuses
table has the following columns:
id
: PRIMARY Integerinternal_temp
: Floatbattery_level
: Integerunit_id
: FOREIGN KEY Integerserial_id
: String- ...
Currently, I want to void
out old units, so that way I can save new units
with duplicate/same serial_id
. However, I still want to preserve the relationship that voided units
and statuses
have and maintain the relationship/data in an organized, scalable manner.
My first idea, was to simply add is_void
to the units
table and then do something like:
Unit.where(serial_id: serial).find_by_is_void(false).statuses
but, I am not sure if this will scale well. Currently, a unit
makes nearly 2000 status
entries per day.
I was thinking along the lines of creating a join table that can manage the relationship between the unit
and status
but I was unsure and wanted to seek some advice.
答案1
得分: 2
如果您使用Rails 5或更低版本,您可以使用paranoia gem来实现软删除功能。这个gem要求我们在要软删除的模型中添加一个名为deleted_at
的列。然后,它使用默认作用域(default scope)来仅获取那些尚未被软删除的记录。它提供了各种实用方法,以轻松获取已删除的记录,真正销毁记录等。
如果您使用Rails 6或想要自己实现软删除功能,以下是您需要执行的步骤:
- 在要软删除的模型中添加一个名为
deleted_at
的列。 - 在该模型中添加一个默认作用域,如
default_scope -> { where(deleted_at: nil) }
。 - 然后,您可以编写实用方法来检查记录是否已删除,或者创建范围(scopes)以获取已删除的记录。此API可以是您想要的任何内容。
- 为了可扩展性,您甚至可以将与软删除模型关联的所有常见方法提取出来,放入一个concern中,只需在需要的地方简单地插入即可。
正如您所看到的,这个实现与paranoia gem提供的功能非常相似。如果您正在学习并且有很多时间,我建议构建自己的功能。如果这是需要在专业项目中尽快部署的功能,我建议使用该gem,因为它可能会加快进程。
这是一篇描述paranoia gem及其功能的不错文章:Rails Soft Delete with Paranoia gem
英文:
If you're using Rails 5 or lower, you could use the paranoia gem to implement the soft delete functionality. This gem requires us to add a column called deleted_at
to the model which we want to soft_delete. It then uses a default scope to fetch only those records which have not been soft deleted. It provides various utility methods to easily fetch deleted records, really destroy records etc.
In case you are using Rails 6 or want to implement the soft deletion feature by yourself, here's what you would need to do:
- Add a column called
deleted_at
to the model which you want to soft delete - Add a default scope in that model as
default_scope -> { where(deleted_at: nil) }
- You could then write utility methods to check if records are deleted or not, or scopes to fetch those records which are deleted as well. This API could be anything that you want
- For scalability, you could even extract out all the common methods that you would want, associated with soft deleted models, into a concern which could simply be plugged in wherever required
As you can see, this implementation is extremely similar to what the paranoia gem provides out of the box. In case you're doing this for learning and have lots of time, I'd recommend building your own feature. If this is something that needs to be deployed soon in a professional project, I'd recommend using the gem since it may speed up the process.
This is a nice article which describes the paranoia gem and its features: Rails Soft Delete with Paranoia gem
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论