死磕数据库系列(二十):MySQL 数据库 DDL、DML、DQL、DCL 语言理论与实践(sql 8.0 版)

2023年 8月 12日 68.1k 0

今天,民工哥带大家一起来学习一下 MySQL 数据库的 DDL、DML、DQL、DCL 这几种语言的理论知识与实践。如有帮助,请点在看、转发支持一波!!!

DDL(数据库定义语言)

DDL

数据(结构)定义语言 DDL(Data Definition Language),用于创建和修改数据库表结构的语言。

常用的语句:create(创建)、alter(修改)、drop(删除)、rename(重命名)

创建数据库:

CREATE DATABASE 数据库名;

CREATE DATABASE IF NOT EXISTS 数据库名;# IF NOT EXISTS 意为如果不存在就创建这个数据库,若存在就不创建

CREATE DATABASE IF NOT EXISTS 数据库名 CHARSET utf8;# CHARSET utf8 给数据库设置一个编码

删除数据库:

DROP DATABASE 数据库名;

修改字符集

ALTER DATABASE 数据库名 CHARSET utf8;

mysql中是不能修改数据库名的。

数据库中的表

数据库存储数据的特点

是将数据放到表中,再将表放到数据库当中。

一个数据库中是由多张表的,每个表都拥有一个名字,用来标识自己。且表名是具有性的。

表具有一定的特性,这些特性定义了数据在表中如何的存储,类似Java中的“类”的设计。

数据库表由列组成,我们也称为字段。所有表都是由一个或多个列组成的,每一列都类似java中的“属性”。

表中的数据时按行存储的,每一行就类似于java中的“对象”。

数据表中的基本概念

数据表

表(table)是数据存储的常见和简单的形式,是构成关系数据库的基本元素。表的简单形式是由行和列组成,分别都包含着数据。每个表都有一个表头和表体组成。表头定义表名和列名。表中的行被看作是文件中的记录,表中的列被看作是这些记录的字段。

记录

记录也被称为一行数据,是表里的一行。在关系型数据库的表里,一行数据时指一条完整的记录。

字段

字段是表里的一列,用于保存每条记录的特定信息。如顾客订单表的字段包括“订单ID”、“姓名”、“客户ID”、“职务”、“上级”、“地区”、“运货商”、“国家”等等。数据表的一列包含了特定字段的全部信息。

在我们需要设计一个表的时候。在创建之初,就应该先确定要设计表的以下特征:

表面(表星系)、表中的字段、字段中的数据类型和长度、都有哪些约束(添加数据的一些限制)

主键: 在一张表中代表的一条记录,不能为空,不呢重复

约束:

  • PRIWARY KEY :设置主键约束(主键约束包含了不能为空和性的约束)
  • NOT BULL :设置不能为空的约束(一个表中可以有多个这种的约束)
  • UNIQUE :设置性约束(一个表中可以有多个这种的约束)
  • 检查约束 :这个需要条件判断的约束(不是所有的数据库都可以设置这个约束)
  • 外键约束 :出现在多表关联时使用。

主键自动增长: AUTO_INCREMENT

默认值: DEFAULT default——value

字段注释: COMMENT ‘注释’

数据表的基本数据类型:
  • char(n)长度为n的定长字符串,即使只存入一个字符,它也要站n长的内存
  • varchar(n) 大长度为n的可变长字符串,实际存储几个就占几个字符的内存(在n长之下)
  • date 日期,包含年月日
  • datetime 年月日 时分秒(时间)

在我们应用这些数据类型的时候,就需要注意这些浮点型的小数点位数的控制。

数据类型(M,D)  M:精度,数据的总长度  D:标度,小数点后的长度  Float(6,2)  Double(6,2)  ===》例如:3245.12 四位整数,两位小数总长为6位

BLOB和TEXT类型

BLOB是一个二进制的大对象,可以容纳可变数量的数据,用于存储图片视频信息。有4中BLOB的具体类型:TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB。它们只是可容纳值的大长度不同。

TEXT列字符字符串

有4种TEXT类型:TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT。

它们两个的长度都是可变的长度。

建表语句

建立一个基本表,不涉及任何约束

CREATE TABLE t_student{ `num` INT, `number` VARCHAR(4), `sex` CHAR(1), `birthday` DATE, `height` FLOAT(4,1), `phone` CHAR(11), `register_time` DATETIME}

加上约束来对数据库表进行创建[ ]表示可以没有,也能创建出表。

CREATE TABLE t_user ( id INT [ PRIMARY KEY NOT NULL AUTO_INCREMENT ], number INT (5) [ NOT NULL ], `name` VARCHAR (10) [ NOT NULL ], sex CHAR (1) [ DEFAULT '男' ] COMMENT '性别,默认为男。comment意为注释说明', age INT (3) [ CHECK (age > 18) ], phone CHAR (11) [ NOT NULL UNIQUE ], birthday DATE, weight DOUBLE, oper_time DATETIME,)

删除表语句

DROP TABLE [IF EXISTS] 表名;

修改表名语句

RENAME TABLE 旧表名 TO 新表名;

复制表(对某张表操作时,备份数据)语句

CREATE TABLE 新表名 LIKE 被复制表名;

修改表结构语句

添加/删除表的主键约束

#给表中的某一列添加主键且一张表中只能有一个主键,#但是可以多个表字段联合作为表的主键ALTER TABLE 表名 ADD PRIMARY KEY(列名) #删除表中的主键ALTER TABLE 表名 DROP PRIMARY KEY

设置表中的自动增长

#添加列为自增(设置自增的列必须为整数型的数据类型)ALTER TABLE 表名 MODIFY 列名 数据类型 AUTO_INCREMENT;#删除列的自增ALTER TABLE 表名 MODIFY 列名 数据类型;

设置不能为空

#添加一个列不能为空的约束ALTER TABLE 表名 MODIFY 列名 类型 NOT NULL;#取消一个列不能为空的约束ALTER TABLE 表名 MODIFY 列名 类型 NULL;

设置约束

#添加表中某一列不能为空的约束ALTER TABLE 表名 ADD CONSTRAINT 约束名 UNIQUE(列名);#删除表中某一列不能为空的约束ALTER TABLE 表名 DROP INDEX 约束名;

设置检查约束

#添加约束名ALTER TABLE 表名 ADD CONSTRAINT 约束名 CHECK (条件);#删除约束名ALTER TABLE 表名 DROP CHECK 约束名;

添加列

#添加一个数据表中的列,默认是在后一列进行添加ALTER TABLE 表名 ADD 列名 数据类型; #指定给列前进行一个添加列的操作ALTER TABLE 表名 ADD 列名 数据类型 FIRST;#指定给列名1之后添加一列ALTER TABLE 表名 ADD 列名 数据类型 AFTER 列名1;

删除列

ALTER TABLE 表名 DROP 列名;

修改列名

ALTER TABLE 表名 CHANGE 旧列名 新列名 数据类型;

修改列的数据类型

ALTER TABLE 表名 MODIFY 列名 新数据类型;

DML(数据库操纵语言)

DML 数据操纵语言(Data Manipulation Language)

常用语句:INSERT(插入数据)、DELETE(删除数据)、UPDATE(修改数据)

数据库中NOW()表示的是获得当前所在系统的时间

插入数据:

方式1:

INSERT INTO 表名(列1,列2...,列n) VALUES(值1,值2...,值n);-- 例如:INSERT INTO t_student (  NAME,  sex,  birthday,  height,  mobile,  reg_time)VALUES  (    '张三',    '男',    '2000-1-1',    170.1,    '13333333333',    NOW()  );

方式2:

INSERT INTO 表名 set 列名1=值1,..列名n=值n;-- 例如:INSERT INTO t_student SET NAME = '李四',sex = '女',birthday = '2001-1-1',height = 170.1,mobile = '135555555',reg_time = NOW();

方式3:(一次添加多条数据)

INSERT INTO 表名(列1,列2...,列n) VALUES(值1,值2...,值n),(值1,值2..., 值n),...;-- 例如:INSERT INTO t_student (  NAME,  sex,  birthday,  height,  mobile,  reg_time)VALUES  (    '张三1',    '男',    '2000-1-1',    170.1,    '13333333333',    NOW()  ),  (    '李四1',    '男',    '2000-1-1',    170.1,    '135555555',    NOW()  );

方式4:将一个表的数据复制到另一个表的操作(相当于数据备份)就是它得到值来自于另外的一个查询语句。

INSERT INTO 表名(列1,列2……,列n) 查询语句(查询的列数与插入列数匹配)-- 例子:将t_student表中的数据插入到stu这个表当中去。INSERT INTO stu (  NAME,  sex,  birthday,  height,  mobile,  reg_time)SELECT  NAME,  sex,  birthday,  height,  mobile,  reg_timeFROM  t_student;

修改数据

UPDATE 表名 SET 列名 = '新值' WHERE 条件;-- 例子:修改在t_student表中的num为1的数据中name为张三 sex为女的操作UPDATE  t_studentSET  NAME = '张三',  sex = '女'WHERE num = 1;

修改当中也是可以不用添加条件的,不添加条件的话,就会将每条数据对应的列都做修改。

