Journal MySQL est une bouse immonde

Posté par .
Tags :
30
6
mar.
2012

Ayant commencé une petite appli web avec le framework Catalyst (très bon au passage), j'ai naturellement commencé le développement en utilisant la BDD SQlite.

Très bonne petite base de données embarquée, mais mieux vaut avoir un truc un peu plus costaud en prod. Naïvement, je me suis orienté vers mysql, que je considérais comme une mise à jour logique de sqlite : plus adapté à l'utilisation voulue tout en restant simple.

Heureux de cette conclusion, je donne à bouffer le schéma à mysql qui l'accepte sans broncher, tout a l'air bien parti.

Quelques heures plus tard, je vois que l'appli marche bizarrement : effectivement, à y regarder de plus près une clé étrangère fait référence à une clé primaire inexistante. Je regarde le schéma et effectivement, les clés étrangères n'ont pas été crées. Un peu embêtant de ne pas avoir eu de message d'erreur à la création des tables mais passons, le fait que les tables MyISAM par défaut ne supportent pas les clés étrangères est connu.

On repart pour un tour, cette fois-ci en faisant attention à bien utiliser InnoDB. Ça fonctionne bien mieux, mais encore quelques heures plus tard, je me retrouve avec des données corrompues. Je regarde de plus près mon blob à problèmes, et sa longueur n'est pas anodine : 65535. Quelques recherches google plus tard et après quelques arrachages de cheveux, je constate que, par défaut, MySQL ne retourne pas d'erreur quand on insère une valeur incorrecte dans un champ. Relativement "logique" en fait, vu que cette BDD n'est pas transactionnelle par défaut.

