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


184

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


1
使用したクエリを確認できますか?
Robert

2
VARCHAR列ではなく、TEXT列が本当に必要ですか?TEXT列は、255バイトを超える長さになる可能性があるもの用です。
scy

5
これはコメントであるべきです。また、はい、そうTEXTです。これらの列にデフォルト値を設定することはできません。VARCHARできる。
ペッカ

1
phpmyadminを使用してデータベースを設定している場合、mysql guiツール/ワークベンチを調査することをお勧めします...;)
dmp

1
はい、残念ながら255文字以上必要です。
ラス

回答:


92

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

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

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

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

Linux MySQL v5.0.83-logに最初にデプロイされた、クライアントの1つ用に変更しているWebアプリケーションで同じ問題が発生しています。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'");

3
rootアクセス権があり、phpMyAdminを使用している場合は、メインページに移動し(phpMyAdminロゴをクリック)、[変数]タブに移動してsql_mode変数を見つけ、[編集]をクリックします。
Gavin

1
CentOS 5.8とMySQL v 14.14を使用しています。デフォルト値をTEXTフィールドに設定しようとすると、Distrib 5.1.71が警告ではなくエラーをスローします。すべてのLinuxプラットフォームで機能しているわけではないことに注意してください。
Alex

最近、OS Xはエラーをスローするようです。ドキュメントdev.mysql.com/doc/refman/5.7/en/blob.htmlは、「BLOBとTEXTカラムはDEFAULT値を持つことができない」と述べています。FWIW(理由ではありません)
rogerdpack 2016年

31

mySQLエンジンに関する深い知識がなければ、これはメモリ節約戦略のように聞こえます。私はその理由がドキュメントのこの段落の後ろにあると思います:

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

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


5
-1:市区町村名などのデータをTEXT列に格納すると、同じデータをCHAR列またはVARCHAR列に格納する場合よりも、実際に必要な合計メモリが少なくなります。
David Cary

5
@david私が引用しているマニュアルの章はストレージではなく、検索に関するものです。
Pekka 2012

1
それがどのように異常なメモリ使用量とパフォーマンスのペナルティにつながるかはわかりません。明らかに、ユーザーがデフォルト値を定義すると、データタイプが何であっても(特に一括操作の場合)、パフォーマンスヒットが予想されます。しかし、私が理解している限り、BLOB / TEXTフィールドの場合、このパフォーマンスヒットは他のデータ型に比べて比較的高いと述べていますか?また、BLOB / TEXTが個別のオブジェクトとして内部的に保存されるという事実とどのように関連していますか?これは私には意味がありません。
気まぐれ

27
私見それはメモリ節約戦略ではありません。それはバグか、それを書いた人が気が狂っているかのどちらかです。少なくとも8年間は修正できないため、後者だと思います。他のすべてのデータベースが持つ基本的な機能。
気まぐれ

2
重要ではありませんが、それを使用したい人にとってはオプションであるはずです。
jurchiks

15

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

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

主な質問として:

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

まだ答えはありませんが、簡単な検索を行ったところ、MySQLバグの MySQL開発者からの比較的新しい追加が見つかりました。

[2017年3月17日15:11]StåleDeraas

開発者による投稿:

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

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

それまでの間、コードを記述して、列をnull可能にするか、アプリケーションコードから''それぞれに(デフォルトの)値を明示的に割り当てinsertます...


13

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

TEXT列にデフォルト値を入れたいのは私だけではないようです。この機能は、MySQLの新しいバージョンでサポートされるはずです。

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


nullを許可するTEXTカラムについては、 ""とNULLの間で変更できるはずです。それは可能ではないようです。
phpguru 2017

6

私は通常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');

それだけです。


1
これは、MySQLがなぜ動作するのかという問題には対処しませんが、他の人にも利益をもたらすことができるようにアプローチを共有してくれてありがとう。Stack Overflowへようこそ!
GargantuChet 2012

1
そうですね... STRICTモードをさらに調べて、それが理にかなっているかどうかを確認する必要があります。MySQLはNixのボックスで警告をスローしますが、Windowsのボックスでは失敗するためです。これは、プラットフォームに関係なく、実装に問題がある可能性があることを示しています。MySQLのドキュメントには、「BLOBおよびTEXTカラムにDEFAULT値を含めることはできません。」という注意書きがあります。論理的には、5より前のバージョンの実装は実際にはすべてのプラットフォームで機能していなかったようです。
ダレルグリーンハウス

3

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'

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.