当前位置: 首页 > web >正文

SQL154 插入记录(一)

描述

牛客后台会记录每个用户的试卷作答记录到exam_record表,现在有两个用户的作答记录详情如下:

  • 用户1001在2021年9月1日晚上10点11分12秒开始作答试卷9001,并在50分钟后提交,得了90分;
  • 用户1002在2021年9月4日上午7点1分2秒开始作答试卷9002,并在10分钟后退出了平台。

试卷作答记录表exam_record中,表已建好,其结构如下,请用一条语句将这两条记录插入表中。

FiledTypeNullKeyExtraDefaultComment
idint(11)NOPRIauto_increment(NULL)自增ID
uidint(11)NO(NULL)用户ID
exam_idint(11)NO(NULL)试卷ID
start_timedatetimeNO(NULL)开始时间
submit_timedatetimeYES(NULL)提交时间
scoretinyint(4)YES(NULL)得分

该题最后会通过执行SELECT uid, exam_id, start_time, submit_time, score FROM exam_record;来对比结果

INSERT INTOexam_record (uid, exam_id, start_time, submit_time, score)
VALUES('1001','9001','2021-09-01 22:11:12','2021-09-01 23:01:12','90');
INSERT INTOexam_record (uid, exam_id, start_time)
VALUES('1002','9002','2021-09-04 07:01:02');

SQL INSERT INTO 语句:插入记录的不同方式

INSERT INTO 语句是 SQL 中用于向数据库表中添加新记录(行)的核心命令。根据需要插入的数据完整性、目标列的指定方式以及数据来源,有多种使用方式。

1. 完整插入 (指定所有列)
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
  • 说明: 明确指定要插入数据的所有列名(或大部分关键列),并在 VALUES 子句中提供对应顺序的值。
  • 优点: 清晰、安全、可读性强。即使表结构后续有变动(如新增列),只要新列有默认值或允许 NULL,此语句通常仍能正常执行。
  • 缺点: 需要写出所有列名,代码稍长。
  • 分析: 明确指定了 exam_record 表的 uidexam_idstart_timesubmit_timescore 这5个列,并提供了对应的值。这是一次完整的考试记录插入,包含了开始时间、提交时间和得分。
  • 示例
  • INSERT INTOexam_record (uid, exam_id, start_time, submit_time, score)
    VALUES('1001','9001','2021-09-01 22:11:12','2021-09-01 23:01:12','90');
2. 部分插入 (指定部分列)
INSERT INTO table_name (column1, column2, ...) -- 只列出需要赋值的列
VALUES (value1, value2, ...);
  • 说明: 只指定需要插入数据的部分列名。未指定的列将根据其定义被赋予默认值(如 DEFAULT 约束)、NULL(如果允许),或者如果该列是 AUTO_INCREMENT 主键,会自动生成下一个值。
  • 优点: 灵活,当某些列的值可以由数据库自动生成或可以为空时,无需手动指定。
  • 缺点: 需要清楚了解表结构和各列的约束(如 NOT NULL、默认值等),否则可能因缺少必要值而插入失败。
  • 分析: 只指定了 uidexam_idstart_time 三个列。submit_time 和 score 列未指定。
  • 结果: submit_time 很可能为 NULL(表示考试尚未提交),score 也为 NULL(或0,取决于表设计)。这通常用于记录用户开始考试的事件,最终成绩和提交时间将在考试结束后更新。
  • 示例
  • INSERT INTOexam_record (uid, exam_id, start_time)
    VALUES('1002','9002','2021-09-04 07:01:02');
3. 省略列名列表的插入 (不推荐)

语法:

INSERT INTO table_name
VALUES (value1, value2, value3, ...); -- 值的顺序必须严格匹配表的列顺序
  • 说明: 省略 () 中的列名列表。VALUES 中的值必须严格按照表定义的列顺序提供,且数量必须完全匹配。
  • 优点: 代码最短。
  • 缺点:
    • 极易出错: 一旦表结构改变(如增删列、调整列序),此语句极可能失败或插入到错误的列。
    • 可读性差: 无法直观看出每个值对应哪个列。
    • 灵活性差: 必须为所有列提供值,即使是 NULL 或默认值也需要显式写出来。
  • 结论: 强烈不推荐在生产环境或需要维护的代码中使用此方式。
4. 插入多行记录

语法:

INSERT INTO table_name (column1, column2, ...)
VALUES (value1a, value2a, ...),(value1b, value2b, ...),(value1c, value2c, ...);
  • 说明: 在一个 INSERT 语句中,通过 VALUES 后跟多组用逗号分隔的 (值) 来一次性插入多条记录。
  • 优点: 效率高,比执行多条单行 INSERT 语句更快,尤其是在处理大量数据时,减少了网络往返和事务开销。
  • 注意: 所有行的列名列表必须相同。
  • 示例:
    INSERT INTO exam_record (uid, exam_id, start_time)
    VALUES ('1003', '9001', '2021-09-05 10:00:00'),('1004', '9001', '2021-09-05 10:05:00'),('1005', '9003', '2021-09-06 14:30:00');
