205 votes

Pourquoi une colonne de texte ne peut-elle pas avoir une valeur par défaut dans MySQL ?

Si vous essayez de créer une colonne TEXT sur une table, et de lui donner une valeur par défaut dans MySQL, vous obtenez une erreur (sous Windows du moins). Je ne vois aucune raison pour laquelle une colonne de texte ne devrait pas avoir une valeur par défaut. Aucune explication n'est donnée par la documentation de MySQL. Cela me semble illogique (et quelque peu frustrant, car je veux une valeur par défaut !). Quelqu'un sait-il pourquoi cela n'est pas autorisé ?

1 votes

Peut-on voir la requête que vous avez utilisée ?

2 votes

Êtes-vous sûr de vouloir une colonne TEXT et non VARCHAR ? Les colonnes TEXT sont destinées aux éléments dont la longueur peut dépasser 255 octets.

5 votes

Cela devrait être un commentaire. Aussi, oui, il veut dire TEXT - ces colonnes ne peuvent pas avoir de valeur par défaut. VARCHAR peut.

99voto

Ku Logix Points 316

La version Windows de MySQL v5 génère une erreur, mais Linux et les autres versions ne génèrent qu'un avertissement. Ceci doit être corrigé. WTF ?

Voir également une tentative de correction du bogue #19498 dans le MySQL Bugtracker :

Bryce Nesbitt le 4 avril 2008 à 16 h 36 :
Sous MS Windows, la règle "no DEFAULT" est une erreur, alors que sur les autres plateformes, elle est souvent un avertissement. Bien qu'il ne s'agisse pas d'un bogue, il est possible de se faire piéger par cette règle si vous écrivez du code sur une plate-forme indulgente et que vous l'exécutez ensuite sur une plate-forme stricte :

Personnellement, je considère cela comme un bug. La recherche de "BLOB/TEXT column can't have a default value" renvoie environ 2 940 résultats sur Google. La plupart d'entre eux sont des rapports d'incompatibilités en essayant d'installer des scripts de DB qui fonctionnaient sur un système mais pas sur d'autres.

Je rencontre actuellement le même problème sur une application web que je modifie pour l'un de mes clients, déployée à l'origine sur Linux MySQL v5.0.83-log. J'utilise maintenant Windows MySQL v5.1.41. Même en essayant d'utiliser la dernière version de phpMyAdmin pour extraire la base de données, il ne signale pas de défaut pour la colonne de texte en question. Pourtant, lorsque j'essaie d'exécuter une insertion sur Windows (qui fonctionne bien sur le déploiement Linux), je reçois une erreur de pas de défaut sur la colonne ABC. J'essaie de recréer la table localement avec la valeur par défaut évidente (basée sur une sélection de valeurs uniques pour cette colonne) et je reçois le message suivant, très utile La colonne BLOB/TEXT ne peut pas avoir de valeur par défaut. .

Encore une fois, ne pas maintenir une compatibilité de base entre les plateformes est inacceptable et constitue un bug.


