代码之家  ›  专栏  ›  技术社区  ›  nonopolarity

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

  •  4
  • nonopolarity  · 技术社区  · 15 年前

    假设这是一篇很长的文章(比如100000字),我需要编写一个php文件来显示文章的第1、2或38页。

    display.php?page=38
    

    但是每页的字数会随着时间的推移而变化(例如,现在如果每页500个字,下个月我们可以轻松地将其更改为每页300个字)。什么是将长文章分割并存储到数据库中的好方法?

    附笔。 如果我们想显示500个单词,但包括整个段落,设计可能会更加复杂。也就是说,如果我们已经显示了480字,但段落中还有100多个单词,那么无论如何都要显示这100个单词,即使它超过了500个单词的限制。(然后,下一页不应该再显示这100个单词)。

    6 回复  |  直到 8 年前
        1
  •  2
  •   artemb    15 年前

    我会在存钱的时候把文章放在垃圾桶里。save脚本将使用您设计的任何规则拆分文章,并将每个块保存到如下表中:

    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
  •  2
  •   schnaader    15 年前

    当然,每页只能输出500个单词,但更好的方法是在文章中添加一些中断(句末、段落末)。把这些放在休息的地方。这样,您的页面中不会有确切的x个单词,但大约或最多x个,并且不会将句子或段落分开。 当然,在显示页面时,不要显示这些分隔标记。

        3
  •  1
  •   Travis    15 年前

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

    $array = split("\n",$articleText);
    
        4
  •  1
  •   sasa    15 年前

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

    这是一个简单的数据库结构:
    文章(ID、标题、时间…)
    文章正文(ID、文章ID、页面、正文…)

    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简单地为另一页添加新的文本区域…

        5
  •  1
  •   Alex Martelli    15 年前

    你的桌子可能是

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

    当然,这可能是非常昂贵的空间,或缓慢,等,但您将需要一些测量来确定(因为这么多取决于您的数据库引擎)。顺便说一句,我希望文章表是一个简单的表,其中包含artid键控的文章的元数据,单词表是由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 或编号参数等)。

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

    远非理想,但考虑到你所强调的所有问题,值得考虑。如果你能将页面长度计算为100的倍数,你可以根据100个字块(而不是 Words 表中,只有每行直接存储的文本)。

        6
  •  1
  •   0scar    15 年前

    让作者自己把文章分成几部分。

    作者知道如何将文章分成逻辑部分,如“第1部分安装”、“第2部分配置”等,从而使文章变得有趣和可读。让算法来做这是一个错误的决定,IMHO。

    把一篇文章剪错地方只会让读者恼火。不要这样做。

    我的2岁

    /0