建表需设NOT NULL、PRIMARY KEY、UNIQUE等约束,字段类型选VARCHAR而非TEXT,时间用DATETIME,引擎用InnoDB并指定utf8mb4;INSERT须显式写字段名、防SQL注入;SELECT避免SELECT*和无WHERE;UPDATE/DELETE必带WHERE且先验证。

创建数据库和表时要注意哪些字段约束
MySQL 的 CRUD 操作能否稳定运行,很大程度上取决于建表时的约束设计。不加 NOT NULL 可能导致后续 INSERT 失败却不报错(尤其配合严格模式关闭时),而漏掉 PRIMARY KEY 会让 UPDATE 和 DELETE 缺乏安全锚点。
-
id字段建议用INT AUTO_INCREMENT PRIMARY KEY,避免手动维护唯一性 - 字符串字段优先选
VARCHAR(255)而非TEXT,除非真要存长文本;TEXT不能设默认值,也不参与某些索引策略 - 时间字段用
DATETIME或TIMESTAMP,后者会自动随系统时区变化,开发调试阶段容易引发时间错乱 - 建表语句末尾加上
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4,确保支持 emoji 和事务
CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(255) UNIQUE, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT 语句怎么写才不容易出错
新手常在 INSERT 时省略字段名,只写值,一旦表结构变更或字段顺序调整,就会批量插入错列。更隐蔽的问题是:没处理字符串中的单引号,直接拼接 SQL 导致语法错误或 SQL 注入。
- 永远显式写出字段名,例如
INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com') - 插入多条记录时,用单条
INSERT+ 多组括号,比多条语句更高效:INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com'), ('Charlie', 'c@example.com') - 如果用程序拼接(如 Python 的
mysql-connector-python),务必使用参数化查询,别用f-string或%格式化 - 插入失败常见报错:
ERROR 1062 (23000): Duplicate entry 'xxx' for key 'email',说明违反了UNIQUE约束
SELECT 查询要避开哪些典型陷阱
SELECT * 看似方便,但在表字段变多、加了 BLOB 类型列或做 JOIN 时,会显著拖慢响应,还可能让应用层解析出错。更关键的是,不加 WHERE 条件的 UPDATE 或 DELETE 是线上事故高发操作,但很多人先写 SELECT 验证逻辑,却忘了加条件。
宽维企业网站管理系统功能说明宽维系列网站管理系统全面免费,个人和商业应用均免费。宽维企业网站管理系统是基于Php+MySql技术开发的企业电子商务平台,全后台操作,无需学习网页制作等知识。前台智能生成页面,可以方便地在线管理、维护、更新您的企业网站。宽维企业网站管理系统安装简单快捷,5分钟就可以安装完成。1 栏目管理方便灵活:可以发布和管理您需要的任何内容的个性栏目。内置数十个功能发布模型,并可以
- 查单条记录务必加
LIMIT 1,尤其是用于存在性判断(如登录校验) - 模糊搜索用
LIKE '%keyword%'会导致全表扫描,有性能风险;前导通配符(%abc)无法走索引 - 日期范围查询注意时区:若字段是
TIMESTAMP,WHERE created_at > '2024-01-01'实际比较的是 UTC 时间,可能和业务预期不符 - 用
SELECT COUNT(*) FROM users统计总数,别用SELECT COUNT(id)——前者能利用 InnoDB 的行数估算优化,后者必须实际遍历
UPDATE 和 DELETE 必须带 WHERE,且建议先 SELECT 验证
没有 WHERE 的 UPDATE 或 DELETE 在 MySQL 中默认影响全表,哪怕只改一个字段,也可能清空整个用户表。这不是 MySQL 的 bug,而是它按标准 SQL 行为执行的结果。
- 执行前一定先跑一遍等价
SELECT,确认命中的行数和内容符合预期,例如:SELECT * FROM users WHERE status = 'inactive';→ 再执行UPDATE users SET status = 'archived' WHERE status = 'inactive'; - 更新时间戳字段推荐用
NOW()或CURRENT_TIMESTAMP,而不是客户端传入时间字符串,避免时钟不同步问题 - 删除前考虑是否该用软删(加
is_deleted TINYINT(1) DEFAULT 0字段),物理删除不可逆,审计和恢复成本极高 - 如果误删且没备份,
binlog是最后救命稻草,但需提前开启并确认格式为ROW模式
真正卡住人的往往不是语法,而是对约束、时区、索引机制和执行影响范围的理解偏差。哪怕是最简单的 UPDATE,也得先问一句:这个 WHERE 能命中几行?有没有索引支撑?执行期间会不会锁表?









