
启动¶
- net start mysql
登录¶
- -p后面可以不跟密码,这样会接着让你输密码.
- 默认端口3306
数据都在 /data之下.
数据模型¶
一个mysql服务器里可以有多个数据库.
- create database db01;
这样在/data文件夹当中就会有db01这个文件夹(数据库)了.
一个数据库里可以有多张表.每个表也是一个文件夹.
sql语句¶
分类:
最后一类主要是DBA(数据库管理员)负责的.
DDL - 数据库级别¶
其中,select database()中,database()是一个mysql提供的函数.
查询数据库¶
多的都是系统自带的数据库.
另外,大小写是不区分的.
使用/查询当前数据库¶

创建数据库¶
如果有重名,那么就会报错.因此可以使用create database if not exists db01; 另外还可以指定字符集.实际上我们最常用的就是utfmb4,这是最常用的,可以存诸如表情字符等. mysql8以上,默认就是utf8mb4.
删除数据库¶
如果不存在,那么就会报错.因此可以使用drop database if not exists db01;
也就是说schema和database是一个意思.
- schema又翻译成"架构"
mysql客户端图形化工具 - datagrip¶
选择展示哪些数据库:
注释是两个--并且空一格.
想执行哪句就选中,点击运行:
查看历史:
切换数据库:
这样就不需要对应的sql语句了.以及诸如创建/删除数据库的操作都可以.
DDL - 表结构¶
创建表结构¶
字符串一般使用单引号.
verchar(50) 最长50个字符的字符串
char(1) 固定一个字符的字符串

添加字段¶
可以这样通过图形化的方式添加.
约束¶
如何保证id的唯一性?使用约束
多个约束之间通过空格隔开
自增:auto_increment
generated表示自动增长,从0开始.
也可以手动指定(如10),但是仍然不能重复.下一次增长时,会从上一个开始(也就是11)
另外,如果过程中曾删除过某个条目,那么它之前拥有的id是不会被重新赋给别人的,而是直接跳过.
- 与not null对应的还有个null:表示默认就是null.
数据类型¶
数值¶
常用就是tinyint int bigint(分别对应byte int long)
float(5,2)表示总位数为5(整数+小数位)标度(也就是小数位)为2
数值类型的选取原则:在满足业务需求的前提下,尽可能选择占用磁盘空间小的数据类型.
如:
age:tinyint unsigned
id:int unsigned
字符串¶
如果固定长度就用char,不固定就varchar
如:username就varchar
后面的有blob后缀都是二进制数据,test后缀都是文本数据.我们一般不会在数据库里直接存这个的数据.相反,我们一般是存访问路径.
时间¶
timestamp由于2038就到期了,因此不常用.我们常用的也就date和datetime
样例¶
如果是存性别,用tinyint,并且规定映射关系:
如果是类似于枚举类型,都这么处理:
存password有的人会用varchar(32),因为md5就是32位的.(当然,这样不安全).
基础字段¶
我们设计表的时候,一般都会包括这三个字段:

表的增删查改¶
字段类型是modify,字段名与字段类型是change
当然,这些其实不需要掌握,因为有图形化界面.
DML¶
insert (into)¶

也就是:insert into 表名开头(实测容易忘into) 如果表名后有括号那么就指定某个列,否则就是全部 然后使用values(),() 来描述添加的具体内容.
其实一般来说,即使是插入全部,我们也可以把字段都写出来.
注意,时间也可以使用引号来表示:'2020-01-01'
当前时间:使用函数now()表示当前时间
注意字符串和时间的引号,双引号可以,单引号也可以.当然,sql语句中推荐单引号,因此如果使用双引号,那么datagrip会报错(实际上执行sql语句不会)
update (set)¶
注意多个项之间通过逗号隔开.
不带条件的更新是一种危险的操作.
where语句:
delete (from)¶

DQL¶
SELECT(使用频率占90%)
前两条表示基本查询:
分组查询:
排序查询:
分页查询:

基本查询¶
如果查询的时候自动补全这样:
这个emp.entry_date表示是在emp这个表的entry_date字段.
全表查询¶
另外,全表查询:
第一种方式性能更高.并且更加直观
别名¶
另外,起别名会在结果中体现:
起别名是可以不加引号的:
如果当中有空格,那么必须加引号:
当然,这会导致结果有些怪异:

去重¶
select distinct job from emp;
条件查询¶
- 注意between既包含最小值,也包含最大值.
- 判断null值不能通过=null/!=null,而是必须通过is null/is not null
- <>表示不等于,认识即可,自己还是写!=
- between and是放在字段后面修饰的:
- between A and B,必须确保A是<B的,否则啥都查询不出来.
-
会发现这样两个and虽然看起来怪异,但是是对的.
为了可读性,可以加括号:
- in也是放在字段后面修饰字段的:
- like可以这样用:
也就是说,除号是可以匹配0个字符的.
分组查询¶
分组:按照某些属性把数据分组,然后在分组里操作.
聚合:
注意,所有的聚合函数不参与null值的统计.如count时,遇见null会忽略掉.
下面仅仅列出一些特殊的.
count¶
三种用法:
id是非空的,因此可以.
统计的是总数据量.
只要count的不是null,那么结果都是正确的.原理:会扫描整张表,每扫描到1行,就标记为1,最后统计总共有多少个1.
推荐使用第二种,因为底层优化了,效率更高.第三种也可以.
其他¶
我们可以看出,其实就是把一般的sql语句 select salary from emp中的字段salary变成了聚合函数.
分组查询的语法¶
最后相当于是输出满足条件的分组内容.
示例¶
注意:
结果:
如何理解:我们一般查询的返回结果是张表.使用group by 之后,就会得到两张表.一张是所有"男"的表,一张是所有"女"的表.接着,对两张表的gender列分别使用count处理.
还要处理获得员工数量大于等于2的职位:
因此,having是对分组之后的结果进行过滤处理的.
敲一下熟悉一下:
select job,count(*) from emp where entry_date<='2015-01-01' group by job having count(*) >=2;
排序查询¶
根据多个字段进行排序:只需要在第一个字段排序完成之后,加个逗号,继续第二个字段的排序.
因此,asc/desc只是用来修饰前面一个字段的.
分页查询¶
起始索引默认从0开始,表示从哪开始查.
拿到前端数据页码:
