如果现在重要,我正在使用 MySQL / MyISAM,但我愿意使用 PostgreSQL的。我也愿意使用memcached。
考虑一个用于存储论坛帖子的表:
id forum_name post_date
1 Hey! 2009-01-01 12:00:00
我应该......
创建一个单独的表,例如
id thread_id views
1 1 532
或者将它保存为初始线程表中的列?
id forum_name post_date views
1 Hey! 2009-01-01 12:00:00 532
另一个相关的小问题,显示和增加页面浏览量的实用解决方案是什么?我读了这个thread,似乎我只能缓存一段时间的值,我对增量部分并不十分清楚 - 可能就像将值存储在某个地方的平面文件中一样,然后定期用cronjobs更新每小时左右数据库论坛的观点?
修改 为了澄清,投票就像SO一样,每个线程一票,并且可以有逆转。没关系我对柜台的意思。
答案 0 :(得分:8)
我建议除了线程表之外还定义两个表 - VOTE_CODES
和THREAD_VOTES
。一目了然,它可能看起来过于标准化,但格式将允许您更改投票值而无需重大DML更改。
VOTE_CODES
表vote_code
,主键,IE:向上,向下vote_cast_value
- 归因于上/下投票的价值vote_caster_value
- 选项,如果你想保持反对施法者的反对票的风格。THREAD_VOTES
表thread_id
user_id
vote_code
THREAD_VOTES
中的所有列都是主键 - 这将确保给定用户和线程的行数与投票代码一样多。假设只有两个代码,这将支持反转投票的能力,因为只有两条记录 - 一条带有任何代码。
我建议存储:
以上所有都是主键。您的表格将快速填充,但它将使您能够在视图中创建计算列以获得更准确的报告。
答案 1 :(得分:1)
平面文件显然是一个坏主意,因为你需要实现锁定(数据库已经这样做,并且该代码中的错误更少)。
关系数据库设计更像是一门艺术,而不是一门科学:你可以拥有
CREATE TABLE threads (
tid THREADID
, title THREADTITLE
, views COUNTER
, PRIMARY KEY (tid)
);
并且它不会比
更“正确”CREATE TABLE threads (
tid THREADID
, title THREADTITLE
, PRIMARY KEY (tid)
);
CREATE TABLE views (
tid THREADID
, views COUNTER
, PRIMARY KEY (tid)
, FOREIGN KEY (tid)
REFERENCES threads
);
所以这取决于你。
我会说:首先选择最简单的事情,如果你发现它是必要的话会让它变得更复杂(例如出于性能原因)。 IOW:将views COUNTER
属性放在threads
中。如果事实证明trafic损害了性能(threads.views
属性上的更新太多意味着dbms必须在其他属性中改变其他不可变数据),你总是可以将表拆分为两个,并将其替换为一个加入它们的视图。瞧,从易失性数据中分离出不可变(或很少变化)的数据,界面保持不变。
当然,请使用PostgreSQL。上面显示的代码在dbms中有效,只需添加以下内容:
CREATE DOMAIN threadid
AS INT NOT NULL;
CREATE DOMAIN threadtitle
AS TEXT NOT NULL
CHECK (LENGTH(VALUE) > 0);
CREATE DOMAIN counter
AS INT NOT NULL
CHECK (VALUE > 0);
编辑以反驳OMG小马的评论:当然这是安全的。
UPDATE threads SET
views = views + 1
WHERE tid = X
成功或拯救。
编辑2 以添加投票方面的考虑因素
让我们说规则是:用户可以向线程投票(+1)或向下投注(-1),他或她在给定线程上的投票总和不得超过| 1 |,且历史记录无关紧要。如果用户可以投票给一个帖子,然后向下重置他们的投票“无投票”,然后又重新投票到“投票”,等等。
CREATE DOMAIN vote
AS INT NOT NULL
CHECK (VALUE BETWEEN -1 AND 1);
CREATE TABLE votes (
tid THREADID
, uid USERID
, vote VOTE
, PRIMARY KEY (tid, uid)
);
在MySQL中,你可以
INSERT INTO votes (
tid
, uid
, vote
) VALUES (
X
, Y
, Z -- +1 or -1
)
ON DUPLICATE KEY UPDATE
vote = vote + Z
唉,PostgreSQL还没有内置这样的功能,所以你需要使用idiomatic user-level implementation