[华为云在线课程][7天玩转MySQL基础实战营][day03DDL和DML][学习笔记]

举报
John2021 发表于 2022/02/25 23:02:02 2022/02/25
【摘要】 DDL DDL的定义Data Definition Language的缩写。通过DDL语句定义不同的数据段、数据库、表、列、索引等数据库对象的元数据信息。通常由数据库管理员(DBA)使用。主要的语法有CREATE,ALTER,DROP。主要作用的对象有database,table,view,index,column,event,trigger等。create database if not...

DDL

DDL的定义

  • Data Definition Language的缩写。
  • 通过DDL语句定义不同的数据段、数据库、表、列、索引等数据库对象的元数据信息。通常由数据库管理员(DBA)使用。
  • 主要的语法有CREATE,ALTER,DROP。主要作用的对象有database,table,view,index,column,event,trigger等。
create database if not exists library;
use library;
create table authors
(
    first_name   varchar(20) character set utf8mb64,
    last_name    varchar(20) character set utf8mb64,
    gender       varchar(20) character set utf8mb64,
    age          tinyint unsigned default 0,
    address      varchar(512),
    phone_number varchar(20)
)
    engine = innodb
    row_format = dynamic
    character set = utf8mb64;
create table library.books
(
    isbn             varchar(20) not null default "" primary key,
    name             varchar(50) not null default "",
    first_name       varchar(20) character set utf8mb64,
    last_name        varchar(20) character set utf8mb64,
    price            decimal(20, 2)       default 0,
    press            varchar(512),
    publication_date date comment 'publication date',
    stock            int                  default 0
);

DATABASE级DDL

  • 创建
create database if not exists library default character set = utf8;
  • 修改属性
alter database library character set = utf8mb64;
  • 删除
drop database library;
  • 查看
show databases;
show create database library;

DATABASE级DDL注意点

  • 数据库需保证全局唯一

  • 字符集的选择:utf8 VS utf8mb64

    • utf8实际上就是utf8mb3,支持编码最大字符长度为3字节;utf8mb64是4个字节,utf8mb64是utf8的超集,能够存储Emoji表情,生僻的汉字等
    • 字符集选择优先级:表>库>系统
    • MySQL8.0默认字符集为utf8mb64
  • ALTER DATABASE语句影响整个数据库下面的新增表,谨慎操作

  • DROP DATABASE同时会删除库下所有的表,属于高危操作

    • 可以考虑先DROP每个table,最后DROP DATABASE

TABLE级DDL

TABLE级DDL - 原子的DDL

  • 原子的DDL

    • 一个DDL操作要么执行成功,要么执行都不成功
    • 不可能存在元数据和数据文件不一致的状态
  • MySQL5.X不支持原子的DDL

    • 尽量保证DDL执行过程不出现系统崩溃
    • 万一遇到DDL崩溃带来的不一致,需要人工介入,甚至需要重建库
  • MySQL8.0支持原子的DDL

    • 更稳定更安全
    • 推荐使用

TABLE级DDL - 背景

  • 表的类型

    • 普通表/分区表/临时表
  • RDS for MySQL默认使用InnoDB存储引擎

    • 也支持其他社区版提供的引擎,但是不建议使用
  • 注意表名大小写敏感参数lower_case_table_names

  • 对表的操作需要指定数据库和表,否则默认使用当前数据库

    • 显示切换数据库USE library;,访问authors表
    • 或者通过library.authors引用
  • DDL语句也会记录到Binlog中

    • 采用satement格式

TABLE级DDL - CREATE

create table library.authors
(
    first_name   varchar(20) character set utf8mb64,
    last_name    varchar(20) character set utf8mb64,
    gender       enum ('Male','Female'),
    age          tinyint unsigned default 0,
    address      varchar(512),
    phone_number varchar(20)
)
    engine = innodb
    row_format = dynamic
    character set = utf8mb64;
  • 字段:first_name,last_name,gender,age,address,phone_number
  • 数据类型:varchar(20),enum,tinyint,varchar(512)
  • 类型描述:character set utf8mb64,default 0
  • 表属性:engine = innodb,row_format = dynamic,character set = utf8mb64
create table library.books
(
    isbn             varchar(20) not null default "" primary key,
    name             varchar(50) not null default "",
    first_name       varchar(20) character set utf8mb64,
    last_name        varchar(20) character set utf8mb64,
    price            decimal(20, 2)       default 0,
    press            varchar(512),
    publication_date date comment 'publication date',
    stock            int                  default 0
);
  • 字段:isbn,name,first_name,last_name,price,press,published,stock
  • 数据类型:varchar(20),decimal(20,2),date,int
  • 类型描述:character set utf8mb64,default 0,comment ‘publication date’
  • 索引:primary key
  • 创建临时表:create temporapy table

