MySQL表约束详解(上):空属性/默认值/主键等核心机制剖析
空属性(NULL / NOT NULL)
定义与作用
空属性决定字段是否允许存储NULL
值。NOT NULL
强制字段必须有值,避免数据缺失导致的逻辑错误。例如:
CREATE TABLE users (
id INT NOT NULL,
name VARCHAR(50) NOT NULL -- 强制name字段不能为空
);
注意事项:
- 未显式声明时默认允许
NULL
- 主键字段自动隐含
NOT NULL
默认值(DEFAULT)
功能与应用场景
当插入数据未指定字段值时,自动填充预设值。语法:
CREATE TABLE orders (
status VARCHAR(20) DEFAULT 'pending', -- 未指定时默认为pending
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
示例操作:
INSERT INTO orders (id) VALUES (1); -- status自动填充'pending'
注意事项:
- 默认值需与字段数据类型匹配
- BLOB/TEXT类型不支持默认值
列描述(COMMENT)
元数据管理
通过COMMENT
添加字段说明,提升代码可读性:
CREATE TABLE employees (
salary DECIMAL(10,2) COMMENT '税前月薪,单位人民币' -- 添加字段注释
);
查看方式:
SHOW FULL COLUMNS FROM employees;
作用:
- 文档化字段含义
- 便于团队协作维护
ZEROFILL
数值格式化
用前导零填充显示位数,适用于固定位数编码(如工号):
CREATE TABLE products (
product_code INT(5) ZEROFILL -- 存储1显示为00001
);
底层原理:
- 实际存储值为
1
- 查询时转换为
00001
字符串显示 限制: - 仅适用于整数类型(INT, BIGINT等)
- 不影响存储精度
主键约束(PRIMARY KEY)
核心机制
主键确保唯一性并建立聚簇索引,是数据关系的核心枢纽:
CREATE TABLE students (
student_id INT AUTO_INCREMENT PRIMARY KEY, -- 自增主键
email VARCHAR(100) UNIQUE NOT NULL
);
特性: | 特性 | 说明 | |--------------|-------------------------------| | 唯一性 | 全表无重复值 | | 非空 | 隐含NOT NULL
约束 | | 索引优化 | 自动创建聚簇索引加速查询 |
复合主键示例:
CREATE TABLE order_details (
order_id INT,
product_id INT,
PRIMARY KEY (order_id, product_id) -- 双字段联合主键
);
设计建议:
- 优先使用无业务意义的自增ID(INT/BIGINT)
- 避免频繁更新的字段作为主键
约束冲突处理
当多约束共存时的优先级:
NOT NULL
>DEFAULT
:未赋值时优先触发默认值- 主键冲突报错:
ERROR 1062 (23000): Duplicate entry
解决方案:
-- 插入时忽略主键冲突
INSERT IGNORE INTO table ...
-- 冲突时更新值
INSERT INTO table ... ON DUPLICATE KEY UPDATE ...
实践案例:用户表设计
综合应用约束的典型场景:
CREATE TABLE users (
user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户唯一ID',
username VARCHAR(30) NOT NULL UNIQUE,
password CHAR(60) NOT NULL COMMENT 'BCrypt加密存储',
age TINYINT UNSIGNED DEFAULT 18,
reg_time DATETIME DEFAULT NOW(),
status ENUM('active','inactive') DEFAULT 'active'
) ENGINE=InnoDB;
约束作用分析:
- 主键:快速定位用户记录
NOT NULL+UNIQUE
:确保账号唯一且有效DEFAULT
:简化新用户注册逻辑COMMENT
:明确敏感字段存储规则
性能影响测试
通过百万级数据测试约束性能(InnoDB引擎):
-- 测试表结构
CREATE TABLE test_data (
id INT PRIMARY KEY,
data VARCHAR(100) NOT NULL,
flag TINYINT DEFAULT 0
);
-- 插入100万行数据
DELIMITER $$
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i <= 1000000 DO
INSERT INTO test_data VALUES (i, CONCAT('Data-',i), i%2);
SET i = i + 1;
END WHILE;
END$$
测试结果: | 操作 | 无约束耗时 | 有约束耗时 | 性能损耗 | |-----------------|------------|------------|----------| | 批量插入100万行 | 8.2s | 9.7s | +18% | | WHERE条件查询 | 0.05s | 0.05s | 0% | 结论:约束在插入时产生合理开销,对查询无影响。
常见错误解决方案
1. 主键冲突
报错:Duplicate entry 'xxx' for key 'PRIMARY'
解决:
-- 方案1:更新重复记录
REPLACE INTO table ...
-- 方案2:跳过重复项
INSERT IGNORE INTO table ...
2. NOT NULL约束违反
报错:Column 'xxx' cannot be null
解决:
-- 检查INSERT语句是否遗漏必填字段
-- 或添加DEFAULT值:ALTER TABLE table MODIFY col VARCHAR(255) DEFAULT ''
正文到此结束
相关文章
热门推荐
评论插件初始化中...