贝利信息

mysql数据库的表创建与数据修改操作

日期:2026-01-14 00:00 / 作者:P粉602998670
MySQL建表需显式声明主键、字段类型及约束,推荐使用BIGINT UNSIGNED主键、VARCHAR(255)、DATETIME、utf8mb4_unicode_ci;UPDATE必须带WHERE;ALTER大表慎用;优先选INSERT...ON DUPLICATE KEY UPDATE而非REPLACE INTO。

CREATE TABLE 语句必须显式声明主键和字段类型

MySQL 8.0+ 默认启用 STRICT_TRANS_TABLES 模式,不写主键、用 INT 不写长度、漏掉 NOT NULL 约束都可能让建表失败或埋下隐患。尤其注意:没有显式定义主键时,InnoDB 会悄悄创建隐藏的 ROW_ID,但无法被 SQL 引用,也不支持外键关联。

CREATE TABLE users (
  id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(255) UNIQUE NOT NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

UPDATE 必须带 WHERE 条件,否则整表覆写

这是线上事故最高发操作之一。UPDATE users SET status = 'inactive' 这种语句没加 WHERE,会把全表所有记录状态改成 inactive,且无法靠 binlog 直接回滚(因为 binlog 是语句级或行级,但恢复需人工判断)。

ALTER TABLE 修改字段要警惕锁表与复制延迟

MySQL 5.6+ 对部分 ALTER TABLE 操作支持 ALGORITHM=INPLACE,但不是所有修改都免锁。比如给大表(千万级以上)加 NOT NULL 约束、改字段类型(VARCHAR(100) → VARCHAR(500))、加唯一索引,仍会触发表拷贝,阻塞写入数分钟甚至小时。

INSERT ON DUPLICATE KEY UPDATE 和 REPLACE INTO 的行为差异

两者都能处理重复键冲突,但机制完全不同:REPLACE INTO 是「删 + 插」,会触发 DELETEINSERT 两个事件,自增 ID 会跳号,外键关联记录可能被级联删除;而 INSERT ... ON DUPLICATE

KEY UPDATE 是原地更新,更安全可控。

INSERT INTO users (id, name, email) 
VALUES (123, 'Alice', 'alice@example.com') 
ON DUPLICATE KEY UPDATE 
  name = VALUES(name), 
  email = VALUES(email), 
  updated_at = NOW();

实际操作中,最易被忽略的是字符集与排序规则的隐式继承——新建表时若没指定 COLLATE,会沿用数据库默认值,而不同 collation(如 utf8mb4_general_ci vs utf8mb4_unicode_ci)会导致 ORDER BY 结果不一致、唯一索引判定偏差。建表语句里那行 COLLATE=utf8mb4_unicode_ci 不是装饰,是必要声明。