TABLE级DDL - CREATE之表拷贝

  • 克隆表结构
    • CREATE TABLE authors_clone LIKE authors;
    • 只拷贝表定义,不拷贝数据
  • 拷贝表数据
    • CREATE TABLE authors_copy SELECT * FROM authors;
    • 既拷贝表结构,也拷贝数据

TABLE级DDL - ALTER概述

  • 当现有表的结构不满足业务需求时,需要对表结构进行调整

  • 修改前需要重点评估ALTER对现有业务的影响?

    • ALTER语句涉及的表有多大?
    • ALTER语句需要运行多久?
    • 当前的系统负载有多高,能够支持ALTER TABLE?
    • ALTER语句会不会影响DML?
  • ALTER语句通常涉及到表元数据(和表记录)的修改

    • 有的ALTER只修改元数据
    • 有的ALTER也需要修改表数据
    • 影响到修改表的执行复杂度

TABLE级DDL - ALTER不改数据

  • 目前一般有以下ALTER操作是指修改元数据不修改表数据

    • RENAME TABLE(ALTER TABLE…RENAME TO…)
    • SET DEFAULT
    • DROP DEFAULT
    • MODIFY COLUMN
    • CHANGE COLUMN(虚拟列生成算法)
    • Change index option
    • ADD virtual column, DROP virtual column
    • ADD COLUMN(非生成列,8.0)
  • 其他操作,一般都涉及数据的修改

TABLE级DDL - ALTER的算法

  • ALTER TABLE…,ALGORITHM=DEFAULT|COPY|INPLACE|INSTANT;

    • 如果不指定,或者指定DEFAULT,会自动选择最合适的算法
    • 算法优先级INSTANT>INPLACE>COPY
  • 选取算法之前要了解它们的差异

算法 支持版本 是否修改数据 磁盘空间占用 并发DML 执行效率
COPY 5.6+ 建立一张全新的表 大约额外一倍的表空间 不允许
INPLACE 5.6+ 某些操作不改数据,某些操作会要建立全新的表,某些操作只会在原有的表上进行修改 对于要建立新表的操作,大约额外一倍的表空间,对于在原表修改的,新增的数据本身 大多数操作允许,极少部分不允许 如果新建表,中低效率,但一般都好于COPY,如果不新建表,效率中上
INSTANT 8.0 不修改数据 0 允许 最高

TABLE级DDL - ALTER改字段

  • 加字段

    • ALTER TABLE authors ADD COLUMN title VARCHAR(20) ALTER address;
    • 新字段可以指定位置
  • 改字段

    • ALTER TABLE authors CHANGE COLUMN status new_status VARCHAR(20) DEFAULT ‘zzzz’;
    • 很可能开销不大
  • 删字段

    • ALTER TABLE authors DROP COLUMN title, DROP COLUMN new_status;
    • 总是个开销大的操作

TABLE级DDL - ALTER改索引

  • 加索引

    • ALTER TABLE authors ADD INDEX (phone_number);
    • CREATE INDEX phone_number_idx ON authors(phone_number);
  • 删索引

    • ALTER TABLE authors DROP INDEX phone_number;
    • DROP INDEX phone_number_idx ON authors;
  • 需要的考量

    • 索引会加大DML的开销
    • 增加合适的索引加速查询
    • 不用的索引可以删除
    • 添加或修改主键索引的开销会很大
  • 8.0上如何更好的评估索引-INVISIBLE INDEX

    • ALTER TABLE authors ADD INDEX (phone_number) INVISIBLE;
    • ALTER TABLE authors ADD INDEX (phone_number) VISIBLE;

TABLE级DDL - TRUNCATE

  • 语法
    • TRUNCATE TABLE authors;
  • TRUNCATE TABLE被看作是DDL,而不是DML
  • 本质上它删除表,再重建一张表
  • 清空表内所有的行,重置AUTO_INCREMENT
  • 版本间行为差异
    • 5.6/5.7,崩溃之后,操作一般是重做到提交
    • 8.0根据操作是否成功决定是提交还是回滚

TABLE级DDL - DROP

  • 语法

    • DROP TABLE [IF EXISTS] authors;
    • DROP TABLE [IF EXISTS] authors,books;
    • DROP TEMPORARY TABLE …;
  • 'IF EXISTS’能够避免表不存在的报错

  • 谨慎使用删表操作,数据将无法轻易找回

其他常见DDL

其他常见DDL - VIEW

  • 视图(VIEW)是关联查询的虚表

    • 定义会持久化,只和创建时的表快照相关
    • 其查询出来的数据仍在原表中
    • 原表可以是普通表或临时表
  • 比如书籍价格的视图

    • CREATE VIEW books_price_view AS SELECT name,price FROM books;

其他常见DDL - TRIGGER

  • 触发器(Trigger)可以定义某个表上某个事件的关联操作

    • 同一个表上触发器的类型和个数没有限制
    • 可以定义触发器发生的顺序
    • 常用的触发事件包括INSERT/UPDATE/DELETE
  • 比如更新authors后同步更新books表

DROP TRIGGER IF EXISTS auto_update_books_trig;

DELIMITER  $$
CREATE TRIGGER auto_update_books_trig
    AFTER UPDATE
    ON library.authors
    FOR EACH ROW
BEGIN
    IF (Old.first_name <> New.first_name or Old.last_name <> New.last_name) THEN
        UPDATE library.books
        SET first_name=New.first_name,
            last_name=New.last_name
        WHERE first_name = Old.first_name
          AND last_name = Old.last_name;
    END IF;
END $$
DELIMITER ;
SHOW TRIGGERS;

其他常见DDL - PROCEDURE

  • 存储过程(Procedure)支持整合和抽取业务逻辑到一个函数执行

    • 支持参数传入传出
    • 执行使用CALL procedure_name();
  • 比如对一定库存的书籍进行打折

DROP TRIGGER IF EXISTS discount_books_proc;
DELIMITER $$
CREATE PROCEDURE discount_books_proc(IN max_stock INT, IN discount FLOAT)
BEGIN
    UPDATE library.books SET price=price * discount WHERE stock > max_stock;
END $$
DELIMITER ;

其他常见DDL - EVENT

  • 定时器(Event)支持指定任务的定时调度

    • 可以定义定时器发生时间,频率,有效期
    • 可以定义定时器,但是先不让它执行-设置为DISABLE
    • 定时器不支持参数传都,但是可以调用存储过程
    • 可以使用ALTER EVENT来修改定时器的定义
    • 需设置event_scheduler=on;来开启所有生效的定时器
  • 比如每周对库存超过10本的书籍打9折

DROP EVENT IF EXISTS discount_books_weekly_event;
CREATE EVENT discount_books_weekly_event
    ON SCHEDULE
        EVERY 1 WEEK
    ON COMPLETION PRESERVE DISABLE
    DO
    CALL discount_books_proc(10, 0.9);
ALTER EVENT discount_books_weekly_event ON COMPLETION PRESERVE ENABLE;
SHOW EVENTS;

DML

DML的定义

  • A data manipulation language(DML) is a computer programming language used for adding (inserting), deleting, and modifying (updating) data in a database. A DML is often a sublanguage of a broader database language such as SQL, with the DML
    comprising some of the operators in the language. Read-only selecting of data is sometimes distinguished as being part of a separate data query language(DQL), but it is closely related and sometimes also considered a component of a DML;
    some operators may perform both selecting (reading) and writing.
  • DML主要涉及对用户数据的增删改
  • 有些DML语句会涉及到数据的查询加修改
  • MySQL的DML主要包括INSERT/UPDATE/DELETE三类
  • DML语句都要记录binlog,针对每一行的修改

INSERT

TABLE级的DML - INSERT概述

  • INSERT语句插入新的记录到指定表当中

    • INSERT …VALUES/INSERT …SET插入指定的数据
    • INSERT …SELECT插入查询出来的数据
    • INSERT …ON DEPLICATE KEY UPDATE在唯一索引或者主键索引冲突时可以更新原有行
  • 插入数据的限制和转换,基于SQL_MODE不做检查

    • 插入NULL值到NOT NULL字段,数值一般转换成字段的默认值
    • 插入数值型范围之外的值,会截断到最近的范围值
    • 插入比如’10.34a’到数值字段,非数值部分会被截断
    • 插入字符串类型,如果长度超过,会被截断到合理长度

