DDL(1)表和库的基础操作

实验环境

mysql8.0

1.DDL简介

DDL(data definition Language 数据定义语言)是SQL的三大核心子集之一(DML/DCL),专门用于定义/修改/删除数据库对象的结构(而非操作数据本身)

2.数据库操作

从系统架构的层次上看,mysql数据库系统从大到小依次是

数据库服务器->数据库->数据表->表中的行与列

MySQL里的最大存储单元是数据库,也是数据表的载体

2.1创建数据库

mysql以分号来识别一条语句的结束,若没有则提示语法错误
实操

创建
mysql> CREATE DATABASE test;

查看
mysql> SHOW DATABASES;

结果
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.00 sec)

我们观察到除了我们创建的"test"外,还能看到其他数据库,其中

  • information_schema 是系统自带的数据库,用于保存数据库服务器的系统信息,比如数据库的名称、数据表的名称、字段名、存取权限、数据库文件所在的文件夹等等元数据(这不就是新华字典里的索引吗?那我们可以大胆假设,我们的DDL操作都是基于这个库来执行的)
  • performance_schema是自带的,用于监控mysql的各种性能指标
  • sys 是系统自带的,以一种更容易被理解的方式展示mysql服务器的各种性能指标,帮助开发人员监控mysql的技术性能,即将上述库监控的内容展示出来
  • mysql 保存了服务器运行时需要的系统信息,比如当前使用的字符集

需要注意在mysql语句中关键字函数不区分大小写,但对于数据库名、表明、列名,在win系统下不区分(即表名abc=ABC),但在linux下大小写敏感(abc和ABC是两个不同的表),因此为了兼容性和一致性,推荐关键字使用大写,表名库名等使用小写

sql_mode可设置大小写敏感

手册定义

CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
    [create_option] ...

create_option: [DEFAULT] {
    CHARACTER SET [=] charset_name
  | COLLATE [=] collation_name
  | ENCRYPTION [=] {'Y' | 'N'}
}
  • character set选项指定默认字符集,默认的 MySQL 服务器字符集和排序规则是utf8mb4和utf8mb4_0900_ai_ci
    使用以下命令查看支持的字符集
show character set;

#charset一列表示支持的字符集
show collation; 

字符集问题不仅会影响数据存储,还会影响客户端程序与mysql服务器的通信,显示使用字符集命令

SET NAMES 'utf8mb4'
  • collate指定默认数据库的排序规则,查看与utf8mb4相关的字符集排序
show collation where Charset='utf8mb4';

其中collate的命名规则如下

字符集名称_语言_比较规则后缀
utf8mb4_unicode_ci

常见的后缀含义
后缀 含义 示例效果

后缀 含义
ci case insensitive(不区分大小写)
cs case sensitive(区分大小写)
bin 二进制比较
  • ENCRYPTION在8.0.16中引入,是数据库加密选项

综上创建一个test数据库的完整语句就是

删除原先的库
mysql>DROP DATABASE test;

完整创建
mysql> CREATE DATABASE if not exists \
    -> test character set=utf8mb4 \
    -> collate=utf8mb4_unicode_ci;

2.2创建表格

定义在这里
内容太多,直接看实操吧

选择数据库进入
mysql> USE test;

查看该库有多少表
mysql> SHOW TABLES;

创建表,已进入数据库的话可不带数据库名
mysql>CREATE TABLE  test.demo (\
barcode text, \
goodsname text, \
price int ); 

这里创建了一个demo的数据表,并设置了3个字段,有几点需要注意:

  • 创建表时最好指明数据库"test.",是为了防止没选中数据库或选错数据库的情况
  • 最后一个字段(price)后面不要加逗号“,”

最后查看创建的数据库结构

mysql> DESC test.demo

DESC是 DESCRIBE的前缀

  • Field字段名
  • Type字段类型
  • Null表示字段是否允许空值(NULL)
  • Key键
  • Default默认值
  • EXtra附加信息

先暂时了解其含义

2.2.1表数据的存储文件

关于数据表存储的文件位置,需要先了解存储引擎
8.0之后默认使用Innodb引擎,该存储引擎的存储方式有两种:

  • 在独立表空间中创建的表,表数据和关联索引存储在data文件夹的.db文件中(与表名相同,一个数据表一个文件)
  • 在共享表空间中创建的存放在ibdata1文件中*。共享表空间是指所有的InnoDB表共享同一个表空间文件(ibdata1),这些数据和索引会一起存储在一个或多个共享的物理文件中。 这是MySQL的默认设置。 节省磁盘空间:多个表共用一个文件,适合小型数据库。(一般仅在特殊场景下才如大量小表,考虑使用)

默认使用独立表空间存储,也可以在配置文件my.cnf中设置innbodb_file_per_table选项控制在哪个表空间

