Mysql踩坑记之为什么能不null就不null

本文深入探讨MySQL中字段允许NULL、NOT NULL及NOT NULL DEFAULT ''三种属性的利弊,解析其在实际应用中的影响,尤其强调在唯一索引、字段默认值设定及后期字段添加时的注意事项。

大家都知道,mysql的字段有个属性是是否允许为NULL,我们可以设置为default null 或者not null  或者not null default ‘’ 

下面我列一下这三个表示方法的利弊。

1、default null 

    这种写法,会造成我们根据当前列比较的时候判断当前列是否是null的时候,不用使用常规的=,而是要使用

    

select name from student where name is null;

另外一点是,如果当前列是唯一索引,会允许多个null的值并存,这可能会造成我们的代码上的bug,这点大家一定要注意。

 

2、not null,这要求插入值的时候,当前类不能是null,这本身没有什么问题,但是下面的场景,就会带来大问题,尤其是新手程序员需要注意。

    

create table t1(
id int auto_increment primary key ,
name varchar(30) not null ) ;


-- 场景a 插入sql
insert into t1(name) values('a');


--某个需要,需要增加字段。
alter table t1 add column  address varchar(30) not null;



--如果场景a忘记了修改
insert into t1(name) values('b');
--会报如下错误。
ERROR 1364 (HY000): Field 'address' doesn't have a default value




3、alter table t1 add column  address varchar(30) not null default ‘’ ,这种写法是强烈推荐的 。既可以避免ERROR 1364 (HY000): Field 'address' doesn't have a default value,错误,又可以避免第一个场景下的不便。

<think>嗯,用户现在明确询问在MySQL Workbench中使用ALTER TABLE语句设置外键约束名时的约束条件。用户之前已经了解过图形界面设置方法,现在转向SQL语句层面的技术细节。 从引用材料来看,用户关注的核心是外键约束的完整性实现和技术限制。需要特别注意三个要点:首先是命名规则中的字符限制和唯一性要求,这是用户实际操作时最容易的点;其次是字段兼容性要求,特别是字符集和存储引擎的一致性,这在跨库操作时尤为重要;最后是索引的硬性要求,MySQL会隐式创建索引但仍有显式控制的必要。 用户可能正在调试迁移脚本或处理遗留系统,所以特别强调ALTER TABLE的场景。考虑到用户前一个问题涉及Workbench可视化操作,现在又转向SQL语句,说明ta可能在解决图形界面无法处理的复杂约束问题。需要特别提醒系统保留字和长度限制这两个容易被忽视的细节。 技术细节上要重点说明:约束名长度上限64字符这个硬性限制,字符集对约束名的影响,以及InnoDB的索引强制要求。用户引用中提到的workbench bug[^1]也暗示ta可能遇到过索引创建异常的情况。 准备在回答中结构化呈现三类约束条件:命名规范、字段要求、引擎依赖。对于命名规范要强调唯一性验证的SQL查询方法;字段要求部分需要加入字符集检查的示例语句;索引要求则要区分自动创建和手动处理的同场景。最后补充验证步骤的完整流程,因为用户显然需要确认约束是否生效。 相关问题设计要延续技术深度:约束名修改的原子操作、字符集冲突解决方案、遗留系统迁移的特殊处理,这些都是用户后续可能遇到的延伸问题。尤其字符集问题在跨国业务中很常见,得单独展开。 </think>在 MySQL Workbench 中使用 `ALTER TABLE` 语句设置外键约束名时,需严格遵守以下约束条件: --- ### 一、命名规范约束 1. **唯一性约束** 约束名必须在**数据库内全局唯一**(仅当前表)。以下语句会因重名报错 `Error 3822`: ```sql ALTER TABLE orders ADD CONSTRAINT fk_user -- 若其他表已存在同名约束 FOREIGN KEY (user_id) REFERENCES users(id); ``` **解决方案**:采用 `表名_字段名` 命名规则(如 `fk_orders_user_id`)[^1]。 2. **长度限制** 约束名长度 ≤ 64 字符(受 `information_schema.TABLE_CONSTRAINTS` 表结构限制)。 3. **字符限制** 仅支持字母、数字、下划线(`_`)和美元符号(`$`)。以下法命名将报错: ```sql ADD CONSTRAINT fk-order@user -- 包含法字符"-"和"@" ``` --- ### 二、字段级约束 1. **索引强制要求** **引用字段**(如 `user_id`)**必须已创建索引**。若未索引,MySQL 会**自动创建同名索引**(可能引发索引冗余)[^2]: ```sql SHOW INDEX FROM orders; -- 验证是否生成新索引 ``` 2. **兼容数据类型** 外键字段与关联字段需满足: - 数据类型严格匹配(如 `INT` ≠ `BIGINT`) - 符号属性一致(如 `UNSIGNED` 需两边共存) - 字符集及排序规则相同(常见错误:`utf8mb4 ≠ latin1`) 3. **空约束** 若关联字段是主键或声明为 `NOT NULL`,则外键字段**必须设为 `NOT NULL`**。 --- ### 三、引擎与事务约束 1. **存储引擎限制** 仅 **InnoDB** 引擎支持外键(MyISAM 等引擎无效): ```sql ALTER TABLE orders ENGINE=InnoDB; -- 修改引擎 ``` 2. **事务隔离级别** 在 `READ COMMITTED` 或更低隔离级别下,可能导致外键检查一致(建议使用 `REPEATABLE READ`)。 --- ### 四、语法正确性验证示例 ```sql ALTER TABLE orders ADD CONSTRAINT fk_orders_user_id -- 合规命名 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT; ``` **执行前需验证**: 1. `user_id` 和 `users.id` 数据类型匹配 2. `users.id` 是主键或唯一索引 3. 数据库内无其他名为 `fk_orders_user_id` 的约束 --- ### 五、常见错误解决方案 | **错误码** | **原因** | **解决方案** | |------------|--------------------------|----------------------------------| | Error 1215 | 字段数据类型兼容 | 使用 `SHOW CREATE TABLE` 核对类型 | | Error 1822 | 约束名重复 | 全局唯一命名 | | Error 150 | 关联字段无索引 | 主动创建索引避免自动生成 | > 通过系统表验证约束状态: > ```sql > SELECT CONSTRAINT_NAME > FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS > WHERE TABLE_NAME = 'orders'; > ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值