所以修改的时候一定要注意条件。

删除语句

#删除与修改同样,也是可以不用添加条件的,不添加条件的话就会删除当前表中的所有数据。DELETE FROM 表名 WHERE 条件;-- 例子:DELETEFROM  t_studentWHERE num = 1#指定在t_student表中的num为1的这一行数据进行删除。

在要删除一张表的时候,也可以使用下面这条查询语句:

TRUNCATE TABLE 表名;-- 清空整张表

DQL(数据库查询语言)

DQL(Data Query Language)数据查询语言

数据查询语句是使用频率高的一个操作,是可以从一个表中查询数据,也可以从多张表中进行关联查询数据。

基础语法:

SELECT 查询列表 FROM 表名 [WHERE 条件];

特点:
  • 查询列表可以是:表中的字段、常量、表达式、函数
  • 查询的结果是一个虚拟出的表格。

查询结果的处理

1.查询常量值(了解一下就行了,没啥用)

SELECT 100;

2.查询表达式

在SQL中可用的表达式有:+、-、*、/

SELECT 100*2SELECT 列+5 FROM 表;--例如:SELECT height+5 FROM t_student;--给查出的每一列数据都加上一个5

3.查询函数

SELECT 函数;-- 例如:SELECT VERSION();-- 查看当前SQL的版本是多少

4.特定列查询

SELECT 列名1,列名2,... FROM 表名;

5.全部列查询

SELECT * FROM 表名;

6.去除重复行查询

将查询出来的重复数据去掉,针对查询出来的结果,要求是查询出的所有列数据都要一样,才会去掉。

SELECT DISTINCT 列名1,列名2,... FROM 表名;

使用函数对查询结果的处理

函数:类似于Java中的方法,将一组逻辑语句事先在数据库中定义好,在需要使用的时候直接调用就好了,想调用now()函数一样。

优点:

  • 1.隐藏了实现的细节
  • 2.提高了代码的重用性

调用方式:

SELECT 函数名(实参列表)[from 表];

分类:

  • 单行函数:如concat、lengthifnull等。
    • 就是查询出来的结果是多少行,这个函数就会对每一行的数据都进行处理操作。
  • 分组函数:做统计使用,又称为统计函数、集合函数、组函数。
    • 也叫聚合函数;多行转为一行。

单行函数

字符函数

● length():获取参数值的字节个数。一个中文3个字节。

-- 获得当前列名的字节各处SELECT LENGTH(列名),列名 FROM 表名;

● char_length():获取参数值的字符个数。

-- 获取当前列名的字符个数。SELECT CHAR_LENGTH(列名),列名 FROM 表名;

● concat(str1,str2,…):拼接字符串。

它可以将两个字符接在一起,以一个列进行发送。

SELECT CONCAT(str1,str2...) FROM 表名;-- 例如:-- 将两个列,通过字符的连接,以一个列进行了发送。SELECT CONCAT(列名1,':', 列名2)AS name FROM 表名;-- AS name 是对定义了一个别名(AS也是可以省略的)

● upper():将字符串变成大写。

SELECT UPPER(列名) FROM 表名;

● lower():将字符串变为小写。

SELECE LOWER(列名) FROM 表名;

● substring(str,pos,length):截取字符串,从位置pos位置开始。

SELECT SUBSTRING(列名,开始截取位置(从1开始),截取长度) FROM 表名;

● instr(str,指定字符):返回子串次出现的索引,如果找不到就返回0类似于java中的indexof();

SELECT INSTR(列名,指定的字符) FROM 表名;-- 例子:SELECT INSTR('abcd','a');

● trim(str):去掉字符串前后的空格或子串。trim(指定子串from字符串)

-- 去掉字符前后的空格。SELECT TRIM(列名) FROM 表名;-- 去掉子串SELECT TRIM(指定的子串 FROM 列名) FROM 表名;-- 列子SELECT TRIM('d' FROM 'abcd');

子串和空格一样,只能去掉字符串前后的子串,中间的不行。

● lpad(str,length,填充字符):用指定的字符实现左填充将str填充为指定长度。

SELECT LPAD(列名,指定总长度,填充字符) FROM 表名;-- 例子:SELECT LPAD('wasd',6,'a') ;

指定的总长就是后结果的总长,若需要填充的字符串长度就高于指定总长度,就会截取这么长的字符串。

SELECT LPAD('wasd',3,'a') ;

● rpad(str,length,填充字符):用指定的字符实现右填充将str填充为指定长度。

SELECT RPAD(列名,指定总长度,填充字符) FROM 表名;

● replace(str,old,new):替换,替换所有的子串。没有的就不操作了。

