我正在尝试建立一个类似维基百科的东西,多人可以编辑内容。有特权的人也可以恢复更改。我不希望恢复是有损的(这意味着真的放弃人们所做的编辑。它应该只隐藏它),所以这似乎需要一个像数据结构这样的 git 分支来存储编辑,并带有一个指向“当前”的指针。
我试过这个设计:
CREATE TABLE article (
id serial PRIMARY KEY,
content text NOT NULL,
author integer NOT NULL REFERENCES "user",
path text NOT NULL,
relationship ltree NOT NULL
);
CREATE TABLE current_article (
article_id NOT NULL REFERENCES article
);
其中relationship
记录是新文章还是现有文章的编辑:
id | content | path | author | relationship
---+---------+------+--------+-------------
1 | foo | /a1 | 1 | 'root'
2 | bar | /a1 | 2 | 'root.1'
3 | baz | /a2 | 3 | 'root'
这里的意思是,作者 2 将文章/a1
从 foo 更改为 bar,并且文章/a2
是新的。
current_article
记录哪篇文章是“当前”文章,通常它只是指向最新的文章。还原后,它可以指向一个较旧的:
article_id
----------
2
3
当一个编辑进来时,我像这样插入它:
INSERT INTO article (content, path, author) VALUES ('qux', '/a2', 4);
并且依靠插入前触发器来查找该路径的当前文章并填写关系,并依靠插入后触发器来更新当前文章指针。
你觉得这个设计怎么样?我在这个设计中遇到的问题是处理并发的困难。
在前插入触发器中,当它找到当前文章时,它可能已经被更改,而在后插入触发器中,它可能会错误地用已经指向不同的文章覆盖当前文章。
在这方面我有三个问题:
- 可序列化的隔离会解决问题吗?(我对 MVCC 的概念还很陌生,仍然试图绕开它)如果没有,我应该如何解决它?
- 有没有更好的设计不必处理并发?
- 如果我确实需要处理并发,我如何在不同的竞争条件下对我的设计进行单元测试(或者这样的单元测试甚至是必要的)?
谢谢你。