TABLE级的DML - INSERT语句

  • 插入单条记录

    • INSERT INTO authors VALUES(‘John’,‘Smith’,‘Male’,30,‘Room X, Building Y’,‘12345678901’);
  • 插入多条记录

    • INSERT INTO authors VALUES(‘Robert’,‘White’,‘Male’,33,‘Room U,Building I’,‘12345678902’),(‘Linda’,‘White’,‘Female’,36,‘Room P,Building O’,‘12345678903’);
  • 插入查询结果集

    • CREATE TABLE authors_bak LIKE authors;
    • INSERT INTO authors_bak SELECT * FROM authors;
  • 重复主键或唯一键执行更新操作

    • INSERT INTO authors VALUES(‘John’,‘Smith’,‘Male’,30,‘Room X,Building Y’,‘1234’) ON DUPLICATE KEY UPDATE age=age+5;
  • 替换或插入

    • REPLACE INTO…
    • REPLACE INTO authors VALUES(‘Robert’,‘White’,‘Male’,33,‘Room U,Building I’,‘86-1234’),(‘Linda’,‘White’,‘Female’,36,‘Room P,Building I’,'86-2345);

TABLE级的DML - INSERT与AUTO_INCREMENT

  • 对于使用AUTO_INCREMENT自增字段作为主键索引的表,它和DML的交互需要仔细考虑

  • AUTO_INCREMENT自动递增字段可以建表的时候指定也可以动态添加

    • ALTER TABLE authors ADD COLUMN id INT AUTO_INCREMENT FIRST, ADD PRIMARY KEY(id),DROP PRIMARY KEY;
  • 建表时要考虑可能插入的数据量,避免字段值越界导致无法插入

  • INSERT可以不需要指定该字段的值,它会自动递增生成,保证唯一

  • 如果INSERT指定该字段的值,则之后的INSERT会从表内该字段的最大值继续递增

  • INSERT INTO … SELECT会产生空洞,但不影响唯一

UPDATE

TABLE级的DML - UPDATE概述

  • UPDATE用来更新表内的一行或者若干行
  • 可以指定更新条件-WHERE
  • 可以一次更新一张表或者多张表
    • 单表更新,可以指定LIMIT限制更新的行数
    • 多表更新无法指定LIMIT
  • 注意UPDATE的语义(和标准SQL不一样的地方)
    • UPDATE t1 SET col1=col1+1,col2=col1;
    • col1和col2将会有相同的值
  • 注意UPDATE的性能
    • 修改了二级索引包含的列会导致索引更新
    • 修改了主键会导致所有索引都要更新

TABLE级的DML - UPDATE语句

  • 更新所有记录:年龄增加一岁

    • UPDATE authors SET age=age+1;
  • 更新单条记录:将指定作者的电话进行更新

    • UPDATE authors SET phone_number = ‘86-123456’ WHERE first_name = ‘John’;

TABLE级的DML - UPDATE与AUTO_INCREMENT

ID first_name last_name gender age address phone_number
1 John Smith Male 30 Room X,Building Y 123456
2 Robert Smith Male 45 Room Q,Building W 123456
3 Robert White Male 33 Room U,Building I 123456
5.6,5.7 8.0
UPDATE authors SET id=5 WHERE id=3; UPDATE authors SET id=5 WHERE id=3;
SELECT auto_increment FROM information_schema.tables WHERE table_name LIKE ‘%authors%’;–返回4 SELECT auto_increment FROM information_schema.tables WHERE table_name LIKE ‘%authors%’;–返回6
INSERT INTO authors VALUES(0,‘Linda’,‘White’,‘Female’,36,‘Room P’,12345);–成功,id=4 INSERT INTO authors VALUES(0,‘Linda’,‘White’,‘Female’,36,‘Room P’,12345);–成功,id=6
INSERT INTO authors VALUES(‘Alice’,‘Baker’,‘Female’,28,‘Room Y’,12345);–ERROR 1062(23000):Duplicate entry ‘5’ for key ‘PRIMARY’ INSERT INTO authors VALUES(‘Alice’,‘Baker’,‘Female’,28,‘Room Y’,12345);–成功,id=7

DELETE

TABLE级的DML - DELETE概述

  • 删除表记录当记录不再需要

    • 按条件删除:DELETE … WHERE …;
    • 全表删除:DELETE FROM authors;
    • 指定删除数量:DELETE … LIMIT n;
  • 可以支持删除单张表或者多张表的记录

  • 删除一条记录会影响到所有二级索引

  • InnoDB存储引擎删除全表记录后,AUTO_INCREMENT值不会重置

  • 删除单条记录

    • DELETE FROM authors WHERE first_name = ‘Robert’;

TABLE级的DML - DELETE优化

  • 全表删除应该用TRUNCATE TABLE来替代

    • 性能更好
    • 系统开销更少,尤其是日志IO和存储开销
  • 当要删除一个InnoDB大表中绝大部分数据

    • INSERT INTO t_copy SELECT * FROM t WHERE …;
    • RENAME TABLE t TO t_old,t_copy TO t;
    • DROP TABLE t_old;
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。