Comment désactiver le mode strict dans MySQL 5 (Windows) :

  • Editez /my.ini et recherchez la ligne

    sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
  • Remplacez-la par

    sql_mode='MYSQL40'
  • Redémarrez le service MySQL (en supposant que c'est mysql5)

    net stop mysql5
    net start mysql5

Si vous avez un accès Root/admin, vous pouvez peut-être exécuter

mysql_query("SET @@global.sql_mode='MYSQL40'");

5 votes

Si vous avez un accès Root et que vous utilisez phpMyAdmin, allez sur la page principale (cliquez sur le logo phpMyAdmin), allez sur l'onglet Variables, trouvez la variable sql_mode, et cliquez sur Editer.

1 votes

Je suis sur un CentOS 5.8 et MySQL v 14.14 Distrib 5.1.71 jette une erreur au lieu d'un avertissement lorsque j'essaie de définir une valeur par défaut pour un champ TEXTE. Je tiens à préciser que cela ne fonctionne pas sur toutes les plateformes Linux.

0 votes

OS X semble au moins lancer une erreur ces jours-ci. La documentation dev.mysql.com/doc/refman/5.7/fr/blob.html dire "Les colonnes BLOB et TEXT ne peuvent pas avoir de valeurs par défaut". Pour information (mais pas pour savoir pourquoi)

37voto

Pekka 웃 Points 249607

Sans connaissance approfondie du moteur mySQL, je dirais que cela ressemble à une stratégie d'économie de mémoire. Je suppose que la raison se trouve derrière ce paragraphe de la page d'accueil de docs :

Chaque valeur BLOB ou TEXT est représentée en interne par un objet alloué séparément. Ceci est en contraste avec tous les autres types de données, pour lesquels le stockage est alloué une fois par colonne lorsque la table est ouverte.

Il semble que le pré-remplissage de ces types de colonnes entraînerait une utilisation de la mémoire et des pénalités de performance.

5 votes

-1 : Le stockage de données, telles que les noms de ville, dans une colonne TEXTE nécessite en fait moins de mémoire totale que le stockage des mêmes données dans une colonne CHAR ou VARCHAR.

6 votes

@david le chapitre du manuel que je cite ne concerne pas le stockage, mais la récupération.

1 votes

Je ne vois pas comment cela pourrait entraîner une utilisation anormale de la mémoire et des pénalités de performance. Il est évident que lorsqu'un utilisateur définit une valeur par défaut, il s'attend à un impact sur les performances, quel que soit le type de données (en particulier pour les opérations de masse). Cependant, si je comprends bien, vous dites que pour un champ BLOB/TEXT, cette perte de performance est relativement élevée par rapport à d'autres types de données ? Et comment cela est-il lié au fait que BLOB/TEXT est stocké en interne comme un objet séparé ? Cela n'a aucun sens pour moi.

14voto

David Cary Points 1678

"Prise en charge de DEFAULT dans les colonnes TEXTE/BLOB". est un demande de fonctionnalité dans le Bugtracker MySQL (Bug #21532) .

Je vois que je ne suis pas le seul à vouloir mettre une valeur par défaut dans une colonne TEXTE. Je pense que cette fonctionnalité devrait être prise en charge dans une version ultérieure de MySQL.

Cela ne peut pas être corrigé dans la version 5.0 de MySQL, parce qu'apparemment cela provoquerait une incompatibilité et une perte de données si quelqu'un essayait de transférer une base de données entre les bases de données (actuelles) qui ne supportent pas cette fonctionnalité et les bases de données qui la supportent.

0 votes

Il me semble que vous devriez être en mesure de le modifier entre "" et NULL pour une colonne TEXTE qui autorise null. Cela ne semble pas possible.

14voto

Tim Child Points 1468

Vous pouvez obtenir le même effet qu'une valeur par défaut en utilisant un trigger

create table my_text

(
   abc text
);

delimiter //
create trigger mytext_trigger before insert on my_text
for each row
begin
   if (NEW.abc is null ) then
      set NEW.abc = 'default text';
   end if;
end
//
delimiter ;

6voto

Je fais normalement tourner les sites sous Linux, mais je développe aussi sur une machine Windows locale. J'ai rencontré ce problème à plusieurs reprises et j'ai simplement corrigé les tables lorsque j'ai rencontré les problèmes. Hier, j'ai installé une application pour aider quelqu'un et, bien sûr, j'ai rencontré le problème à nouveau. J'ai donc décidé qu'il était temps de comprendre ce qui se passait - et j'ai trouvé ce fil de discussion. Je n'aime vraiment pas l'idée de changer le sql_mode du serveur pour un mode antérieur (par défaut), alors j'ai trouvé une solution simple (selon moi).

Cette solution nécessiterait bien sûr que les développeurs enveloppent leurs scripts de création de table pour compenser le problème de MySQL fonctionnant sous Windows. Vous verrez des concepts similaires dans les fichiers dump. Un GROS avertissement est que cela pourrait/va causer des problèmes si le partitionnement est utilisé.

// Store the current sql_mode
mysql_query("set @orig_mode = @@global.sql_mode");

// Set sql_mode to one that won't trigger errors...
mysql_query('set @@global.sql_mode = "MYSQL40"');

/**
 * Do table creations here...
 */

// Change it back to original sql_mode
mysql_query('set @@global.sql_mode = @orig_mode');

C'est à peu près tout.

1 votes

Cela ne répond pas à la question de savoir pourquoi MySQL a ce comportement, mais merci de partager votre approche afin que d'autres puissent en bénéficier. Bienvenue sur Stack Overflow !

1 votes

Oui, je sais... Je vais devoir examiner le mode STRICT plus en détail pour voir si cela a un sens - puisque MySQL envoie un avertissement sur les boîtes Nix', mais échoue sur les boîtes Windows. C'est une indication que quelque chose ne va pas dans l'implémentation, quelle que soit la plateforme. Vous remarquerez que dans la documentation de MySQL, il y a cet avis : "Les colonnes BLOB et TEXT ne peuvent pas avoir de valeurs par défaut". Donc, logiquement, il semble que l'implémentation dans les versions antérieures à 5 étaient en fait cassée sur toutes les plateformes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X