Skip to content
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

Adaptation du schéma de données pour MySQL #11

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Pierrot-ongit
Copy link

Pour faciliter la conversion de la bdd SQLITE en format MySQL

legi/sql/schema.sql Outdated Show resolved Hide resolved
@Changaco
Copy link
Member

Changaco commented Mar 6, 2017

À vrai dire je n'aime pas beaucoup l'idée de dégrader le schéma SQL pour se conformer aux limitations de MySQL.

@Changaco Changaco changed the title Patch 1 Adaptation du schéma de données pour MySQL Mar 7, 2017
Pierrot-ongit and others added 3 commits March 7, 2017 17:10
Changement de la key de la table db_meta, et mise au format char(30) au lieu de text.
Cela ne devrait rien changer à la version SQLITE. Par contre lorsque la db SQLITE est converti en db MySQL, il n'est pas possible d'avoir une clé en TEXT.
Même raison que patch précédent. En SQLITE, il n'y pas de problème à ce qu'une clé de table (ou index) soit en format text. En MYSQL, par contre cela n'est pas permis.
Ce changement ne devrait rien changer au bon fonctionnement de la génération de la bdd en SQLITE et permettra de la convertir en MYSQL sans avoir à corriger le fichier SQLITE manuellement avant.
@Seb35
Copy link
Member

Seb35 commented Mar 19, 2017

J’aimerais bien aussi que ça puisse être disponible pour MySQL ; à l’utilisation, la base SQLite est assez lente sur mon ordinateur (là, je viens de lancer la recherche des articles d’une section et en attendant j’écris ce message) et je pense bien que MySQL ne souffrirait pas de telles lenteurs.

Sur le changement du schéma, c’est somme toute assez mineur, et vu les avantages procurés (Pierre pourrait utiliser legi.py après conversion du SQLite -> MySQL, et possibles/probables gains de vitesse) le ratio coûts/bénéfices me semble fortement positif.

Sur les coûts, il y a surtout le changement pour les bases existantes. Mais il est possible qu’il n’y ait pas besoin de les changer, seulement les nouvelles intègreraient ce nouveau schéma.

Je suis (encore) en train de travailler sur legi.py+Archéo Lex (j’avais pas beaucoup avancé). J’essaye de tester aujourd’hui :

  • ce patch sur une nouvelle base
  • ce patch sur une base actuelle

@Changaco
Copy link
Member

Je doute que tu obtiennes un fort gain de performance simplement en changeant de moteur SQL. Si une requête prend beaucoup de temps c'est pour deux raisons:

  • elle n'utilise pas un index
  • les données ne sont pas en RAM

Pour optimiser une requête SQL il est utile d'analyser son exécution avec EXPLAIN.

@Changaco
Copy link
Member

Modifier uniquement le schéma SQL ne me semble pas être une bonne idée, tout gain de performance qui serait obtenu par chance en utilisant un autre moteur serait perdu en temps de mise à jour de la base. S'il y a un réel besoin d'utiliser un autre moteur SQL alors il faudrait modifier tout legi.py pour qu'il devienne indépendant de SQLite.

@Seb35
Copy link
Member

Seb35 commented Mar 20, 2017

En l’occurence, Pierre peut importer dans Drupal, pour son projet, une base MySQL (qui est courrament utilisée pour Drupal). Étant donné que c’est du SQLite, il faut soit convertir vers MySQL, soit trouver un connecteur SQLite. Je crois qu’il a cherché un peu SQLite sans trop trouver, puis la conversion vers MySQL semblait la plus facile, mais on s’est heurté au problème d’incompatibilité du schéma.

La solution de contournement temporaire a été de faire un dump puis d’appliquer les modifications de schéma, puis d’importer dans MySQL, et ça a marché. Bien sûr, il pourra continuer à faire ça à chaque import, mais si ça peut être facilité, c’est toujours ça de pris.

L’argument de performance me concerne plus particulièrement, j’aimerais bien que ça soit plus rapide, notamment pour faire de l’export sur une base régulière. Ça, c’est mon souhait, après les moyens d’y arriver sont ouverts. Je vais essayer d’importer dans MySQL pour vérifier, je vais peut-être effectivement me casser les dents. Et si ça ne marche pas, pourrais-t-on ajouter des clés primaires ? Je voyais qu’il n’y en avait pas sur sections.id ou articles.id. Enfin, ça c’est une autre pull request à discuter peut-être ailleurs.

@Changaco
Copy link
Member

sections.id et articles.id sont des clés primaires, elles ont unique not null (ce qui est à peu près la même chose que primary key).

@JMLX42
Copy link
Member

JMLX42 commented Mar 20, 2017

À vrai dire je n'aime pas beaucoup l'idée de dégrader le schéma SQL pour se conformer aux limitations de MySQL.

Je pense que c'est l'inverse.
Dans le cas présent, SQLLite ignore surement complètement l'index posé sur des champs de type "text".

En l'occurrence, changer le schéma tel que décrit dans le premier patch permettrait d'avoir des index sur les champs en question (ce qui était à priori dans le schéma original mais ignoré par SQLLite), ce qui boostera les performances.

