2009-05-31 5 views
4

On suppose qu'il est un long article (disons 100.000 mots), et je dois écrire un fichier PHP pour afficher la page 1, 2, ou la page 38 de l'article, parComment diviser un article long et stocker dans la base de données pour une récupération facile et avec pagination?

display.php?page=38 

mais le nombre de mots pour chaque page peut changer au fil du temps (par exemple, en ce moment si c'est 500 mots par page, mais le mois prochain, nous pouvons le changer à 300 mots par page facilement). Quel est un bon moyen de diviser le long article et stocker dans la base de données?

P.S. La conception peut être encore plus compliquée si nous voulons afficher 500 mots mais inclure des paragraphes entiers. C'est-à-dire, si nous montrons déjà le mot 480 mais le paragraphe a encore 100 mots restants, alors montrez ces 100 mots de toute façon même si cela dépasse la limite de 500 mots. (et ensuite, la page suivante ne devrait plus montrer ces 100 mots).

Répondre

2

je le ferais en scindant les articles sur chuks quand les sauver. Le script sauver fendrait l'article en utilisant toutes les règles que vous concevez dans et enregistrer chaque morceau dans une table comme ceci:

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

Ensuite, lorsque vous chargez une page d'un article:

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

Chaque fois que vous voulez changer la logique des articles de fractionnement en pages, vous exécutez un thats de script tire tous les morceaux ensemble et les re-divise:

UPDPATE: Donner les conseils que je suppose que votre demande est en lecture intensive plus écriture intensive, ce qui signifie que les articles sont lus plus souvent qu'ils ne sont écrits

+0

et s'il y a quelques centaines d'articles longs et les re-fractionnant peut-être besoin d'arrêter le site pour maintenance ... et s'il y a un bug dans le script de re-split, alors le contenu peut être contaminé? –

+0

Eh bien, s'il y a un bogue dans un code qui fonctionne avec des données, le contenu peut être endommagé. Vous pouvez éviter la nécessité d'arrêter le site en démarrant et en validant une transaction autour de l'enregistrement de chaque article. Mais arrêter un site de maintanance de temps en temps est une chose courante. – artemb

+0

Vous n'auriez pas besoin d'arrêter le site !!, vous pourriez reconstruire l'article pendant qu'il est en ligne. Je suggère également d'ajouter un article de table (avec article_id comme identité/autoincrement/..., et le corps du texte), c'est le texte original qui est divisé en morceaux. Dans l'algorithme, je voudrais définir un déclencheur pour mettre à jour le texte des morceaux en ligne ... ajouter de nouveaux morceaux qui n'étaient pas là, et supprimer les morceaux inutiles. –

2

Vous pouvez bien sûr produire exactement 500 mots par page, mais le mieux serait de mettre un peu de pauses dans votre article (fin de phrase, fin de paragraphe). Mettez-les à des endroits où une pause serait bonne. De cette façon, vos pages ne contiendront pas exactement X mots dans chacune d'entre elles, mais environ X ou moins et ne déchireront pas les phrases ou les paragraphes. Bien sûr, lors de l'affichage des pages, n'affichez pas ces marqueurs de rupture.

1

Vous pouvez commencer par briser l'article vers le haut dans un tableau des paragraphes en utilisant la commande division: http://www.php.net/split

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

alors comment décidez-vous que les paragraphes pour montrer quand il est à la page 38? –

1

Il est préférable de couper manuellement le texte, car ce n'est pas une bonne idée de laisser un programme qui détermine où couper. Parfois, il sera coupé juste après l'étiquette h2 et continuer avec le texte sur la page suivante.

Ceci est la structure de base de données simple pour que:
article (id, titre, temps, ...)
article_body (id, article_ID, page corps, ...)

La requête 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; 

En application, vous pouvez utiliser jQuery pour ajouter un nouveau textarea pour une autre page ...

+0

dit s'il y a quelques centaines de ces articles, les séparer manuellement pourrait prendre trop de temps. De plus, s'il est décidé d'avoir 300 mots par page le mois prochain, vous ne pouvez pas les refaire à la main. –

1

Votre table pourrait être quelque chose comme

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

Bien sûr, cela peut être très coûteux espace, ou lent, etc, mais vous aurez besoin des mesures pour déterminer que (comme si dépend beaucoup de votre DB moteur). BTW, j'espère qu'il est clair que la table Articles est simplement une table avec des métadonnées sur des articles entrés par artId, et les mots table une table de tous les mots dans chaque article keyId (essayant d'économiser de l'espace en identifiant des mots déjà connus quand un article est entré, si c'est faisable ...). Un mot spécial doit être le marqueur «fin de paragraphe», facilement identifiable en tant que tel et distinct de tout mot réel.

Si vous structurez vos données de cette manière, vous obtenez une grande flexibilité dans la récupération par page, et la longueur de la page peut être modifiée en un instant, même requête par requête si vous le souhaitez. Pour obtenir une page:

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 

paramètres @pagenum, @pagelength, @extras, @articleid doivent être insérés dans la requête préparée au moment de la requête (utilisation quelle que soit la syntaxe de votre base de données et le langage comme, par exemple :extras ou paramètres numérotés ou autre) . Donc, nous obtenons @extras mots au-delà de la fin de page attendue, puis du côté client, nous vérifions ces mots supplémentaires pour nous assurer que l'un d'entre eux est le marqueur de paragraphe final - sinon nous ferons une autre requête (avec différents BETWEEN valeurs) pour obtenir encore plus. Loin d'être idéal, mais compte tenu de tous les problèmes que vous avez mis en évidence, il vaut la peine d'en tenir compte. Si vous pouvez compter sur la longueur de la page, par ex. un multiple de 100, vous pouvez adopter une légère variation de ceci sur la base de blocs de 100 mots (et pas de tableau Words, juste du texte stocké directement par ligne).

1

Laissez l'auteur diviser l'article en plusieurs parties.

Les auteurs savent comment rendre un article intéressant et lisible en le divisant en parties logiques, comme "Partie 1-Installation", "Partie 2-Configuration" etc. Avoir un algorithme c'est une mauvaise décision, à mon humble avis.

Le fait de couper un article au mauvais endroit ne fait qu'agacer le lecteur. Ne fais pas ça.

mon 2 ¢

/0 
Questions connexes