)
前言很多初学MySQL的小伙伴建表时往往只关注字段名称和数据类型觉得“能存数据就行了”。但真正开始写业务代码时各种问题就冒出来了——用户手机号重复插入、年龄字段出现了负数、查询数据时WHERE条件写得乱七八糟……其实这些问题都可以在表设计阶段通过SQL约束来规避而DQL查询则是你从数据库中高效获取信息的核心能力。本文基于真实教学笔记整理手把手带你掌握✅ 6种SQL约束主键、自增、非空、唯一、默认值、外键✅ DQL条件查询全套语法比较/逻辑/范围/模糊/空值✅ 实战案例代码 避坑指南无论你是准备面试还是夯实基础这篇文章都值得收藏一、SQL约束给数据加上规矩1.1 什么是约束数据类型本身也是一种约束比如INT不能存字符串而SQL约束是在数据类型基础上额外增加的要求。举个例子age INT—— 只能存整数age INT CHECK (age 0)—— 不仅要是整数还必须大于等于01.2 六大约束一览约束类型关键字核心作用主键约束PRIMARY KEY唯一标识每条记录非空且唯一自增约束AUTO_INCREMENT主键自动递增需配合主键使用非空约束NOT NULL列的值不能为空唯一约束UNIQUE列的值不能重复默认值DEFAULT不指定值时使用默认值外键约束FOREIGN KEY维护表与表之间的关联关系1.3 主键约束PRIMARY KEY特点主键值必须唯一主键列不能为NULL每张表只能有一个主键创建主键的三种方式sql-- 方式1建表时直接指定 CREATE TABLE person ( id INT PRIMARY KEY, name VARCHAR(20) ); -- 方式2建表时单独声明 CREATE TABLE person2 ( id INT, name VARCHAR(20), PRIMARY KEY (id) ); -- 方式3联合主键两列组合唯一 CREATE TABLE person3 ( id INT, name VARCHAR(20), PRIMARY KEY (id, name) );验证主键约束sql-- ✅ 正常插入 INSERT INTO person VALUES (1, 张三); -- ❌ 报错主键冲突已有id1 INSERT INTO person VALUES (1, 李四); -- ❌ 报错主键不能为NULL INSERT INTO person VALUES (NULL, 王五); -- ✅ 删除主键慎用 ALTER TABLE person DROP PRIMARY KEY;1.4 自增约束AUTO_INCREMENT每次插入新记录时数据库自动生成递增的ID值。使用规则自增列类型必须是整型INT、BIGINT等自增列必须是某个键一般是主键sqlCREATE TABLE person3 ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20) ); -- 不指定id自动生成1,2,3... INSERT INTO person3 (name) VALUES (张三); INSERT INTO person3 (name) VALUES (李四); -- 也可以显式传NULL同样触发自增 INSERT INTO person3 VALUES (NULL, 王五);DELETE vs TRUNCATE 的区别操作删除数据重置自增序列DELETE FROM 表✅❌ 不重置TRUNCATE TABLE 表✅✅ 重置sql-- 自增序列不会重置 DELETE FROM person3; -- 自增序列会重置为1 TRUNCATE TABLE person3;1.5 非空约束NOT NULL确保列中必须有值不能为NULL。易错点空字符串≠NULL空字符串算有值sqlCREATE TABLE person4 ( id INT NOT NULL, name VARCHAR(20) NOT NULL, city VARCHAR(20) ); -- ✅ 正常插入 INSERT INTO person4 VALUES (1, 张三, 北京); -- ❌ 报错id不能为NULL INSERT INTO person4 VALUES (NULL, 张三, 北京); -- ❌ 报错name不能为NULL INSERT INTO person4 VALUES (2, NULL, 北京); -- ✅ 空字符串可以因为不是NULL INSERT INTO person4 VALUES (2, , 北京);1.6 唯一约束UNIQUE确保列中的值不能重复但可以为NULL且多个NULL不冲突。注意一张表可以有多个UNIQUE 约束一张表只能有一个PRIMARY KEYsqlCREATE TABLE person5 ( id INT, name VARCHAR(20), phone VARCHAR(20) UNIQUE -- 手机号不能重复 ); -- ✅ 正常插入 INSERT INTO person5 VALUES (1, 张三, 13800138000); -- ❌ 报错phone重复 INSERT INTO person5 VALUES (2, 李四, 13800138000); -- ✅ 多个NULL是可以的 INSERT INTO person5 VALUES (3, 王五, NULL); INSERT INTO person5 VALUES (4, 赵六, NULL);1.7 默认值DEFAULT插入数据时如果没有指定该列的值则使用默认值。sqlCREATE TABLE person6 ( id INT PRIMARY KEY, name VARCHAR(20), city VARCHAR(20) DEFAULT 北京 -- 默认北京 ); -- ✅ 指定了city使用南京 INSERT INTO person6 VALUES (1, 张三, 南京); -- ✅ 不指定city使用默认值北京 INSERT INTO person6 (id, name) VALUES (2, 李四); -- ✅ 显式传NULL存NULL不会触发默认值 INSERT INTO person6 (id, name, city) VALUES (3, 王五, NULL);1.8 综合案例学生表设计将以上约束组合使用设计一个完整的学生信息表sqlCREATE DATABASE school_db; USE school_db; CREATE TABLE student ( sid INT PRIMARY KEY AUTO_INCREMENT COMMENT 学号, sname VARCHAR(20) NOT NULL UNIQUE COMMENT 姓名, gender VARCHAR(10) NOT NULL DEFAULT 男 COMMENT 性别, age INT COMMENT 年龄, class VARCHAR(20) NOT NULL COMMENT 班级 ) COMMENT 学生表; -- 插入测试数据 INSERT INTO student (sname, gender, age, class) VALUES (张三, 男, 20, 三班);这个表同时用到了✅ PRIMARY KEY主键✅ AUTO_INCREMENT自增✅ NOT NULL非空✅ UNIQUE唯一✅ DEFAULT默认值二、DQL条件查询精准找到你要的数据2.1 准备工作建表与测试数据sqlCREATE DATABASE IF NOT EXISTS db2 CHARSETutf8; USE db2; -- 商品分类表 CREATE TABLE category ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(24) NOT NULL ); -- 商品表 CREATE TABLE products ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(24) NOT NULL, price DECIMAL(10, 2) NOT NULL, score DECIMAL(5, 2), is_self VARCHAR(8), category_id INT ); -- 插入分类数据 INSERT INTO category VALUES (1, 手机), (2, 电脑), (3, 美妆), (4, 家居); -- 插入商品数据 INSERT INTO products VALUES (1, 华为Mate50, 5499.00, 9.70, 自营, 1), (2, 荣耀80, 2399.00, 9.50, 自营, 1), (3, 荣耀70, 1999.00, 9.30, 非自营, 1), (4, 红米note 11, 999.00, 9.00, 非自营, 1), (5, 联想小新14, 4199.00, 9.20, 自营, 2), (6, 惠普战66, 4499.90, 9.30, 自营, 2), (7, 苹果Air13, 6198.00, 9.10, 非自营, 2), (8, 华为MateBook14, 5599.00, 9.30, 非自营, 2), (9, 兰蔻小黑瓶, 1100.00, 9.60, 自营, 3), (10, 雅诗兰黛粉底液, 920.00, 9.40, 自营, 3), (11, 阿玛尼红管405, 350.00, NULL, 非自营, 3), (12, 迪奥996, 330.00, 9.70, 非自营, 3);2.2 简单查询SELECT基础sql-- 1. 查询全部 SELECT * FROM products; -- 2. 查询指定列 SELECT name, price FROM products; -- 3. 列别名AS可省略 SELECT name AS 商品名称, price 价格 FROM products; -- 4. 表别名 SELECT p.name, p.price FROM products AS p; -- 5. 去重查询 SELECT DISTINCT category_id FROM products;2.3 条件查询WHERE2.3.1 比较运算符运算符含义等于大于小于大于等于小于等于!或不等于sql-- 查询自营商品 SELECT * FROM products WHERE is_self 自营; -- 查询价格低于1000的商品 SELECT * FROM products WHERE price 1000; -- 查询价格大于等于999的商品 SELECT * FROM products WHERE price 999;2.3.2 逻辑运算符运算符含义AND并且两边都成立OR或者至少一边成立NOT取反sql-- 自营 且 价格大于2000 SELECT * FROM products WHERE is_self 自营 AND price 2000; -- 价格不大于2000 SELECT * FROM products WHERE NOT price 2000; -- 等价于 SELECT * FROM products WHERE price 2000; -- 价格高于4000 或 低于1000 SELECT * FROM products WHERE price 4000 OR price 1000;2.3.3 范围查询sql-- BETWEEN ... AND ...闭区间含边界 SELECT * FROM products WHERE price BETWEEN 999 AND 4199; -- IN离散值列表 SELECT * FROM products WHERE price IN (999, 2199, 4199); -- NOT IN SELECT * FROM products WHERE price NOT IN (999, 2199, 4199);2.3.4 模糊查询LIKE通配符含义%匹配任意多个任意字符_匹配任意一个任意字符sql-- 以华为开头 SELECT * FROM products WHERE name LIKE 华为%; -- 以14结尾 且 总共6个字符 SELECT * FROM products WHERE name LIKE %14 AND CHAR_LENGTH(name) 6; -- 包含小字 SELECT * FROM products WHERE name LIKE %小%; -- 以华为开头总共8个字符华为 任意6个字符 SELECT * FROM products WHERE name LIKE 华为______;2.3.5 空值判断IS NULL / IS NOT NULLsql-- ❌ 错误写法NULL不能使用 判断 SELECT * FROM products WHERE score NULL; -- ✅ 正确写法 SELECT * FROM products WHERE score IS NULL; -- 未评分 SELECT * FROM products WHERE score IS NOT NULL; -- 已评分三、知识速查表约束速查约束关键字特点主键PRIMARY KEY唯一 非空每表一个自增AUTO_INCREMENT自动递增必须整型 键非空NOT NULL必须有值唯一UNIQUE不能重复可为NULL默认值DEFAULT不填时使用默认值外键FOREIGN KEY关联其他表主键WHERE条件速查类型运算符/关键字比较!逻辑ANDORNOT连续范围BETWEEN ... AND ...离散范围IN (...)模糊匹配LIKE%多个_单个空值IS NULL/IS NOT NULL四、总结本文系统讲解了MySQL中SQL约束和DQL条件查询两大核心知识点约束是数据质量的保障——在建表阶段就定义好规则能从源头防止脏数据进入数据库。查询是数据价值的体现——只会存不会查数据库就是一座数据坟墓。熟记WHERE条件语法——比较、逻辑、范围、模糊、空值5种条件覆盖了95%以上的查询场景。一句话建议先学约束规范数据再学查询提取价值——这是每个数据库开发者的必修课。如果这篇文章对你有帮助欢迎点赞 收藏⭐ 转发你的支持是我持续创作的动力有疑问欢迎在评论区留言我会第一时间回复