Donc ça ne dégrade pas le schéma SQL. Bien au contraire. Ca le rend plus compatible et plus performant.

Modifier uniquement le schéma SQL ne me semble pas être une bonne idée

Si le schéma SQL n'est pas valide (ce qui est à priori le cas, cf mon commentaire plus haut), alors je ne vois pas pourquoi ça n'est pas une bonne idée.

S'il y a un réel besoin d'utiliser un autre moteur SQL alors il faudrait modifier tout legi.py pour qu'il devienne indépendant de SQLite.

SQLLite est censé être un dropin pour MySQL en mode embarqué.
Il y'a très probablement un driver MySQL avec une interface compatible avec tout ce qui existe déjà dans legi.py.
Dans le meilleur des cas, ça doit revenir à changer une ligne de code pour utiliser le driver MySQL au lieu de SQLLite, et les deux pourraient même rester utilisables via une option.

@Changaco
Copy link
Member

Dans le cas présent, SQLLite ignore surement complètement l'index posé sur des champs de type "text".

Non, d'ailleurs tu peux voir que les index sont bien présents dans le diagramme du schéma #9 (comment). Un index sur une colonne de type text est parfaitement normal, SQLite et PostgreSQL les gèrent très bien, il n'y a que MySQL qui ne sait pas le faire.

SQLLite est censé être un dropin pour MySQL en mode embarqué.

Non, ce sont deux projets indépendants et incompatibles entre eux.

@fgallaire
Copy link
Member

SQLite est super dans l'optique d'une utilisation personnel sur un client Desktop, pas de serveur de BD à installer.

MySQL ouvre vers un autre type d'utilisation, avec une intégration aisée avec des frameworks/CMS/sites utilisant déjà un serveur de BD.

Je pense que les deux utilisations sont intéressantes, et qu'une ORM permettant de mettre la BD que l'on veut derrière, avec choix par défaut SQLite, serait un choix logique.

@Changaco
Copy link
Member

Les ORM ont tendance à dégrader les performances et à empêcher l'optimisation. Pour rendre legi.py indépendant de SQLite je pencherais plutôt pour https://pypi.python.org/pypi/sql ou https://pypi.python.org/pypi/records.

@JMLX42
Copy link
Member

JMLX42 commented Mar 26, 2017

Je ne vois toujours pas pourquoi on mettrait pas un champ text en varchar vu que ça ne change rien pour SQLLite mais qu'au moins ça marche en MySQL. Personne n'y perd, ceux qui veulent utiliser MySQL y gagnent. Où est le soucis ?

@fgallaire
Copy link
Member

Les ORM sont une couche intermédiaire, donc oui par nature elle dégradent les performances. Mais c'est une petite constante, les perf dépendent surtout de la complexité de la requếte. Si ce niveau de perfs compte, alors faut réécrire legi.py en C...

BTW records est basé sur l'ORM SQLAlchemy.

@Changaco
Copy link
Member

@promethe42 Le soucis est qu'il s'agit d'une bidouille. On ne peut pas garantir que limiter artificiellement titrefull_s à 512 caractères fonctionnera toujours.

@Changaco
Copy link
Member

@fgallaire Indirectement legi.py est déjà majoritairement en C, à travers les modules qu'il utilise (libarchive, lxml, sqlite, etc). Le code python ne fait que le lien entre tout ça.

Tu as raison quand tu dis que la complexité des requêtes SQL est un facteur important, et c'est justement un point faible des ORMs : ils cachent les requêtes et rendent plus difficile l'optimisation de celles-ci.

(Je sais que records est basé sur SQLAlchemy, mais je doute qu'il utilise la partie ORM de celui-ci.)

@JMLX42
Copy link
Member

JMLX42 commented Mar 30, 2017

Le soucis est qu'il s'agit d'une bidouille. On ne peut pas garantir que limiter artificiellement titrefull_s à 512 caractères fonctionnera toujours.

Inversement, un index sur un truc qui fait plus de 512 caractères me semble étrange.

Quelle est la longueur max aujourd'hui ? D'après ce que j'ai compris, c'est très (très) inférieur à 512 caractères. Alors que le besoin d'une compatibilité MySQL existe bel est bien aujourd'hui.

@fgallaire
Copy link
Member

Ajouter un flag ou une option du genre schema=sqlite par défaut et schema=mysql pour ceux qui en ont besoin pourrait arranger tout le monde non ?

@revolunet
Copy link

En solution alternative, on pourrait peut-être crowdsourcer sur github des scripts de migration vers d'autres formats ? (ex: postgres, json...)

@revolunet
Copy link

revolunet commented Feb 28, 2018

Hello

Pour info j'ai fait un test avec postgresql; en convertissant le fichier sqlite vers postgres :

pgloader --cast "type day to varchar" legi.sqlite postgresql://postgres:[email protected]:5433/legi

je passe de 150s à 50s pour générer une version du code de la PI (avec archeo-lex)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants