今天,民工哥带大家一起来学习一下 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
不等连接:
在连接条件中,可以使用其他比较运算符,比较被连接的列的列值。这些运算符包括>、>=、