-
-
Notifications
You must be signed in to change notification settings - Fork 797
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SQL : Nouvel identifiant d'article entier basé sur la date #202
Comments
Je trouve que le plus pratique serait d'intégrer dans l'identifiant comme décrit ci-dessus la date de découverte / insertion de l'article dans la base de données, et de conserver le champ date inchangé (c'est-à-dire une date telle que déclarée par le flux).
|
Actuellement, le entry.id est généré par un hachage de entry.guid. Hors, ce GUID ne semble pas très unique entre plusieurs flux. GUID provient de http://simplepie.org/wiki/reference/simplepie_item/get_id .
|
Ajout temporaire d'un index sur e.date en attendant #202
Préparation de GUID en prévision de #202
Pour simplifier, plutôt que d'utiliser un hachage, je pense finalement qu'il serait préférable d'utiliser seulement microtime(true) comme identifiant, transformé en BIGINT, les doublons étant évités grâce à UNIQUE(e.id_feed, e.guid) d2d26bf En plus, on peut laisser faire le travail de conversion entier 64-bit / flottant à MySQL, ce qui permet d'éviter tout problème lorsque PHP est en 32-bit.
Et pour l'affichage sur le client Web, une chaîne décimale directe ou du base64url par exemple : function base64url_encode($data) { //RFC 4648
return strtr(rtrim(base64_encode($data), '='), '+/', '-_');
}
function base64url_decode($data) { //RFC 4648
return base64_decode(strtr($data, '-_', '+/'));
}
$id = 1384898862.8061;
$encoded = base64url_encode(pack('d', $id));
echo $encoded, "\n"; //Affiche JJezS_ii1EE
$decoded = unpack('d', base64url_decode($encoded));
echo $decoded[1], "\n"; //Affiche 1384898862.8061 Dans cet exemple, base64url fait gagner 4 octets sur 15 (-27%) mais au prix de plusieurs appels de fonctions. |
Contribue à #202 e.id est généré à l'insertion par microtime(true).
Expérimentation : classement par date d'ajout dans la base plutôt que selon la date déclarée par le flux (qui est parfois fausse dans le passé, dans le futur, ou absente). Quelques conséquences : * Les flux avec des dates erronées ne sont plus un problème * Lorsqu'on fait "marquer tout comme lu", les articles arrivés pendant la lecture ne sont plus indûment marqués comme lus * Les articles ont tendance à être plus regroupés par flux lorsqu'on les affiche par catégorie * Si un utilisateur n'utilise pas de cron et n'utilise pas FreshRSS pendant plusieurs jours, lors du rafraîchissement, les nouveaux articles seront dans "Aujourd'hui" (à interpréter donc comme les articles reçus aujourd'hui, et non comme déclarés comme étant publiés aujourd'hui) * La pagination est plus efficace Termine l'implémentation de #202
À tester plus, mais a priori fini :-) |
Pour ce que j'ai essayé, ça marche bien :) |
Super :-) Expérimentation : Classement selon la date d'ajout dans la base plutôt que selon la date déclarée par le flux (qui est parfois fausse dans le passé, dans le futur, ou absente).
|
Alors je n'avais pas testé ça effectivement. Seulement il y a une chose qui me dérange, c'est justement le fait que les articles soient regroupés par flux plutôt que par date. Généralement je cherche plutôt à voir mes articles pour une date donnée (la veille ou l'avant-veille) plutôt que par flux. Et si je veux les voir par flux, il y a déjà la possibilité de filtrer... |
Cela devrait toujours fonctionner comme tu le souhaites. La différence est
|
Ah oui d'accord, je viens de comprendre le comportement. Le problème c'est lorsqu'on importe des flux (OPML) c'est que de très vieux articles peuvent se retrouver tout en haut de la liste au détriment des plus récents |
Effectivement, au tout premier import, ce n'est pas optimal, mais cela |
En fait, j'ai une idée pour l'import OPML, qui est de faire comme dans le |
Ok :) sinon oui, le comportement pour les jours suivants me convient mais il faudra quand même voir à l'usage ce qu'il en est réellement |
Voilà, semble maintenant beaucoup mieux pour l'ajout de nouveaux flux |
Parfait ! Et les performances pour l'actualisation sont géniales aussi ! :) |
:-) |
Le trie par e.id semble bien fonctionner suite à #202
Microtime(true) dépend de la précision de PHP définie dans php.ini, et par défaut, nous perdons les deux dernières décimales des microsecondes. Du coup, sur une machine très rapide, cela aurait pu poser des problèmes d'identifiants dupliqués. Patch utilisant gettimeofday() à la place. Au passage, reste en string tout le long et plus besoin de faire la conversion CAST(? * 1000000 AS SIGNED INTEGER) côté base de données. #202
Discussion pour le choix d'un nouvel identifiant pour les articles.
Actuellement, FreshRSS utilise un CRC32 pour identifier les articles, encodé en base64 modifié.
Cela représente des problèmes majeurs, en particulier un problème de collisions trop important, et le fait que c'est peu pratique et lent pour les requêtes SQL.
http://www.codinghorror.com/blog/2007/08/url-shortening-hashes-in-practice.html
https://fr.wikipedia.org/wiki/Paradoxe_des_anniversaires
J'aurais voulu utiliser un champ date incluant les microsecondes, mais c'est disponible seulement depuis la version 5.6 de MySQL (par exemple pas disponible sur l'actuelle Ubuntu LTS), du coup abandonné
http://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html
Du coup, je fais une proposition basée sur BIGINT (entier 64 bits) disponible sur MySQL depuis longtemps et SQLite :
http://dev.mysql.com/doc/refman/4.1/en/integer-types.html
http://www.sqlite.org/datatype3.html#affname
The text was updated successfully, but these errors were encountered: