MySQL技术笔记-表结构设计与管理的完整指南

目录

一、建表范式

(一)范式等级说明

(二) 2NF 与 3NF 的区别

 二、 表基础管理

(一) 建库

建库语法

库名命名规则

常用命令

修改数据库

(二)建表

建表语法

相关命令

(三)修改表

语法格式

操作命令

(四)复制表

 三、表记录管理

(一)插入表记录

(二)修改表记录

(三)删除表记录

 四、表数据类型

(一)数值类型

(二)日期和时间类型

(三)字符类型

(四)枚举类型

(五)布尔类型

(六)JSON类型

(七)空间类型

(八)自定义类型

(九)支持多种扩展数据类型

 五、表数据批量处理

(一)检索目录

默认目录

操作步骤

(二)数据导入

操作步骤

语法格式

(三)数据导出

语法格式

 六、表头约束

(一)约束介绍

(二)查看约束

(三)基本约束

NOT NULL

DEFAULT

UNIQUE

(四)高级约束

PRIMARY KEY

使用规则

创建主键

删除/添加

复合主键

AUTO_INCREMENT

FOREIGN KEY

使用规则

创建外键

查看外键

删除外键

添加外键


前言

一、建表范式

(一)范式等级说明

范式说明
1NF字段不可再分,每列都是原子值
2NF在满足1NF的基础上,消除部分依赖,非主键字段必须完全依赖于主键
3NF在满足2NF的基础上,消除传递依赖,非主键字段不能依赖于其他非主键字段
BCNF任何非主属性不能对候选键有部分依赖
4NF消除多值依赖
5NF消除连接依赖

实际开发中,满足第三范式(3NF) 即可应对大多数场景。

(二) 2NF 与 3NF 的区别

  • 2NF:如果一张表中包含多种不同实体的属性,必须拆分为多张表

  • 3NF:在已拆分的基础上,确保一张表中只能包含另一张表的主键,不能有其他冗余信息。

 二、 表基础管理

(一) 建库

建库语法

CREATE DATABASE [IF NOT EXISTS] <数据库名>
[[DEFAULT] CHARACTER SET <字符集名>]
[[DEFAULT] COLLATE <校对规则名>];

  • []表示可选项
  • IF NOT EXISTS:假设库不存在,避免建库重名报错。
  • CHARACTER SET:指定表使用的字符集(存储字符串的方式)。
    • MySQL 8.0.26 
      • 默认字符集utf8mb4
      • 特点:支持完整的Unicode字符,包括Emoji 和特殊符号,适合多语言环境,尤其是中文支持
    • MySQL 5.x 
      • 默认字符集:通常为 latin1utf8utf8mb4
      • 问题utf8 编码仅支持最多 3 字节的字符,无法存储 Emoji 或某些特殊汉字
  • COLLATE:指定排序规则

库名命名规则

  • 仅可以使用数字、字母、下划线不能纯数字
  • 区分字母大小写
  • 具有唯一性
  • 不可使用MySQL命令或特殊字符
CREATE DATABASE testdb;
CREATE DATABASE TESTDB;
CREATE DATABASE TESTDB;  -- 报错
CREATE DATABASE IF NOT EXISTS testdb;  -- 正常

常用命令

SHOW DATABASES;  -- 查看库
USE 库名;  -- 进入库
SELECT DATABASE();  -- 查看所在的库
DROP DATABASE IF EXISTS 库名;  -- 删除库

修改数据库

ALTER DATABASE 数据库名{
[DEFAULT] CHARACTER SET <字符集名> |
[DEFAULT] COLLATE <校对规则名>};

(二)建表

建表语法

CREATE TABLE库名.表名(
表头名1 数据类型 [约束],
表头名2 数据类型 [约束],
表头名3 数据类型,…);
  • 表必须存放在库里
  • 示例
CREATE TABLE test.users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    age INT,
    email VARCHAR(100) UNIQUE
);

相关命令

SHOW TABLES;  -- 显示已有的表
DESC 库名.表名;  -- 查看表头
SELECT * FROM 库名.表名;  -- 查看表记录
DROP TABLE 库名.表名;  -- 删除表

(三)修改表

语法格式

ALTER TABLE 库.表 操作命令;

操作命令

  • ADD添加新字段,一起添加多个字段使用,分隔ADD命令(FIRSTAFTER)。
  • MODIFY修改字段类型,也可修改字段的位置
  • CHANGE修改字段名,也可以同时修改字段类型
  • RENAME修改表名
  • DROP删除字段,删除多个字段使用,分隔DROP命令。
  • 示例
    • 添加列:
      ALTER TABLE test.users ADD COLUMN phone VARCHAR(20) AFTER email;
    • 修改列类型:
      ALTER TABLE test.users MODIFY COLUMN age TINYINT;
    • 修改列名和类型:
      ALTER TABLE test.users CHANGE COLUMN name username VARCHAR(60);
    • 删除列:
      ALTER TABLE test.users DROP COLUMN phonenumber;
    • 重命名表:
      ALTER TABLE test.users RENAME TO test.user_info;

(四)复制表

复制表结构及数据

CREATE TABLE 新表名 AS SELECT * FROM 原表名; -- 全部字段
CREATE TABLE 库.表 SELECT 列名 FROM 库.表 [WHERE 条件]; -- 指定字段
CREATE TABLE test.user_copy AS SELECT * FROM test.users;
  • 注意:不会复制原表的索引和主键

仅复制表结构

CREATE TABLE 库.表 LIKE 库.表;
CREATE TABLE test.user_structure LIKE test.users;
  • 注意:会复制原表索引、主键等结构。

 三、表记录管理

(一)插入表记录

不指定列名插入记录必须给所有列赋值

INSERT INTO 库名.表名 VALUES(值列表);  -- 插入1行
INSERT INTO 库名.表名 VALUES(值列表),(值列表)....;  -- 插入多行
  • 注意:值的顺序必须和表中列的顺序一致,且数据类型要匹配。
  • 示例
    INSERT INTO testdb.users VALUES (1, 'Alice', 25, 'alice@example.com');
    INSERT INTO testdb.users (name, age, email) VALUES
    ('Charlie', 28, 'charlie@example.com'),
    ('David', 35, 'david@example.com');

指定列名插入记录仅须给指定列赋值

INSERT INTO 库名.表名(列名列表) VALUES(值列表);  -- 插入1行
INSERT INTO 库名.表名(列名列表) VALUES(值列表),(值列表)....;  -- 插入多行
  • 注意:列和值顺序要一致列名先后顺序不重要;没有赋值的列使用默认值、自增长结果赋值。
  • 示例
    INSERT INTO test.users (name, age, email) VALUES ('Bob', 30, 'bob@example.com');
  • 使用SELECT查询结果赋值
    INSERT INTO 库名.表名(字段列表) (SELECT 字段列表 FROM 库.表 WHERE 条件);
  • 注意:SELECT查询语句的字段个数和顺序必须和INSERT语句字段顺序和个数一致。
  • 示例
    INSERT INTO test.user_backup (name, age, email)
    SELECT name, age, email FROM test.users WHERE age > 30;
  • 使用SET命令赋值
    INSERT INTO 库名.表名 SET 字段=值,字段=值,……;
  • 示例
    INSERT INTO departments SET dept_name = "教研部";
    INSERT INTO employees (name, hire_date) (SELECT name, hire_date FROM employees WHERE employee_id IN (1, 2));

(二)修改表记录

// 批量修改
UPDATE 库名.表名 SET 字段1=值,字段2=值;
// 仅修改与条件匹配的
UPDATE 库名.表名 SET 字段1=值,字段2=值 WHERE 条件;
  • 示例
    UPDATE test.users SET password = "test1";
    UPDATE test.users SET password = "test2" WHERE name = "root";

(三)删除表记录

DELETE FROM库名.表名WHERE条件;  -- 仅删除与条件匹配的行
DELETE FROM库名.表名;  -- 清空表记录
TRUNCATE TABLE库名.表名;  -- 清空表记录

  • 示例
    DELETE FROM test.users WHERE shell IS NULL;
    DELETE FROM test.users;
    TRUNCATE TABLE test.users;

  • TRUNCATE TABLE不支持WHERE条件。
  • 自增长列TRUNCATE后从1开始;DELETE继续编号
  • TRUNCATE不能回滚DELETE可以
  • TRUNCATE效率略高于DELETE

 四、表数据类型

MySQL 8支持以下数据类型:

(一)数值类型

  • 整型TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT
  • 浮点型FLOAT、DOUBLE
  • 定点型DECIMAL(适合金额等精度要求高的场景)。
    • 整型类型仅存储数值的整数部分浮点类型存储有小数点的数
  • 示例
    CREATE TABLE test.finance (
        company_name VARCHAR(100),
        daily_flow DECIMAL(10,2),
        quarterly_flow DECIMAL(15,2)
    );

(二)日期和时间类型

  • DATE、TIME、YEAR、DATETIME、TIMESTAMP
  • 用于存储如生日、注册时间、出生年份、入职日期等。
  • 其中,DATETIMETIMESTAMP可以存储精确到秒级别的时间戳,但它们在存储方式和范围上存在一些差异。
  • 推荐使用DATETIME,避免TIMESTAMP2038年问题。
  • 示例
    CREATE TABLE test.events (
        event_name VARCHAR(100),
        event_date DATETIME
    );

(三)字符类型

  • CHAR、VARCHAR、TEXT、BLOB用来存储如姓名、收货地址、工作单位、家庭地址等。
    • CHARVARCHAR用于存储短字符串,而TEXTBLOB用于存储较长的文本和二进制数据。
    • CHAR类型:不够指定字符个数时在右边用空格补全字符个数超出时无法写入数据
    • VARCHAR类型:按数据实际大小分配存储空间字符个数超出时无法写入数据
    • 示例
      CREATE TABLE testdb.members (
          name VARCHAR(50),
          gender ENUM('male', 'female'),
          hobbies SET('reading', 'sports', 'music')
      );

(四)枚举类型

  • ENUM、SET分别用于枚举集合类型数据的存储。

  • ENUM类型单选,字段值仅能在范围内选择1个值
  • 示例
    CREATE TABLE test.test3 (
        name CHAR(5),
        gender ENUM("boy", "girl")
    );
    
  • SET类型多选,字段值能在范围内选择1个或多个值
  • 示例
    
    CREATE TABLE test.test4 (
        name CHAR(5),
        gender ENUM("boy", "girl"),
        hobbies SET("eat", "game", "music")
    );

(五)布尔类型

  • 包括BOOLBOOLEAN

(六)JSON类型

  • MySQL 8引入了JSON类型,用于存储和处理JSON格式的数据

(七)空间类型

  • 包括GEOMETRYPOINTLINESTRINGPOLYGON等。

(八)自定义类型

  • 通过CREATE TYPE语句创建的自定义类型。

(九)支持多种扩展数据类型

  • 数组、XMLGIS等。

 五、表数据批量处理

(一)检索目录

默认目录

SHOW VARIABLES LIKE "secure_file_priv";

操作步骤

  • 创建目录并修改所有者及组
  • 修改主配置文件并重启服务
    #创建并修改目录属性
    mkdir /myload
    chown mysql:mysql /test
    
    #修改配置文件
    vim /etc/my.cnf.d/mysql-server.cnf
    #配置内容
    [mysqld]
    secure_file_priv = "/test"
    
    #重启服务
    systemctl restart mysqld

(二)数据导入

操作步骤

  • 建表
  • 拷贝文件到检索目录
  • 导入数据

语法格式

LOAD DATA INFILE "/目录名/文件名" INTO TABLE 库名.表名
FIELDS TERMINATED BY "分隔符"
LINES TERMINATED BY "\n";

(三)数据导出

语法格式

SELECT命令 INTO OUTFILE "/目录名/文件名";
SELECT命令 INTO OUTFILE "/目录名/文件名"
FIELDS TERMINATED BY "分隔符"
LINES TERMINATED BY "\n";

 六、表头约束

(一)约束介绍

  • 约束是一种限制,设置在字段上,用来控制字段的赋值
  • 类型
    • NOT NULL非空,用于保证该字段的值不能为空
    • DEFAULT默认值,用于保证该字段有默认值
    • UNIQUE唯一索引,用于保证该字段的值具有唯一性可以为空
    • PRIMARY KEY主键,用于保证该字段的值具有唯一性并且非空
    • FOREIGN KEY外键,用于限制两个表的关系,用于保证该字段的值必须来自于主表的关联列的值,在从表添加外键约束,用于引用主表中某些的值

(二)查看约束

DESC 库.表;

(三)基本约束

NOT NULL

  • 不允许赋空值
    CREATE TABLE test.test6 (
        name CHAR(12) NOT NULL,
        class CHAR(5) NULL
    );
    
    DESC test.test6;

DEFAULT

  • 不给字段赋值时,使用默认值赋值
    CREATE TABLE test.test7 (
        name CHAR(12) NOT NULL,
        class CHAR(5) NULL DEFAULT "TEST"
    );
    
    DESC test.test7;

UNIQUE

  • 字段的值不允许重复
    CREATE TABLE test.test8 (
        name CHAR(12) NOT NULL,
        class CHAR(5) NULL DEFAULT "TEST",
        phonenumber CHAR(11),
        UNIQUE (phonenumber)
    );
    
    DESC test.test8;

(四)高级约束

PRIMARY KEY

使用规则
  • 字段值不允许重复不允许赋NULL值。
  • 一个表中只能有一个PRIMARY KEY字段。
  • 多个字段做主键,称为复合主键,必须一起创建
  • 主键标志为PRI
  • 主键通常与AUTO_INCREMENT连用
  • 通常把表中唯一标识记录的字段设置为主键(如行号字段)。
创建主键
CREATE TABLE test.test9 (
    stu_id INT PRIMARY KEY,
    name CHAR(6) NOT NULL,
    class CHAR(5) NULL,
    phonenumber CHAR(11)
);

DESC test.test9;
删除/添加
ALTER TABLE test.test9 DROP PRIMARY KEY;  -- 删除
ALTER TABLE test.test9 ADD PRIMARY KEY(stu_id);  -- 添加
复合主键
  • 多个字段一起做主键,复合主键的值不允许同时重复
  • 语法格式
    CREATE TABLE 库.表(
    字段列表,
    PRIMARY KEY(字段名列表)
    );
  • 示例
    CREATE TABLE test.test10 (
        cip CHAR(15),
        port INT,
        status ENUM("allow", "deny"),
        PRIMARY KEY (cip, port)
    );
    
    DESC test.test10;

AUTO_INCREMENT

  • 通过字段自加1计算结果赋值
  • 语法格式
    CREATE TABLE库.表(
    字段名 类型 PRIMARY KEY AUTO_INCREMENT,
    字段名 类型,……
    );
  • 示例
    CREATE TABLE test.test11 (
        id INT PRIMARY KEY AUTO_INCREMENT,
        name CHAR(8),
        class CHAR(5),
        age INT
    );
    
    DESC test11;

FOREIGN KEY

  • 插入记录时,字段值在另一个表的字段值范围内选择
使用规则
  • 表存储引擎必须是InnoDB
  • 字段类型要一致
  • 被参照字段必须是索引类型的一种(如PRIMARY KEY)。
创建外键
CREATE TABLE库.表名(
字段列表,
FOREIGN KEY(字段名)
REFERENCES 库.表名(字段名)  # 指定外键
ON UPDATE CASCADE  # 同步更新
ON DELETE CASCADE  # 同步删除
) ENGINE=InnoDB;  # 指定存储引擎
查看外键
SHOW CREATE TABLE库.表 \G
SELECT * FROM information_schema.table_constraints WHERE table_name = '表名';
删除外键
ALTER TABLE 库.表 DROP FOREIGN KEY 外键名;
添加外键
ALTER TABLE 库.表 ADD FOREIGN KEY(字段名) REFERENCES 库.表名(字段名) ON UPDATE CASCADE ON DELETE CASCADE;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值