文章目录
作者信息
作者:黄钰朝
邮箱:kobe524348@gmail.com
日期:2019年7月10日
前言
今天的学习任务是数据库的基础语法和三大范式。
基础语法方面主要就是一些查询元数据的语句,比如查看一下数据库,查看一下建表语句,增删改查太基础了我就不把它写一遍了,学到的新东西是正则表达式的关键字,还有计算字段这种操作,之前只知道起别名。还有一些数据处理函数,我似乎只用过count,后面就是数据库设计三大范式的内容,我写得很简陋。总的来说,今天学的东西感觉不多,那些触发器,存储过程都没学,索引的知识是明天的任务。
一.基础查询语句
1.1 查询元信息
- show databases 列出数据库
- show tables 列出所有表
- show columns 列出所有字段
- show status 列出服务器状态
- show grants 列出用户的授权状态
- show create database 列出建库语句
- show create table 列出建表语句
- show errors 列出服务器错误
- show warnings 列出服务器警告
1.2 SELECT语句
查询记录使用select语句。格式如下:
- select 字段… from 表名 [where]
其中where 子句有AND,OR,NOT,IN等操作符。
前面三个顾名思义,我刚刚才知道还有IN.
select name from user where age IN (18,19,20);
表示年龄在18,19,20中的一个的都符合条件。其实就是OR语句的简化。
1.3 MySQL的通配符
- % :百分号表示任意字符重复任意次数,等于说啥都行
- _ :下划线表示任意单个字符
1.4 MySQL的正则表达式
只需要一个关键字:REGEXP (我目测是 regex pattern 的缩写)
select name from user where age REGEXP ‘18|19|20’;
关键字后面加正则表达式就行了。
下面是常用的正则:
- select name from user where age REGEXP ‘.8’; "."表示匹配任意字符
- select name from user where age REGEXP ‘18|19|20’; “|”相当于OR
- select name from user where age REGEXP '[123] 0 '; 表示10,20,30 都匹配。也就是第一个数字从1,2,3里选
- select name from user where age REGEXP '[1-3] 0 '; 表示10,20,30 都匹配。也就是第一个数字从1到3之间选
二.对数据的处理
2.1 计算字段
计算字段就是将查出的字段做一些计算或处理。
2.1.1 起别名
最简单的计算,给字段起个别名。使用AS关键字。
- select name AS nickname from user ; 把查出来的name字段叫做nickname
2.1.2 拼接字段
把取出来的字段拼接一下,使用Concat函数。
- select Concat( ’ 姓名:’, name) from user; 将“姓名”和name字段拼接起来
2.1.3 算术计算
简单理解就是几个字段加减乘除。
- select price*number from product;将两个字段相乘
2.2 数据处理函数
2.2.1 数值处理函数
对某个字段的值进行处理。
直接上图:
2.2.2 聚集函数
跟数值处理函数不同在于,数值处理是对每个单独的字段的处理,而聚集函数是对某一列的所有被查询的字段的整体所作的统计处理,比如求和,求平均值。
还是上图:
2.2.3 时间处理函数
时间处理函数就是用来处理时间数据(废话),具体有哪些见下表。
为什么要时间处理函数?
举个栗子:数据库保存的是精确到秒的时间,如一条记录保存的时间(字段为time)是2019年7月10日19时22分18秒,我想查出所有时间为这一天的记录,咋办?不用时间处理函数的话,用select * from table1 where time = 2019-07-10的话,肯定是不行的,显然这两个时间匹配不上的,这时候时间处理函数就派上用场了,用select * from table1 where Date(time) = 2019-07-10,就可以把那个精确的时间(2019年7月10日19时22分18秒)的日期部分取出来去匹配条件。
2.3 排序
关键字:ORDER BY
这个再简单不过了,ORDER BY子句,逆序加个DESC就完了。用法顾名思义吧。
2.4 分组
关键字:GROUP BY
直接看例子比较方便:
- SELECT name, COUNT(*) FROM student GROUP BY name; 按名字分组,统计每个人(每组)有多少条记录。
2.5 过滤一些分组
关键字:HAVING
用来过滤一些符合HAVING后面的条件的分组。
- SELECT name, COUNT(*) FROM student GROUP BY name HAVING name = “小明” ; 按名字分组,统计每个人(每组)有多少条记录 ,除去所有小明的记录。
二.数据库设计三大范式
2.1 第一范式(原子性)
第一范式是要求每一列都是不可分割的,比如一个订单有多个商品,如果都写在一行记录里,那么商品一栏就有多个数据,也就是说,商品这一列已经不是不可分割的了,应该分成多行,让每行都是这个订单对应其中一个商品,这样就是一行记录只记一件事,每一列也就不可分割。
2.2 第二范式(消除部分依赖)
在满足第一范式的基础上,第二范式要求消除部分依赖,这是针对使用联合主键的情况,如果已经满足第一范式,又只有一个主键,那么自动满足第二范式。
如果使用了联合主键,那么第二范式要求,所有非主键的字段都要依赖于联合主键,而不能只依赖于主键中的部分字段。
比如假设有一张表使用订单id和商品id作为联合主键,那么如果表中还有商品名称,商品价格这些只依赖于商品id而与订单id无关的字段,就属于只依赖于部分主键的情况,要使其满足第二范式,应当将商品名称,商品价格这些对主键部分依赖的字段分离出去,否则如果很多订单都是买同一个商品,那么这个商品名称和商品价格就会在多行记录中重复出现,而且,如果要添加一个新的商品,那么由于没有订单信息,导致无法插入这张表,就非常荒诞了。
部分依赖带来以下问题:
- 数据重复
- 修改时要同时修改多处地方
- 可能导致无法插入需要保存的数据,如上面例子中的商品信息
2.3 第三范式(消除传递依赖)
在满足第一,第二范式的基础上,第三范式要求消除传递依赖。
传递依赖就是指,一个字段与主键不存在依赖关系,只是通过另外一个字段间接依赖主键。例如商品价格依赖于商品id,商品id依赖于主键订单id,那么商品价格对主键就是传递依赖。
第三范式要求不要把对主键间接依赖的字段放在表中。比如订单表中只要记商品id,剩下的商品的相关信息全部都分离出去。
传递依赖带来的问题和部分依赖相同。
总结
看了那两本书的基础语法部分,感觉像是在复习SQL语句,后面有一些新概念,比如通配符,函数那些,但是内容也不多,数据三大范式之前训练营都讲过了,感觉也是复习,可能是我看的书太浅了。不过毕竟今天早上做断点续传项目去了,下午补http的笔记去了(整理http的加密和认证过程和原理,头都大了),晚上这点时间确实也学不了多少东西,还是看明天能不能学得深入一点吧。
参考资料
- 《高性能MySQL》
- 《MySQL必知必会》
- 菜鸟教程-MySQL教程
- 数据库设计三大范式
- 第二范式和第三范式的区别?