Un petit "SET sql mode = 'TRADITIONAL';" plus tard le problème est résolu. Ce n'est que quelques minutes que je constate un autre problème : l'appli affiche une date de création anormalement récente pour pleins de choses. Arrachage de cheveux, questionnement sur la bonne utilisation de DBIx (l'ORM utilisé par Catalyst) que je découvre, et enfin une découverte uxamifiante : les champs de type timestamp se mettent à jour automatiquement à la date/heure courante quand on fait un update sur la table _o_

Bref, j'abandonne cette bouse de MySQL, je vais essayer PostgreSQL et serai bien plus indulgent avec les petits défauts d'Oracle et DB2.

PS : Manifestement, je ne suis pas le seul à avoir des problèmes avec ce simulacre de base de données, qui a aussi le défaut de chier lamentablement sur de l'unicode parfaitement valide : http://linuxfr.org/suivi/fermeture-problematique-de-balises-markdown

PS2 : Et pour se détourner de cette abomination, voilà la désormais traditionnelle jolie nimage : http://30.media.tumblr.com/tumblr_m0cdp5ipIE1qbsz3ko1_500.png

  • # t'accuse

    Posté par . Évalué à 10.

    merci pour ce journal qui dénonce grave.
    Et merci pour la jolie nimage qui… bref, qui est jolie.

    question : pourquoi ne pas rester à sqlite si ça fonctionne bien comme ça ?

    Only wimps use tape backup: real men just upload their important stuff on megaupload, and let the rest of the world ~~mirror~~ link to it

    • [^] # Re: t'accuse

      Posté par . Évalué à 5. Dernière modification le 06/03/12 à 23:09.

      question : pourquoi ne pas rester à sqlite si ça fonctionne bien comme ça ?

      Principalement deux raisons :

      • SQLite n'a pas de types date/heure spécifiques, ce qui est un peu pénible pour générer le schéma automatiquement dans DBIx
      • Un serveur de BDD est plus flexible et sûr qu'un fichier qui traine quelque part et est entièrement lisible par l'user de l'application
      • [^] # Commentaire supprimé

        Posté par . Évalué à 3.

        Ce commentaire a été supprimé par l'équipe de modération.

        • [^] # Re: t'accuse

          Posté par (page perso) . Évalué à 5.

          Le but d'utiliser un orm c'est, aussi, qu'il va te faire un mapping entre ta base et des champs du bon type.
          Si tu met du unix time en string dans la base, ton orm va te sortir une string. Donc ça ne sert à rien car tu dois le relire, caster, etc avant de t'en servir.
          Si tu met un champ de type date / time / datetime / … dans la base, ton orm va gentiment te le caster dans un champ de type Date / … donc tu peux te servir de la date tout de suite. Idem en insertion.

          • [^] # Commentaire supprimé

            Posté par . Évalué à 5.

            Ce commentaire a été supprimé par l'équipe de modération.

            • [^] # Re: t'accuse

              Posté par . Évalué à 3.

              Ben voilà, peut-être une explication. Mais je ne suis pas sur que cela soit celle de bombe fourche.

              Ma problématique est la suivante : imaginons que j'ai une table plop avec un champ creation_date.

              Si le champ est de type timestamp, plop->all[0]->creation_date est un objet perl DateTime.

              Si le champ est de type text ou autre (fonctionnement de sqlite), plop->all[0]->creation_date est de type text ou autre, et il faut modifier manuellement le schéma généré pour que ce soit automatiquement désérialisé dans un objet DateTime.

              Sinon en ce qui concerne les ORM j'ai tendance à être d'accord avec toi, d'où le choix de DBIx : il est très léger et a pour principal intérêt de ne pas avoir à faire trainer dans le code une requête SQL suivie d'une boucle pour les select relativement simples.

              • [^] # Commentaire supprimé

                Posté par . Évalué à 2.

                Ce commentaire a été supprimé par l'équipe de modération.

                • [^] # Re: t'accuse

                  Posté par . Évalué à 1.

                  Le time_t est peut-être alors une bonne (la moins mauvaise) solution. Il y a peu à faire coté application.

                  [:uxam] en quoi un time_t est une meilleure solution qu'un objet perl de (très) haut niveau ?

            • [^] # Re: t'accuse

              Posté par . Évalué à 2.

              Quelle idée ? Je la mets sous forme d'entier… et je la récupère dans un time_t.

              Si tu veux faire une requête sur tous les posts du vendredi pour compter le nombre de troll, ça va pas être facile sur un time_t.

              Ça n'empèche pas la base de stocker ensuite un time_t, elle sait juste comment manipuler la donnée.

            • [^] # Re: t'accuse

              Posté par . Évalué à 2.

              Je trouve que le monde OO et le monde relationnel sont bien trop loin l'un de l'autre pour avoir quelque chose qui fonctionne réellement

              +1000

    • [^] # Re: t'accuse

      Posté par (page perso) . Évalué à -2.

      Euh non, on n'utilise pas SQLITE sur un serveur web, ce n'est absolument pas fait pour. Concurrence d'accés et cie, bonjour les fichiers corrompus après.

      • [^] # Re: t'accuse

        Posté par . Évalué à 10.

        sqlite3 supporte la concurrence et est même ACID [:aloyd].

        Par contre le locking se fait au niveau de la BDD ce qui n'est pas exactement optimal pour une utilisation sur un serveur web en prod.

    • [^] # J'approuve (la nimage)

      Posté par . Évalué à 2.

      C'est vrai qu'elle est jolie la jolie nimage… c'est qui?

  • # \o/

    Posté par . Évalué à 2.

    \o/

    • [^] # Re: \o/

      Posté par (page perso) . Évalué à 3.

      \o_ _o/

      * Ils vendront Usenet^W les boites noires quand on aura fini de les remplir.

      • [^] # Re: \o/

        Posté par . Évalué à 6.

        (o)(o)

        moi aussi j'sais faire des dessins avec mon clavier!

        Vous pouvez moinser et reprendre une activité normale.

  • # normal

    Posté par . Évalué à 4.

    • [^] # Re: normal

      Posté par . Évalué à 10.

      Oui les timestamps c'était à insérer dans le schema.
      Et ce n'est pas tout, pour le problème de ne pas avoir utilisé innodb, c'était plutot à ton schema de contenir le type d'engine.
      En fait fallait un peu rtfm avant de l'utiliser..

      • [^] # Re: normal

        Posté par . Évalué à 10.

        Lire le manuel ? Tu n'y penses pas !

        Mieux vaut se servir de quelque chose qu'on ne connait pas, être surpris par un comportement et dire que c'est de la merde parce que ça n'est pas ce qu'on attendait !

        En plus comme ça on peut faire un journal.

        • [^] # Re: normal

          Posté par . Évalué à 3.

          Ce qui est étonnant c'est qu'à aucun moment tu as remis en cause ton ORM alors qu'il agit en tant qu'intermédiaire entre ton code et ta base.

        • [^] # Re: normal

          Posté par . Évalué à 4.

          Lire le manuel ? Tu n'y penses pas !

          Donc, si je comprends bien, si c'est documenté, tu trouves normal qu'une base de données qui a le mot SQL dans le nom se comporte de façon non prévue par le standard SQK et différente de toutes les autres bases de données ?

          • [^] # Re: normal

            Posté par (page perso) . Évalué à 10.

            En fait je pense que tu voulais utiliser un type DATETIME, pas TIMESTAMP qui sert comme son nom l'indique à stocker un horodatage des données de ta row.

            Mais t'as raison, continue de gueuler sur la base alors que t'es pas foutu de lire le manuel pour éviter des erreurs de débutant.

            Quant à invoquer une arlésienne du nom de Standard SQL, je me gausse : aucune base de données n'implémente le moindre standard SQL totalement et sans particularités locales (sans compter que le standard est très incomplet sur certaines choses essentielles comme la gestion des valeurs NULL, les mécanismes de locking, les stored procedures, etc…)

            Bref, les bases de données c'est pas un truc pour neuneus, sauf à utiliser une couche d'abstraction (qui forcément sera moins efficace).

            • [^] # Re: normal

              Posté par . Évalué à 8.

              C'est pas encore vendredi, mais je me lance.

              Quant à invoquer une arlésienne du nom de Standard SQL, je me gausse : aucune base de données n'implémente le moindre standard SQL totalement et sans particularités locales (sans compter que le standard est très incomplet sur certaines choses essentielles (…))

              C'est marrant, on pourrait presque remplacer "SQL" par "HTML/CSS/Javascript" et MySQL par Internet Explorer, et dire pratiquement la même chose. Mais dans ce cas, tout le monde ici n'hésiterait pas à dire qu'IE, c'est de la daube.

              Pourtant, la situation n'est pas bien différente : MySQL a bien des comportements bizarres et non-standards (documentés, certes, mais les trucs non standards d'IE sont eux aussi documentés), qui posent des problèmes de compatibilité.

              • [^] # Re: normal

                Posté par . Évalué à 7.

                C'est marrant, on pourrait presque remplacer "SQL" par "HTML/CSS/Javascript" et MySQL par Internet Explorer

                Sauf que dans le monde des bases de données, il n'y a que des internet explorer!

                • [^] # Re: normal

                  Posté par . Évalué à 7.

                  Ça ne change rien au fait que le standard existe, que certains font de vrais efforts pour s'y conformer au maximum (PostgreSQL, par exemple), alors que d'autre se torchent avec. MySQL est certainement pire que la plupart des bases de données proprio à ce niveau.

                • [^] # Re: normal

                  Posté par (page perso) . Évalué à 4.

                  Sauf que dans le monde des bases de données, il n'y a que des internet explorer!

                  Et chaque explorer utilise son propre web.

                  Au moins au temps héroïque du web (disons jusqu'à 2000), IE et Netscape tentaient de digérer les mêmes pages HTML (avec un rendu parfois incertain du fait des différences). Pour les bases de données, on est loin de l'interropérabilité.

                • [^] # Re: normal

                  Posté par . Évalué à 2.

                  Sauf que dans le monde des bases de données, il n'y a que des internet explorer!

                  La grande majorité des bases de données proprios et même la plupart des bases de données libre sont compatibles SQL92 voire SQL99.
                  Après comme partout il y a des extensions propriétaires, parfois bien pratiques et donc souvent sur-utilisées. Mais même Oracle commence à faire les cascade de CASE proprement.

                  Après au niveau du support du support SQL2003 c'est assez variable, mais bon SQL2003 part un peu dans tous les sens avec de multiples modules et des éléments comme le support d'ADA ou l'accès aux données via des maps objet/XML qui sont d'une utilité assez limité quand même.

            • [^] # Re: normal

              Posté par . Évalué à 10.

              Postgresql n'a pas de type DATETIME et utilise TIMESTAMP pour les dates.

              DB2 n'a pas de type DATETIME et utilise TIMESTAMP pour les dates.

              Oracle n'a pas de type DATETIME et utilise TIMESTAMP pour les dates.

              SQLite n'a pas de type DATETIME et n'increménte pas les dates magiquement.

              Pardon d'avoir supposé que c'était pareil dans MySQL.

              • [^] # Re: normal

                Posté par . Évalué à 10.

                • [^] # Re: normal

                  Posté par (page perso) . Évalué à 1.

                  Pour la défense de MySQL, bien que ce soit pas compatible avec une norme (c'est mal), nommer une date DATE, une temps TIME, mais ne pas nommer une date+temps DATETIME mais un truc qui ne ressemble pas et qui peut prêter à confusion (mettre "STAMP" dans le mot, j'avoue que je comprend une automatisation avec l'heure présente), c'est un peu du n'importe quoi.

                  Mais certes : c'est la norme, faudrait la suivre même si elle est nulle.

                  • [^] # Re: normal

                    Posté par . Évalué à 9.

                    Rien n'interdit d'avoir un type 'DATETIME' qui serait un alias vers TIMESTAMP. Mais effectivement, je suis d'accord, le nommage n'est pas très logique.

                    Par contre, ce qui est clairement impardonnable, c'est que MySQL réutilise un type définit par la norme et lui colle un comportement complètement délirant.

              • [^] # Re: normal

                Posté par (page perso) . Évalué à 2.

                En Transact-SQL (SQL Server, Sybase, les deux gros acteurs du marché après Oracle), le type "date avec l'heure" s'appelle DATETIME.

                Et les deux ont un type TIMESTAMP, mais ça n'est pas vraiment une date…

                Le monde merveilleux des bases de données…

              • [^] # Re: normal

                Posté par (page perso) . Évalué à -2.

                Et MySQL ne met à jour automatiquement les champs TIMESTAMP que si on le lui demande avec un DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP. Pourquoi avoir choisi cette option, si non voulue ?

                alf.life

                • [^] # Re: normal

                  Posté par . Évalué à 3.

                  Non :

                  With neither DEFAULT CURRENT_TIMESTAMP nor ON UPDATE CURRENT_TIMESTAMP clauses, it is the same as specifying both DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP.

                  • [^] # Re: normal

                    Posté par (page perso) . Évalué à 1.

                    Ah pardon, bien vu. Faut croire que j'ai la manie de toujours mettre une valeur par défaut.

                    alf.life

            • [^] # Re: normal

              Posté par . Évalué à 2.

              une arlésienne du nom de Standard SQL, je me gausse : aucune base de données n'implémente le moindre standard SQL totalement et sans particularités locales

              J'ai entendu dire que DB2 de chez IBM le respectait, mais je ne sais pas si c'est vrai.

    • [^] # Re: normal

      Posté par . Évalué à 10.

      J'adore cette partie de la doc MySQL, c'est je crois ma préférée :

      Elle commence par expliquer comment enlever les auto-insert et les auto-update du timestamp :

      Auto-initialization and auto-update:
      col_name TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      
      Auto-initialization only:
      col_name TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      
      Auto-update only:
      col_name TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP
      
      Neither:
      col_name TIMESTAMP DEFAULT 0
      
      

      Donc si on veut pas mettre le timestamp à jour il suffit de rajouter DEFAULT 0 dans la définition de la colonne
      C'est d'ailleurs redonné en exemple plus tard

      CREATE TABLE t (
      ts1 TIMESTAMP DEFAULT 0,
      ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                    ON UPDATE CURRENT_TIMESTAMP);
      
      

      Là on voit bien, ts1 aura une valeur à 0 par défaut, et ts2 aura la valeur current_timestamp

      SAUF QUE :

      The following examples that use DEFAULT 0 do not work if the NO_ZERO_DATE SQL mode is enabled because that mode causes “zero” date values (specified as 0, '0000-00-00, or '0000-00-00 00:00:00') to be rejected. Be aware that the TRADITIONAL SQL mode includes NO_ZERO_DATE.
      
      

      Ah oui, si on est en mode transactionnel, par défaut le 0 est en fait le #0 et ne peut pas être utilisé pour une date. C'est l'option NO_ZERO_DATE. Bon alors comme le #0 c'est un poil un standard SQL on va peut-être pas y toucher de peur des effets de bords et décider de mettre à jour à une autre date. Le truc c'est qu'il y a peut être des éléments dont on ne connais pas encore la date, ou d'autres qui n'en ont pas. Dans ce cas là on prend NULL

      SAUF QUE :

      By default, TIMESTAMP columns are NOT NULL, cannot contain NULL values, and assigning NULL assigns the current timestamp.
      
      

      Ah merde, ils l'aiment vraiment le current_timestamp chez MySQL. Bon alors si je mets NULL, ca va me rentrer le current_timestamp et en plus je peux pas mettre 0 comme date repère… Heureusement je peux déclarer NULL comme une valeur possible.

      CREATE TABLE t
      (
        ts1 TIMESTAMP NULL DEFAULT NULL,
        ts2 TIMESTAMP NULL DEFAULT 0,
        ts3 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
      );
      
      

      Bon alors ts2 ne marche pas en transactionnel parce que NO_ZERO_DATE est actif par défaut. Mais avec les deux autres on devrait pouvoir s'en sortir. Cependant on a un peu pleuré quand même pour la mise en place.

      Phénomène amusant : sous MySQL la première colonne définie de type timestamp qui n'a pas de default est considéré comme auto-initialisée / auto-updatée. Ce qui veut dire que si vous mettez un default 0/default 1/default NULL dans cette première colonne, la colonne de type timestamp suivante deviendra auto-updatée automatiquement. On ajoute à cela le fait que MySQL jusqu'à la version 5.6.4 prend les microsecondes, les affiche, peut faire des calculs dessus MAIS NE LES STOCKE PAS ! Il arrondit à la seconde supérieure avant de stocker.

      Après les gens se demandent pourquoi sous MySQL je stocke toutes mes dates au format DECIMAL, et je fais les conversions à la volée.

  • # Les gens c'est rien que des cons!

    Posté par . Évalué à 6.

    Quand je pense à tous ces imbéciles qui ont utilisé pendant des années, utilisent, et prévoir de continuer à utiliser MySQL en prod…
    Tous des cons que j'vous dis moi! Valent pas mieux que les moutons sous Windows.

    Heureusement il n'aura fallu à from_kobb que quelques heures pour pouvoir enfin révéler au reste du monde qu'en fait leurs systèmes avec MySQL marchent sans doute pas bien.

    Moi je vais écrire un journal sur cette bouse immonde qu'est Emacs. Aucune de mes fonctions Vim ne marche dedans!
    En plus, j'ai lu la doc en diagonale, et il s'avère qu'on ne peut pas effacer une ligne en tapant dd.
    Si c'est pas révélateur d'un éditeur de texte de merde!

    • [^] # Re: Les gens c'est rien que des cons!

      Posté par . Évalué à 10.

      Et tu sais que ces cons, ils ont viré les pédales quand je suis passé d'un "vélo" à une "moto". Du coup, je suis obligé de pousser. Ça pèse un âne mort ce truc.

    • [^] # Re: Les gens c'est rien que des cons!

      Posté par . Évalué à 6.

      En fait MySQL (comme Oracle) c'est un choix que l'on ne te reprochera jamais en entreprise. Alors que si tu fait un autre choix tu va devoir justifier se choix au lancement du projet ainsi que chaque fois qu'il y aura un petit accro avec.

      Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

      • [^] # Re: Les gens c'est rien que des cons!

        Posté par . Évalué à 2.

        C'est malheureusement très vrai.
        Et encore, il y a peu, on pouvait même te reprocher mysql vs oracle.
        Mais avec la crise, le "gratuit" a le vent en poupe.
        C'est malheureusement encore vrai pour m$win sur le desktop.

  • # Merci

    Posté par . Évalué à 10.

    Contrairement à beaucoup de commentaires au dessus, merci d'avoir pointé ces petits trucs.

  • # Django !

    Posté par (page perso) . Évalué à 3.

    L'avantage de frameworks comme Django, c'est qu'ils abstraient un grand nombre de ces soucis, et la pluspart du temps ça juste-marche. Perso, je n'ai eu des problèmes que lorsque j'ai voulu utiliser les types spatiaux avec GeoDjango, saptialite et postgis.

    • [^] # Re: Django !

      Posté par . Évalué à 2.

      C'est l'ORM qui fait ça, django en utilise un, mais c'est absolument pas lié aux framework web. Hibernate par exemple peut s'utilise pour n'importe quoi.

      Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

  • # Euh ?

    Posté par . Évalué à 8.

    Quel rapport avec la moto ?

    Tous les nombres premiers sont impairs, sauf un. Tous les nombres premiers sont impairs, sauf deux.

    • [^] # Re: Euh ?

      Posté par (page perso) . Évalué à 1.

      C'est un clin d’œil à l'épisode des Simpsons dans lequel Homer s'étrangle avec un bretzel.

      La gelée de coings est une chose à ne pas avaler de travers.

  • # Re:

    Posté par . Évalué à 4.

    Il est incompréhensible que MySql soit aussi populaire. PostgreSQL est 10 fois meilleur et plus facile à gérer. MySql c'est pour les kékés.

    • [^] # Re:

      Posté par (page perso) . Évalué à 3.

      Mouai… MySQL est par certains aspects bien plus abordable que PostgreSQL. Ce ne veut pas dire que l'un soit meilleur que l'autre mais bon.
      De même, si MySQL se trouvait chez tous les hébergeurs c'est bien qu'il répondait à des problématiques que PostgreSQL faisaient surement moins bien (bien peut avoir beaucoup de sens différents…)

      Après, on peut faire des choses sympa tout de même avec MySQL, genre https://developers.google.com/cloud-sql/

    • [^] # Re:

      Posté par (page perso) . Évalué à 10. Dernière modification le 07/03/12 à 11:52.

      Il est incompréhensible que MySql soit aussi populaire.

      La réponse est simple et historique. Elle s'appelle mysql-3.23.

      • un moteur de base de données simple à administrer sans fioriture
      • gestion des droits facile à comprendre y compris max_user_connections
      • qui scale grave
      • gratuit et opensource

      En 2000 tu n'avais guère le choix.

      J'ai encore des 3.23 en prod avec plus de 5000 bases sur un xeon 4 coeur / 2GO de ram des disques scsi tout simple et aucun problème de perfs. A partir de MySQL5, c'est une autre histoire mais je pense que c'est cette inertie historique qui fait son succès.

      • [^] # Re:

        Posté par (page perso) . Évalué à 7.

        phpmyadmin a certainement été un facteur favorable à la démocratisation de mysql , avec les espaces perso de free (entre autres)

        Envoyé depuis mon Archlinux

        • [^] # Re:

          Posté par . Évalué à 3.

          À noter qu'il existe maintenant phppgadmin. Je n'ai pas encore assez testé pour savoir s'il y a autant de fonctionnalités que dans phpmyadmin.

      • [^] # Re:

        Posté par . Évalué à 2.

        Tout à fait d'accord.

        qui scale grave

        Oui.

        Et c'est pour moi le boom du commerce en ligne qui a amené à délaisser postgresql. On avait plus vraiment besoin de gérer des modèles de base et des requêtes complexes, mais plutôt des modèles simples (client, produit, vente) qui devaient supporter beaucoup de requêtes simples.

        Pour m'être récemment mis à postgresql (je ne connaissait auparavant que mysql), certes c'est un peu moins simple par certains abords, comme l'authentification par exemple, mais on se rends vite compte que c'est beaucoup plus souple et puissant d'avoir un fichier pg_hba.conf qu'une table à l'intérieur même du SGBD.

        Il me semble également que postgre est nettement en avance en terme de fonctionnalités, exemple : la réplication.

        Je comprends bien pourquoi Nerim à choisi de proposer du postgresql plutôt que mysql pour l'hébergement "de base" de bases.

        • [^] # Re:

          Posté par (page perso) . Évalué à 3.

          Pour m'être récemment mis à postgresql

          J'aime beaucoup postgresql (et pas trop mysql mais pour d'autres raisons que celles énoncés ici). Mais force est de constater que si tu laisses le choix, les clients choisissent massivement mysql même si pour l'usage actuel et notamment les requêtes imbitables générées par des ORM, postgresql (à mon humble avis) s'en sort beaucoup mieux (plus lent au démarrage mais plus stable avec l'augmentation du volume de datas).

          • [^] # Re:

            Posté par . Évalué à 3.

            À mon avis, les raisons de cet état de fait sont assez proches des raisons qui font que Windows a 90% de part de marché : c'est ce que les gens connaissent (ou au moins, ils en ont entendu parler), la plupart des applications sont développées pour, c'est fourni en standard par la plupart des hébergeurs, et ça marche suffisamment bien pour qu'ils ne cherchent pas autre chose.

            • [^] # Re:

              Posté par (page perso) . Évalué à 5.

              Je me rappelle, à l'époque du début de php, Perl avait déjà DBI et était multi-base… alors que php était plus que crade avec ses instructions natives mysql ! Mais il y a eu easy-php qui installait PHP+Apache+MySQL en deux click. Voila la raison du succès. Un enrobage qui était super facile à diffuser et installer.

              Bref, beaucoup d'énergie qui aurait pu aller dès le début dans les projets libres Perl et PostgreSQL ;-) Mais bon, la diversité apporte aussi l'émulation inter-équipe.

              • [^] # Re:

                Posté par (page perso) . Évalué à 4. Dernière modification le 12/03/12 à 23:18.

                Je ne sais pas si c'est l'enrobage la raison. J'étais hébergeur de serveur web à l'époque du début de php - qui s'appelait encore PHP/FI. Il y avait plein de scripts cgi en perl, dispos un peu partout, facile à utiliser. Nos clients, des geek, des concepteurs de sites touche-à-tout pour la plupart, ou des SSII bourrées d'ingés débutants, étaient dans l'ensemble capables de s'installer perl + apache sur leur machine, mais la majorité avait peu d'expérience en programmation.
                Dès son apparition, PHP/FI a remporté l'adhésion, car PHP avait deux gros avantages sur Perl:
                1. PHP n'utilisait pas le répertoire cgi;
                2. PHP/FI était un langage jeune, moins puissant et beaucoup plus simple que Perl, beaucoup plus facile à apprendre.

                C'est comme MySQL. La version 3.23 était simple, fiable et stable. Relativement peu gourmande. D'apprentissage facile. Crev, un peu plus haut, l'a bien rappelé.

                C'est vrai que Easy-PHP a eu un rôle, mais plus tard (PHP était déjà dans les usages).

                "La liberté est à l'homme ce que les ailes sont à l'oiseau" Jean-Pierre Rosnay

          • [^] # Re:

            Posté par . Évalué à 1. Dernière modification le 07/03/12 à 17:37.

            plus lent au démarrage

            Ça n'a rien à voir mais puisque tu en parles. Il est tellement lent que mon snort qui l'utilise comme backend n'arrive pas à démarrer au démarrage du système : "Database pas dispo", il démarre seulement à la mano après. J'ai bien essayé de jouer sur les priorités des scripts d'init mais ça ne fonctionne pas. Il semble que malgré les priorités souhaitées il puisse y avoir des différences, c'est ça le "dependancy based boot system" ? Parce que postgresql semble toujours démarrer à la fin. Snort me dit ok dans les messages lors du boot mais il n'est pas démarré et dans le log il se pleint de n'avoir pas pu se connecter au sgbd :/ (Debian squeeze je précise)

            Comment ça c'est pas ici les rapport de bogues ?!

            • [^] # Re:

              Posté par (page perso) . Évalué à 2.

              Quand je disais plus lent au démarrage, je signifiais que postgres semble plus lent que mysql sur un faible volume de données en fait postgres est surtout (c'est mon expérience pas un bench) plus constant dans ses perfs que mysql.

              Pour ton problème de démarrage tu devrais voir ce qui prends du temps en lançant le service à la mano. Ça peut-être un mauvais paramétrage ou le script d'init (si ça existe encore chez debian qui fait un vacuum (je sais que celui de mysql fait un mysqlcheck).

              En dernier recours /etc/rc.local est ton mauvais compagnom

  • # Mauvaise méthode de développement ?

    Posté par (page perso) . Évalué à 1.

    effectivement, à y regarder de plus près une clé étrangère fait référence à une clé primaire inexistante.

    Donc quelque part, ton code est pourri.

    mais encore quelques heures plus tard, je me retrouve avec des données corrompues. [..] MySQL ne retourne pas d'erreur quand on insère une valeur incorrecte dans un champ

    Donc quelque part, ton code est pourri.

    Et ils sont où tes test unitaires et fonctionnels ?

    Parce que tout ça, même si la base de donnée ne te renvoi pas les erreurs ou autre, tes tests unitaires te l'auraient montré, avant même que tu passes en prod.

    Sans parler que, comme il a été indiqué plus haut, tu n'as pas cherché à te renseigner sur l'utilisation de Mysql et ses particularités SQL (qu'ont toutes les bases de données, y compris SQLite, qui a quand même la syntaxe SQL la plus pauvre que je n'ai jamais vu).

    Bref, pour moi, le problème se situe surtout entre la chaise et le clavier.

    Mauvaise méthode de dev, changer méthode de dev.

    PS: je ne cherche pas à défendre MySql, qui, il est vrai, a quelques "particularités" parfois désagréables. Mais il en a d'autres qui facilitent tellement la vie…

    • [^] # Re: Mauvaise méthode de développement ?

      Posté par . Évalué à 10.

      Je trouve un peu gros de rejeter la faute sur le code applicatif quand la base de données accepte sans erreur des données invalides. Je veux bien que ça soit un bug côté application, mais c'est en aucun cas une excuse pour que la base avale sans broncher derrière.

      Garantir l'intégrité des données, c'est quand même un des rôles principaux d'une base de données.

      • [^] # Re: Mauvaise méthode de développement ?

        Posté par (page perso) . Évalué à 1.

        mais c'est en aucun cas une excuse pour que la base avale sans broncher derrière.

        La base a fait ce que l'application et le développeur lui ont indiqué de faire. (mauvais choix du type de stockage etc). Elle a avalé sans broncher parce qu'on lui a dit de ne pas broncher. Dans mysql, ce n'est pas un bug, c'est une fonctionnalité (bah oui, on a besoin parfois qu'il n'y ait pas de contrainte d'intégrité, pour diverses raisons, comme la performance, et donc avec mysql, on peut choisir un moteur de stockage qui ne bronche pas)

        Si il y avait des tests, le problème aurait été détecté immédiatement, que l'origine du problème ait été la base ou le code.

      • [^] # Re: Mauvaise méthode de développement ?

        Posté par . Évalué à 0.

        Les données sont intègres: elles sont là, à dispo, tel qu'elles ont été écrite.
        Elles n'ont juste pas de sens métier.
        Déporter les vérifications de référence sur la base est une possibilité mais en aucun cas obligatoire.
        Donc rtfm et un code pas testé est un code pas produit.

    • [^] # Re: Mauvaise méthode de développement ?

      Posté par . Évalué à 6.

      effectivement, à y regarder de plus près une clé étrangère fait référence à une clé primaire inexistante.

      Donc quelque part, ton code est pourri.

      Ça sert à quoi de pouvoir mettre des contraintes sur une base de donnée s'il faut les revérifier à la main derrière ?

      Tous les nombres premiers sont impairs, sauf un. Tous les nombres premiers sont impairs, sauf deux.

      • [^] # Re: Mauvaise méthode de développement ?

        Posté par (page perso) . Évalué à -5.

        s'il faut les revérifier à la main derrière ?

        Qui a dit de vérifier "à la main". Tests unitaires, fonctionnels, ça te parle ?

        • [^] # Re: Mauvaise méthode de développement ?

          Posté par . Évalué à 4.

          Par "à la main" je voulais dire "en rajoutant du code applicatif pour le vérifier avant de l'insérer." Ce qu'on doit trouver dans le code, c'est ce qu'on fait quand le SGBD nous répond "euh tu fais n'importe quoi mon coco, ta donnée, je ne te l'insère pas". Peut-être qu'entre le moment où tu as commencé à créer ton tuple et celui ou tu le finis, quelqu'un d'autre a supprimé ta clé primaire. Tu peux évidement faire du code qui redemande à la base de donnée si elle existe toujours, mais ça fait, dans la plupart des cas, du code exécuté en plus.

          Par exemple si tu veux commander un billet de train et que le train est supprimé entre le moment où tu as demandé la liste des trains et celui où tu as finalement choisi que tu voulais un siège côté couloir dans celui de 13:37 (au bout de dix minutes), comme la suppression d'un train est un évènement rare, revérifier que le train 42 existe toujours au début de ta transaction est inutile, vu que la base de donnée va de toute façon le faire pour toi. Et tu gères le cas ("la SNCF s'excuse mais finalement il n'y a pas de train") au moment où la base de donnée te le dit.

          Tous les nombres premiers sont impairs, sauf un. Tous les nombres premiers sont impairs, sauf deux.

          • [^] # Re: Mauvaise méthode de développement ?

            Posté par (page perso) . Évalué à -1.

            non mais j'ai bien compris hein. ça fait 15 ans que je fais de la base de donnée.

            Ce que je voulais dire, c'est que tout ce que tu viens de dire, tout ces cas "exceptionnel", ça se test, si possible par des tests automatisés (qui sont donc en dehors du code), pour vérifier justement que ton appli ne se plante pas ou n'insère pas n'importe quoi dans ta base. Faire une confiance aveugle à la base, c'est un peu dangereux. Il suffit par exemple un oubli de mettre la contrainte qu'il faut sur la bonne colonne, pour que ça parte en vrille (ce qui peut arriver lors d'un passage en prod, "oups, j'ai oublié d’exécuter mon script SQL d'upgrade de mon schema en prod", ou "oups, mon script d'upgrade n'était pas complet").

            Et justement pour palier à ce genre d'erreur, ce n'est pas forcément inutile de faire ces vérification "à la main" dans le code comme tu indiques, surtout si ça ne gène pas au niveau des perfs ou autre, ou si ça permet de mieux controller l'execution, donc de fournir une meilleure "experience utilisateur". Parce que bon, traiter des exceptions, ce n'est pas toujours simple quand tu as plusieurs cas possible qui peut arriver au même endroit.

            • [^] # Re: Mauvaise méthode de développement ?

              Posté par . Évalué à 5.

              Effectivement, ou bien "oups j'ai oublié de jouer mes tests en passant de SQLite à MySQL" aussi. Je suis d'accord d'avoir des tests pour tester si tout se passe bien (pour éviter ça), mais je suis quand même réticent à avoir une vérification dans le code + dans la base de données.

              Tous les nombres premiers sont impairs, sauf un. Tous les nombres premiers sont impairs, sauf deux.

            • [^] # Re: Mauvaise méthode de développement ?

              Posté par (page perso) . Évalué à 7.

              non mais j'ai bien compris hein. ça fait 15 ans que je fais de la base de donnée.

              Y'a des fortunes sur DLFP ou faut soumettre un patch ?
              (sans animosité Laurent hein ;)

    • [^] # Re: Mauvaise méthode de développement ?

      Posté par (page perso) . Évalué à 7.

      Donc quelque part, ton code est pourri.

      Ton propos est non seulement hyper agressif mais surtout très déplacé. Comment veux-tu avancer des arguments et dialoguer sereinement après ça ?
      Comme dit précédemment c'est le rôle du moteur de gérer l'existence des clés étrangères et de renvoyer une erreur en cas d'absence.

      • [^] # Re: Mauvaise méthode de développement ?

        Posté par (page perso) . Évalué à 3.

        Et comme dit précédemment ce moteur existe. Mais c'est le rôle du développeur de gérer l'existence de plusieurs moteurs et de choisir le bon suivant les fonctionnalités désirées.

        • [^] # Re: Mauvaise méthode de développement ?

          Posté par (page perso) . Évalué à 5.

          Et le développeur le sait, ce qu'il regrette c'est qu'il n'y rien qui le signal quand on les utilise.

          Un peu embêtant de ne pas avoir eu de message d'erreur à la création des tables mais passons, le fait que les tables MyISAM par défaut ne supportent pas les clés étrangères est connu.

          « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

        • [^] # Re: Mauvaise méthode de développement ?

          Posté par . Évalué à 3.

          Et comme dit précédemment ce moteur existe. Mais c'est le rôle du développeur de gérer l'existence de plusieurs moteurs et de choisir le bon suivant les fonctionnalités désirées.

          Toutes les autres bases de données que j'ai testé proposent des défauts raisonnables pour du développement, je ne vois pas pourquoi MySQL ne serait pas capable de faire de même.

          • [^] # Re: Mauvaise méthode de développement ?

            Posté par . Évalué à 0.

            Toutes les autres bases de données que j'ai testé proposent des défauts raisonnables pour du développement, je ne vois pas pourquoi MySQL ne serait pas capable de faire de même.

            Un exemple ?

            Par ailleurs dans toutes ces bases tu as testé, as-tu utilisé aussi uniquement ton ORM ? Tu lui fais confiance alors que visiblement tu as une méconnaissance de son fonctionnement, c'est suicidaire. Tout se tapage parce que ton machin est pas foutu de gérer les FK en utilisant InnoDB quand le serveur est de type MySQL.

            • [^] # Re: Mauvaise méthode de développement ?

              Posté par . Évalué à 7.

              Un exemple ?

              PostgreSQL.

              Les clés étrangères marchent parfaitement bien sans rien faire de particulier et, si il y a une erreur, on a un joli message "ERROR: current transaction is aborted, commands ignored until end of transaction block" assorti d'une exception dans l'ORM.

              Tout se tapage parce que ton machin est pas foutu de gérer les FK en utilisant InnoDB quand le serveur est de type MySQL.

              Relis mieux le journal, le problème est que MySQL ne créée pas les clés étrangères sans le dire.

        • [^] # Re: Mauvaise méthode de développement ?

          Posté par (page perso) . Évalué à 4.

          c'est le rôle du développeur de gérer l'existence de plusieurs moteurs

          T'en connais beaucoup des SGBD qui gèrent plusieurs moteurs ?

          • [^] # Re: Mauvaise méthode de développement ?

            Posté par . Évalué à 3.

            Ceux qui ont un code de suffisamment bonne qualité pour ne pas pouvoir ajouter toutes les fonctionnalités standards dans un même moteur.

            Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

    • [^] # Re: Mauvaise méthode de développement ?

      Posté par . Évalué à 5.

      Et ils sont où tes test unitaires et fonctionnels ?

      Les tests sont sensé testé le code, pas ta plateforme. Tu n'es pas censé vérifier que les allocations mémoire fonctionnent bien sur ton linux pour chacun de tes projets.

      Personnellement pour moi une base de données avant de parler de performance elle doit me garantir la cohérence des données. Si j'ai besoin de plus de perf après coup je désactive des fonctionnalités de vérification des données mais par défaut de la sécurité avant tout. Ce n'est pas le choix des développeurs de MySQL et c'est le gros point noir pour moi de MySQL.

      Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

  • # Quitte à rester dans le gore

    Posté par (page perso) . Évalué à 5. Dernière modification le 08/03/12 à 14:16.

    MySQL est aussi totalement incapable de gérer les schémas.

    CREATE SCHEMA foo passe sans soucis… mais créé une base de données foo au lieu d'un schéma.
    En effet d'après la doc : CREATE SCHEMA is a synonym for CREATE DATABASE !

    Il est donc impossible d'avoir 2 schémas portant le même nom dans 2 bases de données différentes… Ce qui enlève tout intérêt à leur utilisation !

    • [^] # Re: Quitte à rester dans le gore

      Posté par (page perso) . Évalué à 5.

      Il est donc impossible d'avoir 2 schémas portant le même nom dans 2 bases de données différentes… Ce qui enlève tout intérêt à leur utilisation !

      Ben c'est surtout que si create schema est un synonyme pour create database c'est plutôt, et surtout, que les schémas n'existent simplement pas.
      Donc il n'est simplement pas possible d'avoir des schémas dans une base, donc évidemment pas de schémas dans 2 bases différentes, donc évidemment pas deux schémas portant le même nom dans 2 bases de données différentes.

    • [^] # Re: Quitte à rester dans le gore

      Posté par (page perso) . Évalué à 6.

      On peut aussi rigoler sur les triggers qui existent mais non en fait.

      En fait on peut bien rigoler grâce à MySQL. Surtout de ceux qui le considèrent comme un SGBDR.

    • [^] # Re: Quitte à rester dans le gore

      Posté par . Évalué à 1.

      MySQL est aussi totalement incapable de gérer les schémas.

      CREATE SCHEMA foo passe sans soucis… mais créé une base de données foo au lieu d'un schéma.
      En effet d'après la doc : CREATE SCHEMA is a synonym for CREATE DATABASE !

      Il est donc impossible d'avoir 2 schémas portant le même nom dans 2 bases de données différentes… Ce qui enlève tout intérêt à leur utilisation !

      Oui, et c'est bien normal, puisque une base de données au sens de MySQL n'est rien d'autre qu'un schéma au sens "classique" SQL (il n'y a qu'à regarder "information_schema")… MySQL n'est donc en fait qu'un serveur monobase, où les schémas sont vus par l'utilisateur comme une base de données.

      Mais quand on me dit que MySQL est rapide, je rigole bien fort… Sur des requêtes un temps soit peu compliquées, à données strictement équivalentes, j'ai déjà obtenu un rapport de 70 entre PostgreSQL et MySQL.

      Et il est vrai que MySQL pêche par un certain nombre de lacunes/faiblesses/illogismes :

      • absence de contraintes de vérification
      • absence de séquences indépendantes des tables
      • limitation du nombre de triggers à 6 par table
      • longueur de la liste des contraintes inhérentes à l'utilisation des triggers plus longue que celle des fonctionnalités desdits triggers
      • impossibilité de faire des transactions sur des table MyISAM / impossibilité de faire de la recherche Fulltext sur des tables InnoDB
      • complexité des procédures stockées pour renvoyer un ensemble de résultats
      • aberration dans la souplesse d'utilisation du GROUP BY
      • absence de fonctions basiques mais néanmoins vitales (notamment en terme de fonctionnalité de synchronisation) telles que la gestion des microsecondes
      • impossibilité de désactiver ponctuellement un trigger
      • gestion des types ENUM et SET
      • … j'en oublie probablement

      Je rejoins néanmoins ce qui a été dit plus haut : MySQL est populaire depuis sa version 3.23, et du fait que les hébergeurs n'ont eu cesse de le proposer de manière quasi-exclusive.
      Le problème aujourd'hui, c'est qu'une grande majorité de développeurs web (notamment ceux qui font du PHP) ne connaissent rien d'autre, et ont pris tellement de mauvaises habitudes avec que toute autre base qui ne fait pas comme MySQL est anormale… Et ne parlez surtout pas à ces gens là de transaction, d'intégrité, de cohérence ou d'intégration multi-applicative…

      Bref, si MySQL était plutôt un bon choix il y a quelques années, c'est malheureusement aujourd'hui un choix par défaut non motivé, mais qui convient malheureusement parfaitement au gens qui développent au pied levé et n'ont pas envie de s'ennuyer avec une base de données fortement typée.

      Vive PostgreSQL ;-)

      • [^] # Re: Quitte à rester dans le gore

        Posté par . Évalué à 1.

        J'utilise PostgreSQL depuis 1995 (son nom était alors postgres95) sous Linux. À cette époque, les clés primaires n'étaient pas encore natives…

        Un jour, bien plus tard et quelques versions de PG après, j'ai entendu parlé de MySQL. Certain en ont dit que c'était un vrai SGBDR et d'autres disaient que c'était juste une couche SQL au-dessus de fichiers plats (en référence à MyISAM j'imagine).

        Par chance, j'ai appris le SQL et le modèle entité-relation avant MySQL. Après avoir regardé MySQL de plus près, je me suis fait MON avis et lui prédisait seulement un succès d'estime.

        Mais voilà, j'ai été trop "scientifique" dans ma comparaison. MySQL était fonctionnellement en retrait comparé à PostgreSQL (c'est toujours le cas). Mais c'était sans compter sur un acteur majeur: Windows. En effet je pense que c'est grâce à lui que MySQL a acquis la popularité qu'on lui connait aujourd'hui. Pourquoi ? Pour une raison très simple: MySQL s'installe facilement sous Windows contrairement à PG. Il a fallu attendre la version 8 de PG avant d'avoir un installeur natif. Et encore, certaines limitations intrinsèques de Windows en limitaient PG. Les hébergeurs ont suivi la demande, amplifiant encore le phénomène.

        Windows était (et l'est toujours) une plateforme très populaire. MySQL est monté sur son dos le premier. Il n'a trouvé aucun concurrent dans sa catégorie. De quoi séduire une quantité astronomique de développeurs de tout poil, sans expérience avec un SGBDR digne de ce nom. MySQL s'est alors répandu comme une traîné de poudre en dépit de sa médiocrité, aidé par d'autres vecteurs tels que PHP et l'apparition d’installeurs tout-en-un type WAMP et consorts. Je pense donc qu'il ne faut pas chercher sa popularité dans d’hypothétiques qualités techniques. Mc Donald est aussi très populaire, est-ce pour la qualité gastronomique de ses produits ?

        En conclusion, l'habit fait donc le moine ;-) Moralité, en ces temps électoraux, mieux vaut un bon spin doctor qu'un bon programme pour être populaire et gagner des voix ;-)

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.