在 MySQL(或其他 SQL 引擎)中存储历史(影子)表的有效方法
Posted
技术标签:
【中文标题】在 MySQL(或其他 SQL 引擎)中存储历史(影子)表的有效方法【英文标题】:Efficient way to store historical (shadow) tables in MySQL (or another SQL engine) 【发布时间】:2021-03-18 19:44:39 【问题描述】:在使用 API 开发自己的系统时,我将资源存储在数据库中。
一张表(products
)的结构是这样的:
id | name | description | image_id | updated_at | updated_by | updated_with | is_deleted |
---|---|---|---|---|---|---|---|
id | attribute | attribute | relation | timestamp op update | user id of update | client id of update | boolean |
因为我想跟踪该表的所有更改,所以我还制作了一个影子表 (products_HISTORY
),在开头有一个额外的列(_hid
用于历史 ID)来跟踪历史记录。我还在 mysql 中创建了一个触发器,它在每次创建或更新时在此影子表中创建一个新行(不是在删除时,因为我进行了软删除)。为了获得created_at
的值,我从影子表中请求资源的最早行。 deleted_at
也一样,但前提是 is_deleted
为真。
一切都很好,但在不久的将来我想实现一个邮件服务,将邮件保存在 MySQL 数据库中。因为电子邮件很容易达到 25 MB,并且每次更改都会添加一个完整副本的记录,所以在 25 MB 的 40 次更改失败后,我的数据库将变为 1GB。这不是很有效。
我的问题:有没有更有效的方法来保存影子表?是否有专门的软件,或者 MySQL(或其他类似 MySQL 的引擎)是否支持?我正在考虑一些类似 Git 的解决方案,其中只保存实际更改 + 上一个版本的完整内容(您当前的结帐代码)。已经有这样的东西了吗?
提前致谢
本
PS:目前我使用 Laravel,而 Laravel 与 MySQL 配合得非常好。如果有一些适用于 laravel 的解决方案,那就太好了,但如果没有,也欢迎您的回答。
【问题讨论】:
见mariadb.com/kb/en/system-versioned-tables @Akina 是否也支持使用额外的列,例如我的_hid
?
我不明白你的问题......无论如何你都可以测试(例如,在一些在线小提琴上)。
@Akina 我的问题是是否有可能拥有我的普通表,但是在使用 system_versioning 时历史行都有一个 _hid 列。
我查看了这个解决方案,它非常好,但问题是它似乎没有任何节省存储空间的优势。如果我有 1GB 的记录并且我更改了一个字符,我的表将变为 2GB。如果我再次更改它,它将变为 3GB。但是,在像 Git 这样的系统中,它只会保存更改。那时我的表不是 3GB,而是 1.01GB 之类的。
【参考方案1】:
如果您只想跟踪该表的所有更改,可以使用名为 activitylog 的 laravel 包。使用该包,您可以跟踪模型上的所有活动。只需将use LogsActivity;
放在您的模型上,例如示例;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Traits\LogsActivity;
class Product extends Model
use LogsActivity;
protected static $logAttributes = ['name', 'text'];
【讨论】:
但我想将信息保存在我的数据库中。 什么信息?它可以记录/保存记录的表的所有信息 对表所做的所有更改都应保存在同一个数据库中。 那又怎样?它也会保存在同一个数据库中 但我更喜欢数据库本身的解决方案。以上是关于在 MySQL(或其他 SQL 引擎)中存储历史(影子)表的有效方法的主要内容,如果未能解决你的问题,请参考以下文章