5. 从其他表插入数据 (INSERT INTO ... SELECT)

语法:

INSERT INTO table_name (column1, column2, ...)
SELECT column1, column2, ...
FROM source_table
WHERE condition;
  • 说明: 将一个 SELECT 查询的结果集直接插入到目标表中。
  • 优点: 强大且高效,适用于数据迁移、备份、根据条件复制数据等场景。
  • 注意: SELECT 查询返回的列数和数据类型必须与 INSERT INTO 指定的列兼容。
  • 示例 (假设要将已完成的考试记录归档):
    INSERT INTO exam_archive (uid, exam_id, start_time, submit_time, score)
    SELECT uid, exam_id, start_time, submit_time, score
    FROM exam_record
    WHERE submit_time IS NOT NULL AND score IS NOT NULL; -- 假设已提交且有成绩
6. 替换插入 (REPLACE INTO)

语法:

REPLACE INTO table_name [(column1, column2, ...)]
VALUES (value1, value2, ...);
  • 说明: 这是 MySQL 特有的扩展语句。它尝试插入新行,如果新行与现有行在主键或唯一索引上发生冲突,则先删除旧行,再插入新行
  • 核心逻辑: REPLACE INTO = DELETE (冲突行) + INSERT (新行)。
  • 优点:
    • 简化逻辑: 一行代码实现“存在则替换,不存在则插入”。
    • 原子性: 操作通常是原子的。
  • 缺点:
    • 性能开销: “删除+插入”比 UPDATE 开销大。
    • 主键变更: 自增主键会获得新值,可能影响外键引用。
    • 非标准: 仅 MySQL/MariaDB 支持,可移植性差。
  • 示例:
    REPLACE INTO examination_info VALUES(NULL, 9003, "SQL", "hard", 90, "2021-01-01 00:00:00");
    • 分析: 假设 exam_id=9003 是唯一键。
      • 若 exam_id=9003 不存在:直接插入,自增主键获新值。
      • 若 exam_id=9003 已存在:先删除旧记录,再插入新记录,自增主键会变成一个新值

总结与最佳实践

  1. 明确指定列名: 始终使用 INSERT INTO table_name (col1, col2, ...) 的形式,避免省略列名列表。这能确保代码的健壮性和可维护性。
  2. 利用部分插入: 当某些列的值可以由数据库自动处理(如 AUTO_INCREMENTDEFAULTNULL)时,使用部分插入是合理且常见的做法(如你的第二个示例)。
  3. 批量插入: 当需要插入多条记录时,优先考虑使用单条 INSERT 语句插入多行,以提高性能。
  4. 数据来源: 除了直接提供值 (VALUES),也要熟悉 INSERT ... SELECT 这种从查询结果插入数据的强大方式。
  5. 注意数据类型: 确保 VALUES 或 SELECT 中的值与目标列的数据类型兼容。你的示例中使用了单引号包裹字符串和日期时间,这是正确的做法。对于数值类型(如 score),通常不需要引号,但加上引号(如 '90')在多数数据库中也会被隐式转换,不过最好遵循数据类型规范。
http://www.xdnf.cn/news/17034.html

相关文章:

  • VUE工程化
  • 机器学习sklearn:支持向量机svm
  • 【Redis学习路|第一篇】初步认识Redis
  • WebRTC前处理模块技术详解:音频3A处理与视频优化实践
  • 企业自动化交互体系的技术架构与实现:从智能回复到自动评论—仙盟创梦IDE
  • 怎么修改论文格式呢?提供一份论文格式模板
  • 力扣 hot100 Day64
  • C++ 入门基础(3)
  • MySQL半同步复制机制详解:AFTER_SYNC vs AFTER_COMMIT 的优劣与选择
  • 2025年渗透测试面试题总结-2025年HW(护网面试) 76-1(题目+回答)
  • 2025年渗透测试面试题总结-2025年HW(护网面试) 77-1(题目+回答)
  • SEA-RAFT:更简单、更高效、更准确的RAFT架构
  • vulnhub-ELECTRICAL靶场攻略
  • SpringBoot 服务器配置
  • 技术面试知识点详解 - 从电路到编程的全栈面经
  • Python 程序设计讲义(54):Python 的函数——函数概述
  • LVGL代码框架简介
  • 【最新区块链论文录用资讯】CCF A--WWW 2025 23篇
  • 防火墙相关技术内容
  • Tlias案例-登录 退出 打包部署
  • Orange的运维学习日记--25.Linux文件系统基本管理
  • 深入解析 <component :is> 在 Vue3 组合式中的使用与局限
  • 基于Dockerfile 部署一个 Flask 应用
  • Word怎样转换为PDF
  • 【设计模式】 原则
  • CH32V单片机启用 FPU 速度测试
  • Conda和pip的使用记录
  • stm32FLASH RAM 详解说明
  • Vue 3.0 Composition API:重新定义组件逻辑的组织方式
  • 解决mac在安装nvm过程中可能遇到的一些问题