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

数据库-数据类型,表的约束和基本查询操作


一、数值类型

1. 整数类型
类型字节有符号范围无符号范围操作注意事项
TINYINT1-128 ~ 1270 ~ 255默认有符号,UNSIGNED定义无符号
SMALLINT2-32768 ~ 327670 ~ 65535无符号需显式声明
INT4-2^31 ~ 2^31-10 ~ 2^32-1推荐优先使用INT
BIGINT8-2^63 ~ 2^63-10 ~ 2^64-1存储超长整数时使用

示例

CREATE TABLE tt2(num TINYINT UNSIGNED);  -- 无符号TINYINT
INSERT INTO tt2 VALUES(255);             -- 有效
INSERT INTO tt2 VALUES(-1);              -- 报错:越界
2. 小数类型
类型特点语法示例精度对比
FLOAT单精度,约7位有效数字FLOAT(M, D)快速计算但精度低
DOUBLE双精度,约15位有效数字DOUBLE(M, D)精度高于FLOAT
DECIMAL精确小数,高精度计算DECIMAL(M, D)精确存储(如金额)

示例

CREATE TABLE tt8 (salary FLOAT(10,8), salary2 DECIMAL(10,8));
INSERT INTO tt8 VALUES(23.12345612, 23.12345612);
SELECT * FROM tt8; 
-- 结果:FLOAT显示23.12345695,DECIMAL显示23.12345612(精度更高)
3. BIT类型
  • 语法BIT(M),M范围1~64,默认1。
  • 显示规则:按ASCII码显示。
  • 适用场景:存储二进制标志(如性别0/1)。

示例

CREATE TABLE tt5(gender BIT(1));  -- 存储0或1
INSERT INTO tt5 VALUES(0), (1);   -- 有效
INSERT INTO tt5 VALUES(2);        -- 报错:越界

二、字符串类型

1. CHAR与VARCHAR对比
类型特点最大长度存储方式适用场景
CHAR定长,固定占用空间255字符预先分配空间身份证、MD5值
VARCHAR变长,按需分配空间65535字节动态分配空间姓名、地址

示例

CREATE TABLE tt10(name VARCHAR(6) CHARSET=utf8);  -- UTF8下最大21844字符
INSERT INTO tt10 VALUES('我爱你,中国');           -- 6个字符(UTF8每个汉字3字节)
2. BLOB与TEXT
  • BLOB:存储二进制数据(如图片、文件)。
  • TEXT:存储大文本,不支持全文索引和默认值。

三、时间日期类型

类型格式范围占用空间特点
DATEYYYY-MM-DD1000-01-01 ~ 9999-12-313字节仅日期
DATETIMEYYYY-MM-DD HH:MM:SS1000-01-01 ~ 9999-12-318字节日期+时间
TIMESTAMPYYYY-MM-DD HH:MM:SS1970-01-01 ~ 2038-01-194字节自动更新为当前时间

示例

CREATE TABLE birthday (t1 DATE, t2 DATETIME, t3 TIMESTAMP);
INSERT INTO birthday(t1,t2) VALUES('2000-01-01', '2023-10-01 12:00:00');
UPDATE birthday SET t1='2005-05-05';  -- t3自动更新为当前时间

四、ENUM与SET类型

1. ENUM(单选)
  • 语法ENUM('选项1', '选项2', ...),存储对应数字(1,2,…)。
  • 示例
    CREATE TABLE votes(gender ENUM('男','女'));
    INSERT INTO votes VALUES('男'), (2);  -- 2对应'女'
    
2. SET(多选)
  • 语法SET('选项1', '选项2', ...),存储对应数字(1,2,4,8,…)。
  • 查询:使用FIND_IN_SET函数。
    CREATE TABLE votes(hobby SET('登山','游泳','篮球'));
    INSERT INTO votes VALUES('登山,游泳');
    SELECT * FROM votes WHERE FIND_IN_SET('登山', hobby);  -- 查询包含"登山"的记录
    

五、关键注意事项

  1. 数值类型选择
    • 优先使用DECIMAL存储精确小数(如金额)。
    • 避免使用UNSIGNED,直接升级类型(如INTBIGINT)更安全。
  2. 字符串类型优化
    • CHAR适合定长数据(如手机号),VARCHAR适合变长数据(如地址)。
  3. 时间类型自动更新
    • TIMESTAMP字段在数据更新时会自动刷新为当前时间。
  4. ENUM/SET查询技巧
    • 避免直接使用数字插入,优先用可读字符串。

