Nous utilisons MySQL dans mon entreprise et nous avons examiné PostgreSQL (qui fonctionne sur un petit système, à titre de test). Ils ont tous deux leurs avantages et leurs inconvénients. Notez que pour les besoins de cette discussion, je fais référence à MySQL 5.0.x avec InnoDB. Bien que la version 5.1 puisse corriger certains de ces problèmes, elle n'est pas encore stable.
MySQL - Les bons points
Le meilleur atout de MySQL est probablement qu'il est si commun. Comme il fait partie de LAMP, tout le monde et son frère le propose en option. Il fonctionne sous Windows, Linux et tout autre système. Il est impossible de frapper un hébergeur sans que MySQL soit disponible. Il y a des tonnes de personnes qui peuvent vous donner des conseils à ce sujet.
Je préfère les outils (en fait, le client en ligne de commande). Il me semble assez convivial. Vous voulez voir les tables d'une base de données ? SHOW TABLES. Vous voulez voir les bases de données ? SHOW DATABASES. Vous voulez voir l'état de votre réplication par rapport au maître ? SHOW SLAVE STATUS. PostgreSQL ressemble un peu à Oracle pour moi. Il n'y a pas de SHOW TABLES, c'est \dt (IIRC). Pour quitter, ce n'est pas QUIT ou EXIT, c'est \q.
La réplication dans MySQL est plutôt agréable. Elle est intégrée (PostgreSQL n'avait pas de réplication intégrée jusqu'à récemment). La dernière fois que nous avons passé beaucoup de temps à chercher (l'année dernière), la réplication PostgreSQL était basée sur des triggers, ce que nous avons trouvé un peu douteux (en théorie). La réplication MySQL a quelques limitations (elle doit utiliser InnoDB, elle est basée sur les déclarations et non sur les données (changements dans la version 5.1, je crois)), mais elle a bien fonctionné pour nous. Il peut faire plusieurs maîtres, plusieurs esclaves, des chaînes. Encore une fois, c'est une quantité connue, puisque MySQL est si commun.
MySQL - Points faibles
MySQL a quelques très grave limitations. Il est très important que vous comprenez ce dans quoi vous vous engagez.
La plus importante, celle qui nous tue, est l'impossibilité d'ajouter ou de supprimer des colonnes ou des index sans verrouiller la table. Nous avons des tables avec des dizaines de millions d'enregistrements. Nous ne pouvons pas les modifier. L'ajout d'une nouvelle colonne ou d'un nouvel index verrouille la table en lecture et en écriture, ce qui est fatal pour nous. Nous ne savons pas combien de temps cela prendrait, mais ce serait des heures, au minimum. Lorsque nous avons dû ajouter une nouvelle colonne l'année dernière, nous l'avons fait en créant une nouvelle table et en faisant toujours une jointure. C'était la seule façon de faire les choses sans retirer le serveur de la production (ou en passant par un grand désordre puisque nous utilisons la réplication).
MySQL peut parfois être très stupide avec les index. Il est important de lancer un DESCRIBE ou un EXPLAIN sur les index pour voir s'ils font quelque chose de sensé. Nous avons parfois dû utiliser FORCE INDEX pour obtenir de bonnes performances. Ceci est aggravé par le fait qu'il ne peut pas utiliser plusieurs index (pour la plupart). Si vous voulez qu'il utilise votre index sur la colonne date et votre index sur la colonne email, vous devez créer un index sur les deux colonnes. Ce problème est censé être corrigé/amélioré dans la version 5.1 (je pense, je n'ai pas testé la version 5.1).
Les sous-requêtes peuvent également poser un gros problème. Une requête peut fonctionner correctement. Une sous-requête peut fonctionner sans problème. Mais lorsque vous arrivez à trois niveaux de requêtes (ou plus), MySQL peut (et le fait généralement) abandonner. Alors, au lieu de faire les choses intelligemment (même si votre sous-requête est aussi simple qu'un "SELECT id FROM table WHERE id = '5'" constant), MySQL commencera à exécuter cette requête pour chaque ligne, tuant les performances. Encore une fois, vous devez utiliser EXPLAIN / DESCRIBE.
Les messages d'erreur de MySQL sont pires, ce qui n'est qu'un détail. Si vous essayez de créer une table avec une clé étrangère et que vous vous trompez, le système affiche simplement une erreur 150. Il ne vous dit pas quel est le problème (généralement des définitions de colonnes non concordantes), mais seulement l'erreur 150. Il faut aller chercher l'erreur pour voir que 150 est un problème de clé étrangère. D'autres messages d'erreur sont beaucoup plus utiles.
Ensuite, il y a le, eh bien, nous l'appellerons le bogue et la bizarrerie. Les performances de MySQL, du moins sous Windows et Linux, explosent avec plus de 4 (voire 8) processeurs. J'ai entendu dire que ce n'était pas un problème sur Solaris (grâce au travail de Sun et aux processeurs Niagara). C'est quelque chose dont vous devez être conscient. Je crois que les index doivent être conservés en mémoire pour InnoDB. Si vous voulez un index géant que vous n'utiliserez qu'une fois par semaine, tant pis. Cela peut avoir changé, ou être corrigé dans la version 5.1, je ne sais pas.
Vous rencontrez aussi des petites choses amusantes. Nous avons rencontré une condition impliquant des sous-requêtes et des jointures dans la version 5.0 qui fait que MySQL ne renvoie aucune donnée. Malgré ce que dit l'explication, ce que montrent les parties de la requête partielle, etc, vous obtenez zéro ligne. Vous modifiez un peu votre code et le bogue n'est pas atteint et vous obtenez vos données. Les TIMESTAMPs n'enregistrent pas les millisecondes, vous devez le faire à la main avec une autre colonne. Nous avons également rencontré une fois une situation où la commande de formatage de date pouvait faire planter MySQL (c'était à l'époque de la 4.0 ou 4.1). Vous devez simplement être conscient que de petites choses bizarres comme celles-ci peuvent survenir. Ai-je mentionné que j'ai entendu dire (par quelqu'un en qui j'ai vraiment confiance et qui a eu une expérience à ce sujet) que les procédures stockées / triggers pouvaient faire planter le serveur MySQL en 5.0 ? C'était plus tôt dans la branche 5.0 et c'est probablement corrigé maintenant... mais vous devez surveiller MySQL de près.
Cela devrait aller de soi, mais si vous optez pour MySQL, utilisez InnoDB. En fonction de votre configuration, ce n'est peut-être pas le moteur par défaut. Changez cela. Tout ce qui est bon sur MySQL est InnoDB. La réplication et les transactions ont toutes deux besoin d'InnoDB, MyISAM ne les a pas. Il existe d'autres moteurs de stockage, mais ils sont beaucoup plus spécialisés.
PostgreSQL - Bon et mauvais
Maintenant, je n'ai pas une tonne d'expérience avec PostgreSQL. Comme je l'ai dit, nous avons commencé à l'expérimenter. Le fait qu'il n'ait pas les limitations de MySQL est un gros avantage. La simple possibilité d'ajouter une colonne sur une grande table sans verrouiller la chose pendant un temps énorme serait formidable pour nous. PostgreSQL peut également utiliser des index multiples, ce qui, là encore, est un atout majeur. Les messages d'erreur que PostgreSQL renvoie peuvent être beaucoup plus informatifs que ceux de MySQL. Parfois, lorsque vous vous trompez dans une requête, au lieu de "ceci est impossible" ou "vous ne pouvez pas faire cela", vous obtenez quelque chose qui ressemble plus à "ceci est impossible à cause de X". Encore une fois, ce n'est que mon impression. En fait, PostgreSQL ressemble plus à un Oracle open source (une base de données adulte) que MySQL (qui ne ressemble pas vraiment à Oracle).
Les outils sont maintenant BEAUCOUP moins conviviaux, mais si vous venez d'un monde Oracle (ou probablement DB2), vous y serez habitué. Bien qu'ils nécessitent des commandes plus cryptiques (voir les outils MySQL, ci-dessus), ils fonctionnent très bien.
Il y a le problème de la réplication. Lorsque nous avons repris PostgreSQL cette année pour jouer avec un nouveau petit système, nous avons découvert qu'ils ont pris l'un des systèmes de réplication autrefois externes et qu'il a été placé dans l'arbre. C'est une très bonne chose, car la situation de la réplication était un gros problème pour nous. Auparavant, il y avait des petits trucs de tiers (basés sur des déclencheurs) avec lesquels on pouvait tenter sa chance, et il y avait des solutions de réplication payantes. Le fait d'avoir une solution intégrée est très appréciable.
Résumé
Mon conseil ? Bien que j'aie moins d'expérience avec ce système, si je devais commencer avec un nouveau système, je pense que j'opterais pour PostgreSQL. J'ai vu assez de bizarreries dans MySQL pour être prêt à l'essayer. Nous n'avons pas eu de problèmes avec lui jusqu'à présent, et je sais que beaucoup de gens l'utilisent. MySQL s'améliore rapidement. Il a gagné la réplication pour un moteur de stockage sur disque, des procédures stockées, un meilleur choix d'index, et il est devenu beaucoup plus strict pour ne pas autoriser des données manifestement mauvaises (comme la date '0000-00-00') ou des données qui violent une clé.
Le changement de fournisseur n'est pas une décision à prendre à la légère. Le simple fait de transférer les données posera un gros problème si vous n'avez pas été très strict en matière de validation dans le passé.
Mais le plus important, c'est d'essayer. Mettez en place un serveur de test et un rapide hack de la base de code pour faire fonctionner votre code. Introduisez quelques données et évaluez-les. Peut-être que ce ne sera pas beaucoup plus rapide que votre configuration actuelle et que cela ne vaudra pas la peine de s'y intéresser.
Pour votre mise à jour
En ce qui concerne la petite mise à jour que vous avez publiée, j'ai deux commentaires à faire. Pour les BLOBs, sont-ils stockés en dehors de la table ou en ligne ? Je sais qu'Oracle peut le faire, et je suppose que PostgreSQL aussi, mais je ne me souviens pas de MySQL. Cela pourrait être un avantage considérable.
Quant au stockage des PDF en BLOB dans les colonnes, d'après ce qu'on m'a appris, c'est un peu bizarre et cela pourrait causer votre problème de performance. Je n'ai pas une grande expérience dans ce domaine.
Avez-vous essayé de stocker les PDF dans une ou plusieurs autres tables et de ne stocker que les ID ? C'est-à-dire en les normalisant ? Cela pourrait résoudre vos problèmes de performance.
Ce ne sont que des coups de poignard dans le noir.