如何在数据库中划分长文章和存储以便于检索和分页?

时间:2009-05-31 20:28:00

标签: php database database-design schema

假设它是一篇很长的文章(比如10万字),我需要编写一个PHP文件来显示文章的第1页,第2页或第38页,

display.php?page=38

但是每个页面的单词数量可能会随着时间的推移而变化(例如,如果每页500字,但是下个月,我们可以轻松地将其更改为每页300字)。将长文章和商店分成数据库的好方法是什么?

P.S。如果我们想要显示500个单词但包括整个段落,那么设计可能会更复杂。也就是说,如果我们已经显示了单词480,但段落还剩下100个单词,那么即使它超过500个字的限制,也要显示那100个单词。 (然后,下一页不应再显示那100个单词)。

6 个答案:

答案 0 :(得分:2)

你当然可以每页输出500个单词,但更好的方法是在你的文章中加入某种中断(句末,段落结尾)。把它们放在休息好的地方。通过这种方式,您的页面中每个页面都不会有正好的X个单词,但是大约在X或X之间,并且它不会撕裂句子或段落。 当然,在显示页面时,请勿显示这些中断标记。

答案 1 :(得分:2)

我会通过在保存时分割chuks上的文章来实现。保存脚本会使用您设计的任何规则拆分文章,并将每个块保存到如下表中:

CREATE TABLE article_chunks (
    article_id int not null,
    chunk_no int not null,
    body text
}

然后,当您加载文章的页面时:

$sql = "select body from article_chunks where article_id = "
    .$article_id." and chunk_no=".$page;

每当您想要更改将文章拆分为页面的逻辑时,您运行的脚本会将所有块拉到一起并重新拆分它们:

UPDPATE:提供建议我认为您的应用程序读取密集程度超过了写入密集程度,这意味着文章的阅读频率高于写入时间

答案 2 :(得分:1)

您可能希望首先使用split命令将文章分解为段落数组: http://www.php.net/split

$array = split("\n",$articleText);

答案 3 :(得分:1)

手动剪切文本是更好的方法,因为留下一个确定切割位置的程序并不是一个好主意。有时它会在h2标签之后剪切,并继续下一页的文字。

这是简单的数据库结构:
文章(id,title,time,...)
article_body(id,article_id,page,body,...)

SQL查询:

SELECT a.*, ab.body, ab.page
FROM article a
INNER JOIN article_body ab
    ON ab.article_id = a.id
WHERE a.id = $aricle_id AND ab.page= $page
LIMIT 1;

在应用程序中,您可以使用jQuery简单地为另一个页面添加新的textarea ...

答案 4 :(得分:1)

您的表格可能类似于

CREATE TABLE ArticleText (
  INTEGER artId,
  INTEGER wordNum,
  INTEGER wordId,
  PRIMARY KEY (artId, wordNum),
  FOREIGN KEY (artId) REFERENCES Articles,
  FOREIGN KEY (wordId) REFERENCES Words
)

这当然可能非常昂贵,或者速度很慢等等,但是您需要一些测量来确定(因为这取决于您的数据库引擎)。顺便说一句,我希望很明显,Article表只是一个表格,其中包含artId键入的文章的元数据,而Words表格中包含了wordId所有文章中所有单词的表格(试图通过识别已知单词来节省一些空间)当一篇文章被输入时,如果这是可行的......)。一个特殊的词必须是“段落末尾”标记,可以很容易识别,并且与每个真实词语不同。

如果你像这样构建数据,你可以在页面检索中获得很大的灵活性,并且可以快速更改页面长度,甚至可以根据需要通过查询进行查询。获取页面:

SELECT wordText
FROM  Articles
 JOIN ArticleText USING (artID)
 JOIN Words USING (wordID)
 WHERE wordNum BETWEEN (@pagenum-1)*@pagelength AND @pagenum * @pagelength + @extras
  AND Articles.artID = @articleid

参数@pagenum@pagelength@extras@articleid将在查询时插入准备好的查询中(使用您的数据库和语言的任何语法,例如:extras或编号参数或其他)。

因此我们得到超出预期页尾的@extras个单词,然后在客户端我们检查这些额外的单词以确保其中一个是结束段标记 - 否则我们将进行另一个查询(使用不同的BETWEEN值)以获得更多。

远非理想,但是,考虑到你突出的所有问题,值得考虑。如果您可以依赖页面长度,例如如果是100的倍数,您可以根据100个字块(并且没有Words表格,而不是每行直接存储的文本)对此进行略微变化。

答案 5 :(得分:1)

让作者将文章分成几部分。

作家知道如何通过将文章划分为逻辑部分来使文章变得有趣和可读,例如“第1部分 - 安装”,“第2部分 - 配置”等。有了算法,这是一个糟糕的决定,imho。

在错误的地方抄写一篇文章只会让读者感到恼火。不要这样做。

我的2¢

/0