为什么文本列在MySQL中没有默认值?

Rus*_*uss 164 mysql default-value

如果您尝试在表上创建TEXT列,并在MySQL中为其提供默认值,则会出现错误(至少在Windows上).我看不出文本列不应该有默认值的任何原因.MySQL文档没有给出解释.这对我来说似乎不合逻辑(有点令人沮丧,因为我想要一个默认值!).有谁知道为什么不允许这样做?

小智 83

Windows MySQL v5引发错误,但Linux和其他版本仅引发警告.这需要修复. WTF?

另请参阅MySQL Bugtracker中尝试将其修复为错误#19498:

Bryce Nesbitt于2008年4月4日下午4:36:
在MS Windows上,"no DEFAULT"规则是一个错误,而在其他平台上,它通常是一个警告.虽然不是一个bug,但如果你在一个宽松的平台上编写代码,然后在一个严格的平台上运行代码,就有可能被这个问题困住:

就个人而言,我认为这是一个错误.搜索"BLOB/TEXT列不能有默认值"会在Google上返回大约2,940个结果.其中大多数是在尝试安装在一个系统上运行但不在其他系统上运行的数据库脚本时不兼容的报告.

我正在为我的一个客户端修改的webapp上遇到同样的问题,最初部署在Linux MySQL v5.0.83-log上.我正在运行Windows MySQL v5.1.41.即使尝试使用最新版本的phpMyAdmin来提取数据库,它也不会报告相关文本列的默认值.然而,当我尝试在Windows上运行插件(在Linux部署中运行正常)时,我收到ABC列上没有默认值的错误.我尝试使用明显的默认值(基于该列的唯一值的选择)在本地重新创建表,并最终接收到非常有用的BLOB/TEXT列不能具有默认值.

同样,不维护跨平台的基本兼容性是不可接受的,并且是一个错误.


如何在MySQL 5(Windows)中禁用严格模式:

如果您具有root/admin访问权限,则可以执行

mysql_query("SET @@global.sql_mode='MYSQL40'");
Run Code Online (Sandbox Code Playgroud)

  • 如果您具有 root 访问权限并且正在使用 phpMyAdmin,请转到主页(单击 phpMyAdmin 徽标),转到变量选项卡,找到 sql_mode 变量,然后单击编辑。 (5认同)

Pek*_*ica 28

如果没有对mySQL引擎的深入了解,我会说这听起来像是一种节省内存的策略.我认为原因是文档背后的这一段落后的原因:

每个BLOB或TEXT值在内部由单独分配的对象表示.这与所有其他数据类型形成对比,在打开表时,每列分配一次存储.

看起来预先填充这些列类型会导致内存使用和性能损失.

  • 恕我直言,这不是一种节省内存的策略.它要么是一个bug,要么是写它的人是疯了.我认为这是后者,因为他们现在至少8年都无法修复它.每个其他数据库具有的基本功能. (21认同)
  • @david我引用的手册章节不是关于存储,而是检索. (5认同)
  • -1:在TEXT列中存储数据(如城市名称)实际上比在CHAR或VARCHAR列中存储相同数据所需的总内存更少. (4认同)
  • 没关系,对于想要使用它的人来说,它应该仍然是一个选择。 (3认同)

小智 17

MySQL 8.0.13(2018-10-22 发布)中添加了对使用表达式作为默认值的支持,适用于TEXTJSON和。BLOBGEOMETRY

你仍然不能写:

create table foo(bar text default 'baz')
Run Code Online (Sandbox Code Playgroud)

但你现在可以写:

create table foo(bar text default ('baz'))
Run Code Online (Sandbox Code Playgroud)

哪个达到同样的效果。

  • 多谢!找到这个很痛苦 (2认同)

Tim*_*ild 14

您可以使用触发器获得与默认值相同的效果

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 ;
Run Code Online (Sandbox Code Playgroud)


Dav*_*ary 9

"支持TEXT/BLOB列中的DEFAULT"是MySQL Bugtracker中的一个 功能请求(Bug#21532).

我发现我不是唯一一个想在TEXT列中放置默认值的人.我认为在MySQL的更高版本中应支持此功能.

这在MySQL 5.0版本中无法修复,因为如果有人试图在不支持该功能的(当前)数据库与支持该功能的任何数据库之间来回传输数据库,这显然会导致不兼容和数据损失那个功能.


Mar*_*ier 7

作为主要问题:

有人知道为什么不允许这样做吗?

仍然没有答案,我进行了快速搜索,并在MySQL Bugs上从MySQL开发人员那里找到了一个相对较新的功能:

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

开发者发布:

这确实是一个有效的功能请求,乍看之下添加起来似乎微不足道。但是TEXT / BLOBS值并不直接存储在用于读取/更新表的记录缓冲区中。因此,为它们分配默认值会有点复杂。

这不是绝对的答案,至少是为什么问题的起点。

同时,我将围绕它进行编码,或者使该列可为空,或者''insert应用程序代码中的每个显式分配一个(默认)值。


小智 6

我通常在Linux上运行网站,但我也在本地Windows机器上开发.我遇到过这个问题很多次,只是在遇到问题时修复了表格.我昨天安装了一个应用程序,以帮助某人,当然再次遇到问题.所以,我决定是时候弄清楚发生了什么 - 并找到了这个帖子.我真的不喜欢将服务器的sql_mode更改为早期模式(默认情况下)的想法,所以我提出了一个简单的(我认为)解决方案.

这个解决方案当然要求开发人员包装他们的表创建脚本以补偿在Windows上运行的MySQL问题.您将在转储文件中看到类似的概念.一个大的警告是,如果使用分区,这可能/将导致问题.

// 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');
Run Code Online (Sandbox Code Playgroud)

就是这样.