web-dev-qa-db-ja.com

MySQLでテキスト列にデフォルト値を設定できないのはなぜですか?

テーブルにTEXTカラムを作成し、MySQLでデフォルト値を指定しようとすると、エラーが発生します(少なくともWindowsで)。テキスト列にデフォルト値を含めるべきではない理由がわかりません。 MySQLのドキュメントには説明がありません。私には非論理的なようです(デフォルト値が欲しいので、ややイライラします!)。なぜこれが許可されないのか誰でも知っていますか?

159
Russ

Windows MySQL v5ではエラーがスローされますが、Linuxおよびその他のバージョンでは警告のみが発生します。これを修正する必要があります。 WTF?

MySQL Bugtrackerのバグ#19498としてこれを修正する試みも参照してください。

ブライスネスビット2008年4月4日午後4時36分:
MS Windowsでは「デフォルトなし」ルールはエラーですが、他のプラットフォームでは多くの場合警告です。バグではありませんが、寛大なプラットフォームでコードを記述し、後で厳密なプラットフォームで実行すると、これに引っかかる可能性があります。

個人的には、これをバグと見なしています。 「BLOB/TEXT列にデフォルト値を設定することはできません」を検索すると、Googleで約2,940件の結果が返されます。それらのほとんどは、あるシステムでは機能するが他のシステムでは機能しないDBスクリプトをインストールしようとした場合の非互換性のレポートです。

私は、Linux MySQL v5.0.83-logに元々デプロイされていたクライアントの1つのために変更しているwebappで同じ問題に直面しています。 Windows MySQL v5.1.41を実行しています。最新バージョンのphpMyAdminを使用してデータベースを抽出しようとしても、問題のテキスト列のデフォルトは報告されません。ただし、Windowsで挿入を実行しようとすると(Linux展開で正常に動作します)、ABC列でデフォルトなしのエラーが表示されます。明白なデフォルト(その列の一意の値の選択に基づいて)でテーブルをローカルに再作成し、最終的には非常に便利なBLOB/TEXT列を受け取ることができません値

繰り返しますが、プラットフォーム間で基本的な互換性を維持しないことは容認できず、バグです。


MySQL 5(Windows)で厳格モードを無効にする方法:

  • /my.iniを編集して行を探します

    sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
    
  • で置き換える

    sql_mode='MYSQL40'
    
  • MySQLサービスを再起動します(mysql5であると仮定)

    net stop mysql5
    net start mysql5
    

Root/adminアクセスがある場合は、実行できる場合があります

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

MySQLエンジンについての深い知識がなければ、これはメモリ節約戦略のように思えます。理由は docs のこの段落の背後にあると思います。

各BLOBまたはTEXT値は、個別に割り当てられたオブジェクトによって内部的に表されます。これは、テーブルが開かれるときにストレージが列ごとに1回割り当てられる他のすべてのデータ型とは対照的です。

これらの列タイプを事前に入力すると、メモリ使用量とパフォーマンスが低下するようです。

26
Pekka 웃

トリガーを使用して、デフォルト値と同じ効果を得ることができます

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 ;
14
Tim Child

「TEXT/BLOBカラムでのDEFAULTのサポート」は MySQL Bugtracker(Bug#21532)の機能リクエスト です。

TEXTカラムにデフォルト値を入れたいのは私だけではないようです。この機能はMySQLの新しいバージョンでサポートされるべきだと思います。

MySQLのバージョン5.0では、この機能をサポートしていない(現在の)データベースとサポートしているデータベース間でデータベースをやり取りしようとすると、明らかに非互換性とデータ損失が発生するため、これは修正できません。その機能。

9
David Cary

主な質問として:

なぜこれが許可されないのか誰でも知っていますか?

まだ回答されていないので、クイック検索を行ったところ、MySQL開発者から比較的新しい追加が見つかった MySQL Bugs

[2017年3月17日15:11]ストールデラス

開発者による投稿:

これは確かに有効な機能要求であり、一見すると追加するのは簡単に思えるかもしれません。ただし、TEXT/BLOBS値は、テーブルの読み取り/更新に使用されるレコードバッファに直接保存されません。そのため、デフォルト値を割り当てるのはもう少し複雑です。

これは明確な答えではありませんが、少なくともwhy質問の出発点です。

とりあえず、その周りをコーディングして、列をNULL可能にするか、アプリケーションコードの各insertに(デフォルト'')値を明示的に割り当てます。

6
Marten Koetsier

通常、Linuxでサイトを実行していますが、ローカルのWindowsマシンでも開発しています。私はこの問題に何度も遭遇し、問題が発生したときにテーブルを修正しました。昨日アプリをインストールして誰かを助けましたが、もちろん問題に再び遭遇しました。だから、私はそれが何が起こっているかを理解する時だと決めた-そして、このスレッドを見つけました。サーバーのsql_modeを以前のモード(デフォルト)に変更するというアイデアが本当に好きではないので、簡単な(私が考える)ソリューションを思いつきました。

もちろん、このソリューションでは、Windows上で実行されているMySQLの問題を補うために、開発者がテーブル作成スクリプトをラップする必要があります。ダンプファイルにも同様の概念があります。大きな注意点の1つは、パーティショニングが使用されている場合、これにより問題が発生する可能性があることです。

// 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');

それについてです。

6

Ubuntu 16.04の場合:

MySQL 5.7で厳格モードを無効にする方法:

ファイル/etc/mysql/mysql.conf.d/mysqld.cnfを編集します

以下の行がmysql.cnfに存在する場合

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

次に、それを

sql_mode='MYSQL40'

そうでなければ

Mysqld.cnfに次の行を追加するだけです

sql_mode='MYSQL40'

これで問題は解決しました。

1
ShivBuyya