这个问题是针对我用 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 等等……但问题是,每次打开带有许多修订的粘贴时,都会引入过多的数据库读取。
方法三
还涉及一个单独的修订表,但对于与方法 1 相同的场景,它将像这样存储数据:
+-------+-----------------+
| id | old_id |
+-------+-----------------+
| 1234 | 1233,1232 |
| 1233 | 1232 |
+-------+-----------------+
当有人打开粘贴 1234 时,我将使用 IN 子句来获取那里的所有子粘贴数据。
哪个是最好的方法?还是有更好的方法?我正在使用具有 Eloquent ORM 的 Laravel 4 框架。
编辑:我可以使用 oneToMany 关系执行方法 1 吗?我知道我可以使用Eager Loading来获取所有修订,但是如何插入它们而不必进行肮脏的破解?
编辑:我想出了如何处理上述问题。我将添加一个答案来结束这个问题。