SELECT REPLACE(列名,指定旧字符,新字符) FROM 表名;-- 例子:SELECT REPLACE('wwaa','a','w');

逻辑函数

case when 条件 then 结果1 else 结果2 end;(可以有多个when),当条件满足的时候就是结果1,当条件不满足的时候就是结果2。

SELECT  (CASE WHEN 列名 条件 THEN 结果1 ELSE 结果2 END)FROM  表名;-- 例子:使用多个when来生成结果。SELECT  (CASE WHEN 140>=180 THEN '偏胖' WHEN 140>100 AND 1401,'true','false');

数学函数

1.round(数值):对传入的数值进行四舍五入(四舍五入的时候只看小数点之后的位)

2.ceil(数值):对数值进行向上取整,返回>=该参数的小整数

3.floor(数值):对数值进行向下取整,返回、=、180;

SELECT * FROM student WHERE NOT sex = '男' AND NOT weight>100;

其他的都一样,就不一 一演示了。

模糊查询

LIKE:是否匹配于一个模式,一般情况下是和统配符搭配一起使用的,可以判断字符型或者数值型。

统配符:

% 表示前或后可以有任意多个(包含个字符);_ 前或后只能表示一个,单个字符;(有几个下划线就只能有几个字符,多了少了都不行)BETWEEN 条件1 AND 条件2:表示两者之间,包含临界值;(相当于条件查询中的 >= 条件1 AND  100;

SELECT * FROM student WHERE sex = '女' UNION ALLSELECT * FROM student WHERE weight > 100;

对查出的数据进行排序和数量限制

1.排序

就是对结果进行排序,使用ORDER BY对子句进行排序。

语法:ORDER BY 列名 ASC/DESC

ASC代表的是升序,DESC表示降序,如果不写,默认的是进行升序。

ORDER BY子句中可以支持单个字段、多个字段、表达式、函数、别名。

举例:

SELECT * FROM student WHERE weight > 100 ORDER BY height ASC;

SELECT * FROM student WHERE weight > 100 ORDER BY height DESC;

当一个列排序的时候,应为重复性不能做出明确排序,可以再加一个字段进行排序:(就是先用个排,当个遇到相同的时候,再用第二个排)

SELECT  * FROM student WHERE weight > 100 ORDER BY height DESC,weight DESC;

函数同理;

数量限制

limit子句:可以理解为就是对查询出来的数据进行一个行数限制(书写在SQL语句的末尾位置)。

语法:SELECT * FROM 表名 LIMIT 初始位置,几行数据

初始位置默认初为0

举例:

查询身高高的两名同学:这条语句正常数据是由三条,使用了limit 设置语句,表示它从头开始,查出两行数据。

SELECT  *FROM  studentWHERE weight > 100ORDER BY height DESCLIMIT , 2;

分组查询

语法:

SELECT 分组函数,列名(所要分组的要求列) FROM 表名 [WHERE 分组前的筛选条件] GROUP BY 分组的列名 [HAVING 分组后的筛选]

查询条件 WHERE和HAVING的区别:举例:

-- 意为将数据在student表内按sex进行分组,然后对没一组进行就数据量、数据求和、大值。SELECT sex,COUNT(*),SUM(height),MAX(height) FROM student GROUP BY sex;

SELECT  sex,  COUNT(*)FROM  studentWHERE height IS NOT NULL #分组前将height为空的信息去除GROUP BY sex  #按照sex对数据进行分组HAVING sex = '男' #分组后只要sex为‘男’的数据ORDER BY COUNT(*) #对数据进行一个排序 默认为升序LIMIT ,1 #对查出的数据进行数量限制

子查询

含义:出现在其他语句中的SELECT语句,称为子查询或内查询;外部的查询语句,称为主查询或外查询。

分类:按子查询出现的位置:
  • 1.SELECT后面:仅仅支持标量子查询;
  • 2.FROM后面:支持表子查询;
  • 3.WHERE或HAVING后面:支持标量子查询,列子查询,行子查询;

在修改、删除表中数据的语句中使用子查询,注意的是,子查询中不能使用当前正在操作的表。

按功能、结果集的行列数不同:
  • 1.标量子查询(结果集只有一行一列)
  • 2.列子查询(结果集只有一列多行)
  • 3.行子查询(结果集有一行多列)
  • 4.表子查询(结果集一般为多行多列)

子查询在SELECT语句内部可以出现SELECT语句。

语句结果可以作为外部语句中条件子句的一部分,也可以作为外部查询时的临时表。

在一条SQL语句中,如果出现2个以上的表名时,我们可以为这个表名定义别名

举例:SELECT后面

SELECT  st.sex,  (SELECT s.name FROM student s WHERE s.`name` = st.name)FROM  student st 

在FROM后面:

SELECT  * FROM (SELECT sex,NAME FROM student)sWHERE s.sex = '男'

在WHERE或HAVING之后:

-- 标量子查询SELECT  *FROM  studentWHERE height =(SELECT MAX(height) FROM student);

-- 列子查询SELECT  *FROM  studentWHERE height IN (SELECT height FROM student WHERE height > 170);

-- 行子查询SELECT  *FROM  studentWHERE (height, weight) =(SELECT MAX(height),MAX(weight) FROM student);

多表关联

在设计表的时候,我们有时候是需要多表关联的,主要为了减少数据的冗余,对表进行拆分。

数据库设计范式:为了建立冗余较少,结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则称为范式。范式是符合某一种设计要求的总结。

目前关系数据库有5种范式:

  • 范式(1NF)
  • 第二范式(2NF)就可以
  • 第三范式(3NF)
  • 第四范式(4NF)
  • 第五范式(5NF)又称器完美范式

满足低要求的范式就是范式。在范式的基础上进一步满足更多规范要求的称为第二范式,其余范式依次类推,一般来说,数据库只要到达第三范式就可以了。

范式(确保每列都保持原子性)

范式是对基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了范式。

2.第二范式(包含了主键,要求其他字段都要依赖于主键)

没有主键就没有性,没有性在集合中就定位不到这行数据记录,所以就要有主键。

其他字段为什么要依赖于主键?因为不依赖于主键,就找不到他们。更重要的是,其他字段组成的这行记录和主键表示的是同一个东西,而主键是的,它们值需要依赖于主键,也就成了的。

3.第三范式就是要消除传递依赖,方便理解,可以看作是“消除冗余”。

外键

就是“引用”另外一个数据表的某条记录。

外键类类型必须和主键列类型保持一致。

数据表之间的关联/引用关系是依靠具体的主键(PRIMARY KEY)和外键(FOREIGN KEY)建立起来的。

建表时就增加外键:

CREATE TABLE 表名( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, sid INT, CONSTRAINT 约束名 FOREIGN KEY(sid) REFERENCES 关联表(主键));

添加外键约束名

ALTER TABLE 表名 ADD [CONSTRAINT 约束名] FOREIGN KEY(外键列) REFERENCES 关联表(主键);

删除外键约束:

ALTER TABLE 表名 DROP FOREIGH KEY 外键约束名;

举例:

先建两张表像这种有关系但没有关联的关系我们也叫做弱关联。没有实际之间的约束。

有外键的也就叫做强关联。(添加外键约束)

ALTER TABLE student  ADD CONSTRAINT fk_gradeId FOREIGN KEY (gId) REFERENCES grade(id);

意为将student表中的gId列与grade表中的id列进行关联。

进行关联后,表头也就有了一些的变化。删除外键:

ALTER TABLE student DROP FOREIGN KEY fk_gradeId;

注意:

  • 1.当主表中没有对应的记录时,是不能将记录添加到从表中的。
  • 2.不能更改主表中的值而导致从表中的记录孤立。
  • 3.表存在与主表对应的记录,不能从主表中删除该行。
  • 4.删除主表前,先删从表中的数据。

关联查询

含义:又称为多表查询,当查询的字段来自与多个表时,就会用到连接查询(一对多、多对一、一对一、多对多)

笛卡尔乘积现象:表1有m行,表2有n行,结果 = m*n;

发生原因:没有有效的连接条件

如何避免:添加有效的连接条件

代码演示:

 SELECT * FROM student,grade ;

解决办法:添加条件,多表时,为表定义别名,通过别名去调用表中的列,这样就不会重复了。

SELECT  *FROM  student s,  grade gWHERE s.gId = g.id  -- 先合并表,后筛选

按功能分类:

  • 1.内连接:等值连接、非等值连接、自连接
  • 2.外连接: 左外连接、右外连接
内连接(INNER JOIN)

主要通过设置连接条件的方式,来移除查询结果中某些数据行的交叉连接。

说人话就是:是利用条件表达式来消除交叉连接的某些数据行。

格式:

SELECT 列名 FROM 表1 INNER JOIN 表2 [ON子句]

等值连接:

使用等于号(=)比较被连接列的列值,在查询结果中列出被连接表中的所有列,包括其中的重复列。

SELECT  *FROM  student s  INNER JOIN grade g    ON s.gId = g.id 

不等连接:

在连接条件中,可以使用其他比较运算符,比较被连接的列的列值。这些运算符包括>、>=、

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论