一、约束类型概览

约束类型作用关键字特点
空属性约束控制字段是否允许为NULLNOT NULL强制字段必须有值
默认值约束指定字段的默认值DEFAULT插入数据时可选使用默认值
列描述约束为字段添加注释COMMENT仅描述作用,不影响数据
零填充约束数字显示时自动填充前导零ZEROFILL仅影响显示,不改变存储值
主键约束唯一标识表中的记录PRIMARY KEY唯一、非空,一张表只能有一个
自增长约束自动生成递增的整数值AUTO_INCREMENT需与主键/唯一键搭配使用
唯一键约束确保字段值唯一(允许NULL)UNIQUE KEY可多个,NULL不参与唯一性检查
外键约束强制关联主表的主键或唯一键FOREIGN KEY维护表间数据一致性

二、核心约束详解

1. 空属性约束(NOT NULL)
  • 语法
    CREATE TABLE 表名 (字段名 数据类型 NOT NULL);
    
  • 示例
    CREATE TABLE myclass (class_name VARCHAR(20) NOT NULL,class_room VARCHAR(10) NOT NULL
    );
    
  • 操作细节
    • 插入数据时,若未给NOT NULL字段赋值,会报错:
      ERROR 1364 (HY000): Field 'class_room' doesn't have a default value
      

2. 默认值约束(DEFAULT)
  • 语法
    CREATE TABLE 表名 (字段名 数据类型 DEFAULT 默认值);
    
  • 示例
    CREATE TABLE tt10 (name VARCHAR(20) NOT NULL,age TINYINT UNSIGNED DEFAULT 0,sex CHAR(2) DEFAULT '男'
    );
    
  • 操作细节
    • 插入时省略字段,自动填充默认值:
      INSERT INTO tt10(name) VALUES('张三');  -- age=0, sex='男'
      

3. 列描述约束(COMMENT)
  • 语法
    CREATE TABLE 表名 (字段名 数据类型 COMMENT '注释内容');
    
  • 查看注释
    SHOW CREATE TABLE 表名\G
    

4. 零填充约束(ZEROFILL)
  • 语法
    CREATE TABLE 表名 (字段名 INT(显示长度) ZEROFILL);
    
  • 示例
    ALTER TABLE tt3 CHANGE a a INT(5) UNSIGNED ZEROFILL;
    
  • 效果
    • 存储值1 → 显示为00001,实际存储仍为1

5. 主键约束(PRIMARY KEY)
  • 语法
    -- 单字段主键
    CREATE TABLE 表名 (字段名 数据类型 PRIMARY KEY);-- 复合主键
    CREATE TABLE 表名 (字段1 数据类型, 字段2 数据类型, PRIMARY KEY(字段1, 字段2));
    
  • 示例
    CREATE TABLE tt14 (id INT UNSIGNED,course CHAR(10),PRIMARY KEY(id, course)  -- 复合主键
    );
    
  • 操作细节
    • 插入重复主键报错:
      ERROR 1062 (23000): Duplicate entry '1-123' for key 'PRIMARY'
      
    • 删除主键
      ALTER TABLE 表名 DROP PRIMARY KEY;
      

6. 自增长约束(AUTO_INCREMENT)
  • 语法
    CREATE TABLE 表名 (字段名 INT PRIMARY KEY AUTO_INCREMENT);
    
  • 示例
    CREATE TABLE tt21 (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,name VARCHAR(10) NOT NULL DEFAULT ''
    );
    
  • 操作细节
    • 插入时省略自增长字段,自动生成递增值:
      INSERT INTO tt21(name) VALUES('a');  -- id=1
      INSERT INTO tt21(name) VALUES('b');  -- id=2
      
    • 获取最后插入的ID
      SELECT LAST_INSERT_ID();
      

7. 唯一键约束(UNIQUE KEY)
  • 语法
    CREATE TABLE 表名 (字段名 数据类型 UNIQUE KEY);
    
  • 示例
    CREATE TABLE student (id CHAR(10) UNIQUE COMMENT '学号',name VARCHAR(10)
    );
    
  • 操作细节
    • 允许插入多个NULL值,但非NULL值必须唯一:
      INSERT INTO student VALUES(NULL, '张三');  -- 允许
      INSERT INTO student VALUES('001', '李四');  -- 重复则报错
      

