实验环境
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