【发布时间】:2013-08-29 05:08:52
【问题描述】:
这个问题是针对我用 PHP 编写的 pastebin 应用程序。
我做了一些研究,尽管我无法找到符合我需求的解决方案。我有一个具有这种结构的表:
+-----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+----------------+
| id | int(12) unsigned | NO | PRI | NULL | auto_increment |
| author | varchar(50) | YES | | | |
| authorid | int(12) unsigned | YES | | NULL | |
| project | varchar(50) | YES | | | |
| timestamp | int(11) unsigned | NO | | NULL | |
| expire | int(11) unsigned | NO | | NULL | |
| title | varchar(25) | YES | | | |
| data | longtext | NO | | NULL | |
| language | varchar(50) | NO | | php | |
| password | varchar(60) | NO | | NULL | |
| salt | varchar(5) | NO | | NULL | |
| private | tinyint(1) | NO | | 0 | |
| hash | varchar(12) | NO | | NULL | |
| ip | varchar(50) | NO | | NULL | |
| urlkey | varchar(8) | YES | MUL | | |
| hits | int(11) | NO | | 0 | |
+-----------+------------------+------+-----+---------+----------------+
这是一个 pastebin 应用程序。我基本上想要粘贴修订,因此如果您打开粘贴 #1234,它会显示该粘贴的所有过去修订。
我想到了三种方法:
方法一
有一个带有 id 和 old_id 之类的修订表,对于每个 ID,我会插入所有旧修订,所以如果我的结构如下所示:
rev3: 1234
rev2: 1233
rev1: 1232
该表将包含以下数据:
+-------+----------+
| id | old_id |
+-------+----------+
| 1234 | 1233 |
| 1234 | 1232 |
| 1233 | 1232 |
+-------+----------+
我遇到的问题是它引入了很多重复数据。而且修订越多,它不仅有更多的数据,而且我需要为每个新粘贴到修订表做 N 次插入,这对于大 N 来说并不是很好。
方法二
我可以在顶部的粘贴表中添加一个 child_id 并对其进行更新。然后,在获取粘贴时,我将继续查询数据库中的每个 child_id 及其 child_id 等等……但问题是,每次打开带有许多修订的粘贴时,都会引入太多的数据库读取。
方法3
还涉及到一个单独的修订表,但是对于与方法1相同的场景,它会像这样存储数据:
+-------+-----------------+
| id | old_id |
+-------+-----------------+
| 1234 | 1233,1232 |
| 1233 | 1232 |
+-------+-----------------+
当有人打开粘贴 1234 时,我将使用 IN 子句来获取那里的所有子粘贴数据。
哪种方法最好?还是有更好的方法?我正在使用具有 Eloquent ORM 的 Laravel 4 框架。
编辑:我可以使用 oneToMany 关系执行方法 1 吗?我知道我可以使用Eager Loading 来获取所有的修订,但是我怎样才能插入它们而不必进行肮脏的破解呢?
编辑:我想出了如何处理上述问题。我将添加一个答案来结束这个问题。
【问题讨论】:
-
我将推荐方法 1 的修改。 ID 应为
unique。并在其他表中添加修订。 -
修订存储是树状结构还是线性结构?
-
假设1232是原始的,1233对1232添加一些更改,1234对1232添加一些更改。然后,有人直接将更改添加到1232而不经过1234(称为1235)。你想怎么处理这个案子?
-
这适用于哪个 Laravel 版本?
-
@invisal:同样的方式。如果 1235 是 1232 的新修订版,则 id 将为 1235,old_id 将为 1232。所以当我获取 1235 时,它只会显示 1232 作为修订版。
标签: php mysql laravel eloquent revisionable