创建表格选项(table_option) TABLESPACE也能控制

5.6版本以后默认开启,如下是my.cnf显示设置

[mysqld]
innodb_file_per_table = ON  -- 推荐生产环境启用
mysql>SHOW VARIABLES LIKE 'innodb_file_per_table';

我们可以想到每个表对应独立的文件,删除时直接删除文件,不会产生内存碎片,甚至能对单个表进行迁移备份

2.2.2列选项

即表中的字段后面可以跟哪些参数和注意事项:

  • json列不能被索引
  • 对于char/varchar/binary/varbinary列可以创建仅使用前导部分的索引,即col_name(len),这样能使得列索引文件减小
  • 如果未指定NULL或NOT NULL,则默认NULL
  • auto_increment,每个表只能有一个auto_increment列,且必须被索引,且不能有default值
  • comment注释
  • primary key 主键,唯一索引
  • key | index 都是索引
  • unique不同索引
  • fulltext 用于全文搜索
  • foreign key 外键

其中,主键可以确保数据的唯一性,能够减少数据错误,因此它必须唯一,且不能空。
为我们的表格修改结构增加主键

mysql> ALTER TABLE test.demo \
ADD COLUMN id int PRIMARY KEY AUTO_INCREMENT;

并插入第一条数据

mysql>INSERT INTO test.demo \
(barcode,goodsname,price) \
VALUES ('01','a',3);

mysql>SELECT * FROM test.demo;

2.2.2.1字段类型

首先是5种整数形,不同的整形占用字节数不同,分别为

TINYINT    1字节
SMALLINT   2字节
MEDIUINT   3字节
TINYINT    4字节
BIGINT     8字节

其中常见的TINYINT常用于枚举数据,如系统设定等取值范围很小且固定的场景;极端的BIGINT,只有当处理特别巨大的数值时才会使用,比如双11交易量、大型门户网站点击量等。在实际工作中,系统产生故障的成本远远超过增加几个字段存储空间所产生的成本,因此首先确保数据不会超过取值范围,在这个前提下,再去考虑节省存储空间。


其次是浮点型和定点形。浮点型接触最多的是float和double,分别4字节和8字节。浮点型有个缺陷,就是不精准,这在很多编程语言中早有体现就不多解释了(本质上是存储方式造成的),因此在精确度要求高的项目中,不使用其。
因此精确存储使用定点形DECIMAL(它把十进制的整数部分和小数部分拆开,分别转为十六进制存储)

DECIMAL(M,D)

其中M表示整数加小数部分,一共多少位,M<=65,D表示小数部分位数,D<M<=65


文本类型没啥好介绍的,CHAR(M)固定M长度的字符串,VARCHAR(M)最大M长度的可变长度字符串,TEXT字符串,系统自动按实际长度存储,不需要预先定义长度,由于实际存储长度不确定,mysql不允许TEXT类型的字段做主键,遇到这种情况只能采用CHAR(M)或VARCHAR(M)


日期和时间类型也常用到,但很多实际项目中使用整形存储(时间戳),还有常用到的时间类型就是DATETIME(占用8字节)

DATATIME
日期格式 YYY-MM-DD HH:MM:SS

虽然占用存储空间最多,但表达时间最完整,取值范围也大

2.2.3常见的表格选项

表格选项table_option用于优化表的行为

  • engine新表的默认存储引擎是innodb,还有myisam(主要用于只读或以读为主),memory(数据存内存)
  • character set,collate和comment上面都提过
  • tablespace

2.3删除/修改语句和DDL的回滚

删除/修改语句没啥好说的关键词drop/alter

实操

复制一张表
mysql>CREATE TABLE test.demo1 LIKE test.demo;

添加字段
mysql>DROP TABLE test.demo1 \
ADD  level tinyint;

mysql8.0开始支持原子DDL(atomic DDL),即多条原子ddl语句构成的ddl语句,要么全部失败,要么全部成功,目前只有innoDB支持该功能

注意原子DDL并不是事务DDL,任何一条DDL语句,都会隐式结束当前会话中的任何事务,这意味着ddl语句并不能在另一个事务中执行

3.扩展DML和DQL

即数据表的增删改查,具体语法自行了解,这里只提注意点:

  • 部分插入一条数据记录(部分字段不插入)是可以的,但前提是,不赋值id字段一定要让数据库知道如何处理,比如空和默认值,或主键自增等
  • mysql 支持把查询结果插入到数据表中
INSERT INTO 表名(字段名)
SELECT  字段名 
FROM 表名
WHERE 条件
  • 因为主键需要保持唯一性,所以不要修改主键字段的值

DQL中:

  • 排序ORDER BY ,ASC表示升序,DESC表示降序
  • 部分查询LIMIT A,B
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容