8. 外键约束(FOREIGN KEY)
  • 语法
    CREATE TABLE 从表名 (字段名 数据类型,FOREIGN KEY (从表字段) REFERENCES 主表名(主表字段)
    );
    
  • 示例
    -- 主表
    CREATE TABLE myclass (id INT PRIMARY KEY, name VARCHAR(30) NOT NULL);-- 从表
    CREATE TABLE stu (id INT PRIMARY KEY,class_id INT,FOREIGN KEY (class_id) REFERENCES myclass(id)
    );
    
  • 操作细节
    • 插入无效外键值报错:
      ERROR 1452 (23000): Cannot add or update a child row
      
    • 允许外键为NULL
      INSERT INTO stu VALUES(102, NULL);  -- 允许未分配班级
      

三、综合案例解析

场景:设计商店数据库(商品、客户、购买表)
-- 商品表
CREATE TABLE goods (goods_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '商品编号',goods_name VARCHAR(32) NOT NULL COMMENT '商品名称',unitprice INT NOT NULL DEFAULT 0 COMMENT '单价(分)',category VARCHAR(12) COMMENT '分类',provider VARCHAR(64) NOT NULL COMMENT '供应商'
);-- 客户表
CREATE TABLE customer (customer_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '客户编号',name VARCHAR(32) NOT NULL COMMENT '姓名',email VARCHAR(64) UNIQUE KEY COMMENT '邮箱',sex ENUM('男','女') NOT NULL COMMENT '性别',card_id CHAR(18) UNIQUE KEY COMMENT '身份证'
);-- 购买表(外键关联)
CREATE TABLE purchase (order_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '订单号',customer_id INT COMMENT '客户编号',goods_id INT COMMENT '商品编号',nums INT DEFAULT 0 COMMENT '购买数量',FOREIGN KEY (customer_id) REFERENCES customer(customer_id),FOREIGN KEY (goods_id) REFERENCES goods(goods_id)
);

四、关键注意事项

  1. 主键与业务无关:推荐使用自增ID,避免业务调整影响主键。
  2. 外键性能:外键约束可能影响插入/更新性能,高频写入场景需谨慎使用。
  3. 唯一键与NULL:唯一键允许NULL,但多个NULL不视为重复。
  4. 自增长字段:仅支持整数类型,且一张表只能有一个自增长字段。

MySQL基本查询操作


1. Create(增)
  • 语法
    INSERT INTO 表名 [(列名,...)] VALUES (值列表)[, (值列表)...];
    
  • 操作细节
    • 全列插入:值与表结构列顺序一致,可省略列名。
      INSERT INTO students VALUES (100, 10000, '唐三藏', NULL);
      
    • 指定列插入:插入部分列,未指定列使用默认值或NULL。
      INSERT INTO students (id, sn, name) VALUES (102, 20001, '曹孟德');
      
    • 冲突处理
      • 更新重复键ON DUPLICATE KEY UPDATE
        INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大师')
        ON DUPLICATE KEY UPDATE sn = 10010, name = '唐大师';
        
      • 替换重复键REPLACE(删除旧记录后插入新记录)。
        REPLACE INTO students (sn, name) VALUES (20001, '曹阿晴');
        

2. Retrieve(查)
  • 语法
    SELECT [DISTINCT] 列名 FROM 表名 [WHERE ...] [ORDER BY ...] [LIMIT ...];
    
  • 操作细节
    • 基础查询

      • 全列查询(不推荐):SELECT * FROM exam_result;
      • 指定列查询:SELECT id, name FROM exam_result;
      • 表达式查询:SELECT name, math + 10 AS math_plus FROM exam_result;
      • 别名:SELECT name, chinese + math + english 总分 FROM exam_result;
      • 去重:SELECT DISTINCT math FROM exam_result;
    • 条件过滤(WHERE)

      • 比较运算符:>, =, <=>, BETWEEN, IN, LIKE%匹配任意字符,_匹配单个字符)。
      • 逻辑运算符:AND, OR, NOT
      • 案例:
        -- 英语不及格
        SELECT name, english FROM exam_result WHERE english < 60;
        -- 姓孙的同学
        SELECT name FROM exam_result WHERE name LIKE '孙%';
        -- 总分 < 200(WHERE中不能使用别名)
        SELECT name, chinese + math + english 总分 FROM exam_result WHERE chinese + math + english < 200;
        
    • 排序(ORDER BY)

      • 默认升序(ASC),降序用DESC。
      • 多字段排序:按书写顺序优先级。
        SELECT name, math, english FROM exam_result ORDER BY math DESC, english;
        
    • 分页(LIMIT)

      • 语法:LIMIT n OFFSET s(从s开始取n条,s起始为0)。
        -- 第2页(每页3条)
        SELECT * FROM exam_result ORDER BY id LIMIT 3 OFFSET 3;
        

