C'est pour ça qu'il y a le type gist sous postgresql. Mais je te conseille vraiment de pousser l'idée sur la mailing list internationale de développement.<br><br>Emilie Laffray<br><br><div class="gmail_quote">2012/2/22 Philippe Verdy <span dir="ltr"><<a href="mailto:verdy_p@wanadoo.fr">verdy_p@wanadoo.fr</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Enfin je me suis expliqué plus longuement pourquoi une requête de<br>
simple comptage peut être très efficace et soulager énormément le<br>
serveur.<br>
<br>
Car les technologies d'indexation multidimensionnelle dans une base de<br>
données relationnelle existent depuis longtemps (plusieurs dizaines<br>
d'années qu'elles sont proposées au départ comme extensions dans les<br>
SGBD, puis intégrées totalement à ces systèmes qui incluent nativement<br>
la création de tels index, pour différentes applications y compris les<br>
"métacubes" qui effectuent des agrégations complexes de données au<br>
départ purement relationnelles et à valeur simples).<br>
<br>
La syntaxe de création de tels index multidimensionels peut être aussi<br>
simple que:<br>
<br>
CREATE INDEX nodes_coords ON nodes ((x, y))<br>
<br>
où les parenthèses internes indiquent que les attributs indiqués ne<br>
privilégient pas un ordre d'indexation d'un attribut par rapport à un<br>
autre, mais demandent à l'index de maintenir automatiquement un<br>
parcours équilibré de l'index entre les dimensions indiquées.<br>
<br>
En l'absence de tels index multidimensionnels intégrés au moteur SQL,<br>
il fallait d'abord créer dans la table de noeuds une valeur d'attribut<br>
supplémentaire, produite par une transformée alternant les bits de<br>
données successifs de chaque coordonnées, et ensuite créer un index<br>
basé sur la valeur de cet attribut spécial.<br>
<br>
Mais c'était coûteux en espace, et pas optimal non plus car la<br>
transformation était prédéterminée en fixant dès le départ le mode de<br>
découpage strictement alterné entre les dimensions, sans tenir compte<br>
du poids statistique réel de chaque découpe fixée aussi sur des<br>
valeurs de seuil prédéterminées (sans tenir compte de la densité<br>
réelle des éléments dans chaque découpe : l'arbre de découpage n'était<br>
pas bien équilibré à cause justement de cette transformation<br>
arbitrairement prédéterminée sur des seuils fixes, là où un index<br>
multidimensionnel détermine localement et automatiquement les seuils<br>
les plus adéquats pour maintenir le meilleur équilibre statistique et<br>
une densité à peu près constante dans tous les parcours possibles et à<br>
tous les niveaux de l'arbre).<br>
<br>
Le 22 février 2012 18:31, Philippe Verdy <<a href="mailto:verdy_p@wanadoo.fr">verdy_p@wanadoo.fr</a>> a écrit :<br>
<div class="HOEnZb"><div class="h5">> Non, la signature numérique ne modifie pas du tout l'API car cela<br>
> n'apparaîtra que comme des attributs de plus parmi d'autres.<br>
><br>
> Le 22 février 2012 18:29, Emilie Laffray <<a href="mailto:emilie.laffray@gmail.com">emilie.laffray@gmail.com</a>> a écrit :<br>
>> Salut,<br>
>><br>
>> c'est fort intéressant mais plutôt que nous abreuver de ce genre de détails<br>
>> peut être faudrait il en parler sur la liste de Développement en anglais, la<br>
>> ou toutes les réelles discussions techniques ont lieu.<br>
>> De plus, il y a des raisons historiques et de performances pour le<br>
>> comportement de l'API. Déjà, c'est un choix volontaire de réduire la taille<br>
>> car c'est une API pour les contributeurs. Quand le point est soulevé, on<br>
>> pointe vers le fichier planète avec synchronisation.<br>
>> Ce que tu offres c'est un peu un raisonnement un peu déconnectée de la<br>
>> réalité. De plus, la réplication est déjà possible. Passer vers une solution<br>
>> décentralisée avec une signature ne résoudra pas grand chose et le coup de<br>
>> calcul des signatures sera important, sans parler le coup de la<br>
>> synchronisation (il suffit de demander aux gens qui ont des miroirs ici)<br>
>> rend une vrai solution décentralisée extrêmement compliquée.<br>
>> Ta solution de la signature si elle n'est pas valide obligerait de rappeler<br>
>> l'API et donc de rajouter une charge supplémentaire.<br>
>><br>
>> Emilie Laffray<br>
>><br>
>> 2012/2/22 Philippe Verdy <<a href="mailto:verdy_p@wanadoo.fr">verdy_p@wanadoo.fr</a>><br>
>>><br>
>>> Le 22 février 2012 15:49, sly (sylvain letuffe) <<a href="mailto:liste@letuffe.org">liste@letuffe.org</a>> a<br>
>>> écrit :<br>
>>> > On mercredi 22 février 2012, sukran.geo sukran.geo wrote:<br>
>>> >> Bonjour, J'ai une zone dans OSM que je veux télécharger, mais...<br>
>>> >> apparemment, elle est trop grande, et voici le message qui s'affiche.<br>
>>> >> (voir<br>
>>> >> JPEG Joint) J'ai ensuite téléchargé le fichier de Geofabrik, mais idem,<br>
>>> >> pb<br>
>>> >> de taille. Que faire ? Il me faut toute la zone, et je ne veux pas pas<br>
>>> >> faire<br>
>>> >> plein de petits morceaux.<br>
>>> ><br>
>>> > Elle est grosse comment ta zone ?<br>
>>> > Parce que si tu veux ouvrir un département complet dans JOSM, il vaut<br>
>>> > mieux<br>
>>> > oublier tout de suite et faire autrement ;-)<br>
>>> > Si c'est raisonnablement petit, mais que l'api officielle te bloque,<br>
>>> > dans JOSM<br>
>>> > tu peux tenter de remplacer <a href="http://api.openstreetmap.org" target="_blank">api.openstreetmap.org</a> par<br>
>>> > <a href="http://api.openstreetmap.fr" target="_blank">api.openstreetmap.fr</a><br>
>>> > les limites en téléchargement son plus élevées<br>
>>><br>
>>> Mais c'est vrai aussi qu'il manque à la base OSM un vrai système de<br>
>>> réplication sur des miroirs synchronisés, capables de répondre de<br>
>>> concert à une même requête.<br>
>>><br>
>>> Quelques idées suivent...<br>
>>><br>
>>> Une sorte de RSYNC mais adapté aux bases de données (et non à un<br>
>>> système de fichiers hiérarchique), par lequel toute modification<br>
>>> enregistrée dans la base principale permet d'alimenter un flux de<br>
>>> redistribution des transactions "committées" vers un ensemble de bases<br>
>>> miroirs. De tels systèmes de réplication sont dans tous les RDMBS<br>
>>> commerciaux, mais pas toujours dans les RDBMS libres où ce sont<br>
>>> souvent des greffons mal intégrés ne garantissant pas la<br>
>>> synchrinisation de l'ensemble et la cohérence relationelle des<br>
>>> transactions annulées par un "rollback".<br>
>>><br>
>>> Cela nécessite des systèmes réellement transactionnels pour valider<br>
>>> l'état réel des modifications confirmées sur une base centrale, mais<br>
>>> aussi un système de "rattrapage" permettant même de resynchroniser une<br>
>>> base esclave qui aurait perdu à un moment donné le fil et devrait se<br>
>>> remettre à jour (par exemple en cas d'arrêt momentané pour une<br>
>>> maintenance, ou à cause d'un problème réseau temporaire, ou simplement<br>
>>> pour démarrer une nouvelle base esclave au départ vierge, avec une<br>
>>> synchronisation qui va progressivement charger les donnés manquantes).<br>
>>><br>
>>> Enfin si une telle réplication était réellement opérationnelle et<br>
>>> assez rapide pour qu'un ensemble de bases miroirs puissent toutes<br>
>>> répondre à une demande de chargement de données (je ne parle pas des<br>
>>> requêtes de modification de ces données), une déclaration de ces bases<br>
>>> miroirs opérationnelle pourrait avoir lieu dans le système DNS afin<br>
>>> que ces requêtes soient distribuées au hasard sur n'importe laquelle<br>
>>> de ces bases et pas forcément la base centrale qui est bien plus utile<br>
>>> et seulement nécessaire pour valider les transactions de modification.<br>
>>><br>
>>> Cela imposerait d'avoir deux adresses (URL) de bases de données dans<br>
>>> les éditeurs : une pour les chargements et mises à jour, l'autre pour<br>
>>> les modifications, sachant que ce n'est qu'au moment où on va valider<br>
>>> les données (dans un système de « validation en deux phases ») que la<br>
>>> première chose qui sera faite sera de comparer les versions provenant<br>
>>> des miroirs et celles actuellement dans la base, afin qu'à ce seul<br>
>>> moment-là le serveur central puisse fournir une URL vers les données à<br>
>>> jour dans un des miroirs disponibles sur lequel le serveur central<br>
>>> pourrait poser un verrou temporaire sur les objets correspondants,<br>
>>> pour la validation en deux phases, jusqu'à ce que soit la transaction<br>
>>> soit validée par un "commit" soit annulée par un "rollback", soit que<br>
>>> cette annulation ait lieu automatiquement après un délai raisonnable,<br>
>>> le client devant alors refaire ses transactions et étant prévenu que<br>
>>> sa dernière transaction a été annulée).<br>
>>><br>
>>> Bote: les transations sont autre chose que les groupes de<br>
>>> modifications qui sont des regroupements logiques effectués<br>
>>> utilisateur par utilisateur (selon leur propre logique et leur<br>
>>> déploiement car un même utilisateur peut utiliser simultanément<br>
>>> plusieurs outils et donc avoir plusieurs groupes de modification<br>
>>> ouverts. Ces groupes sont ouverts pour une durée relativement longue<br>
>>> (la fermeture automatique n'a lieu qu'au bout de deux heures<br>
>>> d'inactivité sur ce groupe, en théorie du moins car j'ai déjà vu le<br>
>>> serveur fermer prématurément un groupe en moins de 5 minutes, et même<br>
>>> parfois au beau milieu d'un enregistrement, les autres modifications<br>
>>> non envoyées étant alors rejetées mais devant être enregistrées dans<br>
>>> un autre groupe).<br>
>>><br>
>>> Pour moi la fermeture automatique des groupes n'est pas nécessaire,<br>
>>> sauf pour leur attacher quelques attributs en commun. Notamment le<br>
>>> suivi des attributs indiquant quel est logiciel utilisé, qui l'a créé,<br>
>>> quand il a commencé et quand *l'utilisateur* a indiqué qu'il avait<br>
>>> terminé, et finalisé son commentaire.<br>
>>><br>
>>> Le commentaire ne devrait être finalisé que si *toutes* les modifs ont<br>
>>> pu être envoyées. En cas de conflit d'édition, un groupe de modifs<br>
>>> peut rester ouvert relativement longtemps, le temps pour l'utilisateur<br>
>>> de régler ces conflits avant de soumettre les autres données, dont bon<br>
>>> nombre d'ailleurs ne sont pas en conflit.<br>
>>><br>
>>> Mais le serveur alors va fermer prématurément un groupe de modifs,<br>
>>> alors que les données envoyées sont incomplètes, ce qui laisse par<br>
>>> exemple des noeuds ajoutés, mais pas les chemins qui les connecte, ou<br>
>>> des voies ajoutées sensées remplacer une autre dont la demande de<br>
>>> suppression n'est pas encore passée.<br>
>>><br>
>>> A cause de cela, cela laisse des doublons et données incohérentes dans<br>
>>> la base, et aucun moyen pour les outils de suivi de savoir quoi faire.<br>
>>> D'autant plus que le serveur OSM ne renseigne même pas quand il a<br>
>>> *lui-même* fermé un groupe de modification laissé ouvert (normalement<br>
>>> le temp pour l'utilisateur de régler les conflits ou ses problèmes de<br>
>>> connexion).<br>
>>><br>
>>> Bref, la fermeture automatique des groupes de modification est une<br>
>>> très mauvaise idée, et même une totale et complète ***aberration*** du<br>
>>> schéma actuel. Cela ne correspond d'ailleurs à rien en terme<br>
>>> transactionnel, puisque les validations (commits) et réplications se<br>
>>> feront à une échelle bien plus petite, celles des objets (avec leurs<br>
>>> attributs et leurs membres pour les relations).<br>
>>><br>
>>> Les groupes de modifications eux-mêmes sont un objet distinct de la<br>
>>> base de données. Leur existence est nécessaire avant toute autre<br>
>>> opérations de création/modification/suppression sur les autres objets,<br>
>>> mais personne d'autre que l'utilisateur qui l'a créé via son logiciel,<br>
>>> ***pas même le serveur***, ne doit avoir à en contrôler l'indication<br>
>>> de sa fermeture, ni certains autres attributs tels que le commentaire,<br>
>>> voire des métadonnées nécessaires à la l'octroi de licence, car<br>
>>> personne d'autre que lui ne pourra les changer (en revanche le serveur<br>
>>> continuera à contrôler des attributs comme l'identité de<br>
>>> l'utilisateur, si cette identité a été certifiée par un protocole<br>
>>> sécurisé, et les dates d'ouverture ou de dernière modification dans ce<br>
>>> groupe ; il ne fera éventuellement qu’exiger que certains autres<br>
>>> attributs soient renseignés dans le groupe de modifications, comme<br>
>>> l'identification suffisante du logiciel utilisé, ou le "user-agent"<br>
>>> d'un navigateur, et quelques autres données comme la langue utilisée<br>
>>> dans le logiciel de l'utilisateur).<br>
>>><br>
>>> Ces objets "groupes de modifications" entrent dans les données<br>
>>> nécessaires pour analyser les historiques, retrouver les auteurs,<br>
>>> comprendre les raisons de certaines données, ou à quoi elles étaient<br>
>>> peut-être destinées; elles sont aussi indispensable pour suivre les<br>
>>> conditions de licence et donc doivent être conservées si les autres<br>
>>> objets qui sont listés dans ce groupe à une version donnée sont encore<br>
>>> présents dans la base. Ces groupes de modification sont aussi à<br>
>>> transporter dans les systèmes de synchronisation, au même titre que<br>
>>> les objets géométriques (neuds et chemins) et les relations (ces<br>
>>> objets les référencent version par version).<br>
>>><br>
>>> Un groupe de modifications peut être mis à jour autant de fois que<br>
>>> nécessaire par un même utilisateur et sans limite de durée — du moins<br>
>>> tant que le même utilisateur n'a pas rouvert un autre groupe<br>
>>> référençant des modifications sur un ou plusieurs des mêmes objets<br>
>>> géométriques ou relations, seul cas où éventuellement on peut admettre<br>
>>> une fermeture automatique. Mais je penche plutôt sur une condition de<br>
>>> fermeture basée sur un volume maximum en nombre d'objets modifiés dans<br>
>>> le groupe (basée davantage sur une politique mise en œuvre par le<br>
>>> logiciel client qu'un contrôle absolu par le serveur), afin que le<br>
>>> client s'assure d'envoyer des données cohérentes et suffisantes dans<br>
>>> un même groupe de modifications, notamment quant il doit créer ou<br>
>>> modifier un chemin, dont les nœuds modifiés/créés/ajoutés devraient<br>
>>> toujours être dans le même groupe de modifications. Le logiciel client<br>
>>> pourra créer automatiquement autant de groupes de modifications que<br>
>>> nécessaire pour respecter correctement les contraintes de volume par<br>
>>> groupe, mais seul l'utilisateur doit en contrôler la fermeture, même<br>
>>> s'il y en a plusieurs, afin qu'il puisse finaliser le commentaire et<br>
>>> les données nécessaires à une licence ou le contrôle ultérieur de<br>
>>> validité de cette licence, telles que la citation d'une source<br>
>>> autorisée, ou encore des commentaires destinés à une maintenance<br>
>>> ultérieure sur des données seulement estimées ou incomplètes, ou<br>
>>> encore pouvoir résoudre un conflit partiel nécessitant de modifier<br>
>>> encore un objet déjà envoyé dans ce groupe de modifications.<br>
>>><br>
>>> En revanche les transactions sur le serveur c'est autre chose ! Cela<br>
>>> ne concerne que les objets individuels (ou presque) et se limite à<br>
>>> assurer qu'il n'y a pas de conflit de versions, ni perte de la<br>
>>> cohérence référentielle de base:<br>
>>> * un chemin doit toujours associer au moins deux nœuds (quitte à ce<br>
>>> qu'ils soient superposés géométriquement).<br>
>>> * les nœuds d'un chemin doivent toujours exister, et doivent avoir un<br>
>>> numéro de rang unique dans ce chemin (afin de pouvoir définir un<br>
>>> ordre).<br>
>>> * les membres d'une relation doivent toujours exister, et doivent<br>
>>> avoir un numéro de rang unique dans la relation (afin de pouvoir<br>
>>> définir un ordre).<br>
>>> * chaque version d'un noeud/chemin/relation doit toujours référencer<br>
>>> un groupe de modifs existant,<br>
>>> * une même version d'un noeud/chemin/relation ne peut pas être<br>
>>> référencée par plusieurs groupes de modifs,<br>
>>> * un groupe de modifs doit toujours référencer un utilisateur<br>
>>> existant et cette référence à un utilisateur ne peut pas être changée<br>
>>> (on ne peut que supprimer un groupe de modifiations et les versions de<br>
>>> nœuds/chemins/relations qui référencent ce groupe).<br>
>>> * et certains attributs sur ces objets sont obligatoires et respecter<br>
>>> certaines contraintes pour leur valeur ou leur format.<br>
>>><br>
>>> Ces règles de base (purement relationnelles) sont celles servant à<br>
>>> définir les briques minimales de ce qui sera synchronisé entre<br>
>>> serveurs ou miroirs et lors des transactions (même pour les<br>
>>> transactions à validation multiphase). Avec cela on peut sérieusement<br>
>>> envisager un déploiement solide et plus large de serveurs coopérant<br>
>>> entre eux, y compris pour la contribution de leur bande passante, et<br>
>>> avec les utilisateurs, avec un coût partageable qui pourra être réduit<br>
>>> pour le bénéfice de tout le monde pour peu que chacun puisse faire une<br>
>>> contribution, même petite au regard du volume total des transactions<br>
>>> échangées, mais pourtant utile à tous car elle aussi partagée et<br>
>>> offerte aussi aux autres en tant que service supplémentaire.<br>
>>><br>
>>> Toutefois pour que les miroirs fonctionnent réellement, il doit<br>
>>> exister un moyen de vérifier que ceux-ci ne véhiculent pas<br>
>>> d'informations altérées par rapport au serveur central où sont<br>
>>> validées les modifs. La solution simple consiste à ce que le serveur<br>
>>> central calcule une signature numérique des données qu'il a validées,<br>
>>> avec un certificat de sécurité dont il détient seul la clé privée,<br>
>>> tandis qu'il fournit à tous une copie du certificat de sécurité<br>
>>> contenant la clé publique permettant de comparer les signatures<br>
>>> numériques recalculées. Cette signature numérique serait alors un<br>
>>> attribut de tous les objets qui peuvent accessibles et sont distribués<br>
>>> par la base.<br>
>>><br>
>>> La signature numérique d'une version d'un objet étant dépendante de la<br>
>>> date de cette version, ainsi que du certificat utilisé pour la<br>
>>> calculer à cette date, il faut aussi que l'objet contiennent la<br>
>>> référence à ce certificat (devenu un objet relationnel à part entière<br>
>>> dans la base). Ce qui permet aussi plus tard de mettre à jour ou<br>
>>> changer ces certificats et de recalculer les signatures numériques des<br>
>>> autres objets relationnels (et leurs attributs textuels, numériques ou<br>
>>> géométriques) en cas d'expiration du certificat. Bref deux attributs<br>
>>> par objet: la signature numérique (par exemple une chaine hexadécimale<br>
>>> de longueur fixe dans un attribut "Signature:SHA1"), et un URI (URL ou<br>
>>> URN) vers la copie publique du certificat de sécurité (dans un<br>
>>> attribut comme "Signature:Certificate").<br>
>>><br>
>>> Ces attributs seront calculés par le serveur de validation uniquement<br>
>>> et présentés dans toutes les requêtes. Il faut une signature séparée<br>
>>> par objet (nœud, chemin, relation, groupe de modifications,<br>
>>> utilisateur), cette signature exposée publiquement ne devant être<br>
>>> calculée QUE sur les données publiques accessibles (pas les données<br>
>>> privées ou secrètes, par exemple dans un objet de type utilisateur).<br>
>>><br>
>>> De la même façon le serveur central de validation peut aussi calculer<br>
>>> une signature numérique pour un objet représentant un serveur<br>
>>> lui-même, si le système autorise ce serveur à effectuer des<br>
>>> validations locales qui seront ensuite transmises par ce serveur local<br>
>>> au serveur central, "au nom de" ses propres utilisateurs sur le<br>
>>> serveur local. Cela permet un système où la confiance et la<br>
>>> responsabilité peut être déléguée et partagée, de façon limitée, avec<br>
>>> une responsabilité assumée par celui qui gère un serveur local. Cela<br>
>>> peut aussi servir à accorder à un serveur local davantage de droits en<br>
>>> terme de bande passante, car il assure un service pour de nombreux<br>
>>> utilisateurs en soulageant le serveur central de la visite de ces<br>
>>> mêmes nombreux utilisateurs.<br>
>>><br>
>>> Avec un objet dans la base de données représentant un serveur<br>
>>> (probablement représenté par une URL, mais ce peut être aussi un<br>
>>> simple ID numérique vers un objet contenant en attribut cette URL à<br>
>>> priori unique dans la base), une requête à un serveur pourra donner<br>
>>> une réponse contenant la référence à un autre serveur disponible (par<br>
>>> exemple lors d'opérations de maintenance sur l'un d'eux, ou d'un<br>
>>> problème de disponibilité d'une liaison, ou de délai de mise à jour<br>
>>> dans les données en cache d'un serveur DNS utilisé par le client).<br>
>>><br>
>>> _______________________________________________<br>
>>> Talk-fr mailing list<br>
>>> <a href="mailto:Talk-fr@openstreetmap.org">Talk-fr@openstreetmap.org</a><br>
>>> <a href="http://lists.openstreetmap.org/listinfo/talk-fr" target="_blank">http://lists.openstreetmap.org/listinfo/talk-fr</a><br>
>><br>
>><br>
</div></div></blockquote></div><br>