Truncate nowcoder_exam_record;  

「增删改」是数据操作的核心(DML)

一、增(INSERT):插入数据

1. 基础写法(指定字段,推荐)

-- 插入单条记录(指定字段,避免字段顺序变动出错)
INSERT INTO exam_record (uid, exam_id, start_time, submit_time, score)
VALUES (1003, 9003, '2021-09-05 10:00:00', '2021-09-05 10:30:00', 85);
  • 优点:字段顺序和表结构解耦,即使表新增字段,语句仍能执行;
  • 关键:自增主键(如id)可省略,或赋值为NULL,由数据库自动生成。

2. 批量插入(高效,数仓批量同步常用)

-- 一条语句插入多条记录,减少IO开销
INSERT INTO exam_record (uid, exam_id, start_time, submit_time, score)
VALUES 
  (1004, 9003, '2021-09-06 09:00:00', '2021-09-06 09:40:00', 92),
  (1005, 9004, '2021-09-07 14:00:00', NULL, NULL);
  • 场景:数仓贴源层(ODS)批量同步业务数据,比单条插入效率高10倍以上。

3. 特殊写法:REPLACE INTO(替换插入,MySQL专属)

-- 有主键/唯一索引冲突则删旧插新,无冲突则普通插入
REPLACE INTO examination_info (id, exam_id, exam_name, difficulty, duration, create_time)
VALUES (NULL, 9003, 'SQL进阶', 'hard', 120, '2021-01-01 00:00:00');
  • 避坑:数仓中慎用(会删除旧数据,破坏数据可追溯性),优先用INSERT INTO

二、删(DELETE):删除数据

核心是删除表中符合条件的记录,务必加WHERE条件,否则删除全表数据!

1. 基础写法(带WHERE条件,推荐)

-- 删除答题时长<5分钟且分数<60的记录(精准删除)
DELETE FROM exam_record
WHERE TIMESTAMPDIFF(minute, start_time, submit_time) < 5
  AND score < 60;
  • 关键:WHERE条件是核心,需精准筛选(用主键/索引字段筛选,性能更高)。

2. 限制删除行数(避免误删,数仓常用)

-- 只删除前100条符合条件的记录,防止一次性删太多锁表
DELETE FROM exam_record
WHERE score IS NULL  -- 未提交的记录
LIMIT 100;

3. 危险写法(无WHERE条件,禁止!)

-- ❌ 直接删除全表数据,不可恢复(除非有备份) 
DELETE FROM exam_record;
  • 替代方案:数仓中清空表优先用TRUNCATE(更高效,不可回滚):

三、改(UPDATE):更新数据

核心是修改表中符合条件的记录,务必加WHERE条件,否则更新全表数据!

1. 基础写法(单字段更新)

-- 将试卷9003的时长从90分钟改为120分钟
UPDATE examination_info
SET duration = 120
WHERE exam_id = 9003;

2. 多字段更新(批量修改)

-- 同时更新试卷名称和难度
UPDATE examination_info
SET exam_name = 'SQL进阶实战', difficulty = 'medium'
WHERE exam_id = 9003;

3. 带LIMIT的更新(限制更新行数)

-- 只更新前50条未提交记录的score为NULL(兜底防误更)
UPDATE exam_record
SET score = NULL
WHERE submit_time IS NULL
LIMIT 50;

四、数仓开发核心差异(Oracle/MaxCompute/Hive)

数仓核心原则:

MaxCompute/Hive作为数仓引擎,设计为「只读」模式,禁止直接DELETE/UPDATE(会破坏数据分区结构),需修改数据时:

-- MaxCompute/Hive修改数据:覆盖分区(核心写法)
INSERT OVERWRITE TABLE exam_record PARTITION (dt='20210901')
SELECT uid, exam_id, start_time, submit_time, 85  -- 将score改为85
FROM exam_record
WHERE dt='20210901';

五、避坑总览(新手必看)

  1. 增删改都要加WHERE条件(除非明确要操作全表);
  2. 插入/更新时注意数据类型匹配(如datetime字段必须传YYYY-MM-DD HH:MM:SS格式);
  3. 数仓中优先用INSERT OVERWRITE(覆盖)/INSERT INTO(追加),避免DELETE/UPDATE;
  4. 操作前先备份数据(数仓可通过分区备份,如INSERT INTO exam_record_bak PARTITION (dt='20210901') SELECT * FROM exam_record WHERE dt='20210901')。

总结

  1. 「增」用INSERT INTO(指定字段+批量插入),MySQL特殊场景用REPLACE INTO,数仓用INSERT OVERWRITE/INSERT INTO
  2. 「删」用DELETE + WHERE(加LIMIT兜底),数仓禁用DELETE,用覆盖空数据替代;
  3. 「改」用UPDATE + WHERE(加LIMIT兜底),数仓禁用UPDATE,用重刷分区数据替代;
  4. 所有操作务必加WHERE条件,避免误操作全表数据。