3. Update(改)
  • 语法
    UPDATE 表名 SET 列名=[WHERE ...] [ORDER BY ...] [LIMIT ...];
    
  • 操作细节
    • 单列更新:
      UPDATE exam_result SET math = 80 WHERE name = '孙悟空';
      
    • 多列更新:
      UPDATE exam_result SET math = 60, chinese = 70 WHERE name = '曹孟德';
      
    • 表达式更新:
      -- 总分倒数前三的数学加30分
      UPDATE exam_result SET math = math + 30 ORDER BY chinese + math + english LIMIT 3;
      
    • 慎用全表更新:无WHERE条件时更新全表。

4. Delete(删)
  • 语法
    DELETE FROM 表名 [WHERE ...] [ORDER BY ...] [LIMIT ...];
    
  • 操作细节
    • 删除指定数据:
      DELETE FROM exam_result WHERE name = '孙悟空';
      
    • 清空表
      • DELETE FROM 表名:逐行删除,自增值保留。
      • TRUNCATE 表名:快速清空,重置自增值,不可回滚。

5. 高级操作
  • 聚合函数

    • COUNT, SUM, AVG, MAX, MIN,支持DISTINCT
      -- 统计数学成绩种类数
      SELECT COUNT(DISTINCT math) FROM exam_result;
      -- 计算平均总分
      SELECT AVG(chinese + math + english) 平均总分 FROM exam_result;
      
  • GROUP BY 分组

    • 按部门统计平均工资:
      SELECT deptno, AVG(sal) FROM EMP GROUP BY deptno;
      
    • HAVING过滤分组:
      SELECT deptno, AVG(sal) FROM EMP GROUP BY deptno HAVING AVG(sal) < 2000;
      

6. 注意事项
  • 执行顺序
    FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
  • NULL处理
    • = NULL不安全,需用IS NULL<=>
    • 聚合函数忽略NULL(如COUNT(qq)仅统计非NULL值)。
  • 性能提示
    • 避免全列查询(SELECT *)。
    • 分页时建议用LIMIT防止全表扫描。

7. 实战技巧
  • 去重插入:通过临时表实现原子操作。
    CREATE TABLE no_duplicate_table LIKE duplicate_table;
    INSERT INTO no_duplicate_table SELECT DISTINCT * FROM duplicate_table;
    RENAME TABLE duplicate_table TO old_table, no_duplicate_table TO duplicate_table;
    
  • 分页优化:按主键分页,避免OFFSET过大时性能问题。

相关文章:

  • 探秘 RocketMQ 的 DLedgerServer:MemberState 的技术解析与深度剖析
  • HttpPrinter 是一款功能强大的跨平台 Web 打印解决方案
  • JAVA实战开源项目:纺织品企业财务管理系统 (Vue+SpringBoot) 附源码
  • C++基础代码解释
  • 【iOS】消息流程探索
  • 苍穹外卖12
  • AD 多通道设计---多图纸
  • Python----机器学习(模型评估:准确率、损失函数值、精确度、召回率、F1分数、混淆矩阵、ROC曲线和AUC值、Top-k精度)
  • vue3 - keepAlive缓存组件
  • Python的ArcPy基于Excel表格对大量遥感影像批量重分类
  • 传感器数据处理笔记
  • Spring Boot Jpa封装快速构建Specification、OrderBy、Pageable的查询条件
  • Docker 容器化部署
  • Learning vtkjs之MultiSliceImageMapper
  • 数据分析之药物-基因-代谢物
  • Linux系统编程---进程间管道通信
  • 通讯协议开发实战:从零到一打造企业级通信解决方案
  • Spring AI版本1.0.0-M6和M8效果比较
  • SAM-Decoding_ 后缀自动机助力大模型推理加速!
  • JSON Web Token 默认密钥 身份验证安全性分析 dubbo-admin JWT硬编码身份验证绕过
  • 贵州省黔西市发生载人游船侧翻事故
  • 路遇交通事故镇干部冲进火海救人,已申报见义勇为
  • 中国海警局新闻发言人就日民用飞机侵闯我钓鱼岛领空发表谈话
  • 竞彩湃|德甲保级白热化,都灵主帅直面旧主
  • 乘客被困停滞车厢超4小时,哈尔滨铁路局客服:列车晚点,表示歉意
  • 五一首日出沪高峰,G1503高东收费站上午车速约30公里/小时