关系型数据库管理系统可以分为:
关系型数据库服务端软件
关系型数据库客户端软件
关系型数据库服务端软件:
主要负责管理不同的数据库,而每个数据库里面会有一系列数据文件,数据文件是用来存储数据的, 其实数据库就是一系列数据文件的集合。
关系型数据库客户端软件:
主要负责和关系型数据库服务端软件进行通信(通信语言就是我们的SQL语句,通过SQL可以操作oracle,sql server,mysql,sqlite 等关系型的数据库 ), 向服务端传输数据或者从服务端获取数据.
SQL语言主要分为:
DQL:数据查询语言,用于对数据进行查询,如select
DML:数据操作语言,对数据进行增加、修改、删除,如insert、update、delete
TPL:事务处理语言,对事务进行处理,包括begin transaction、commit、rollback
DCL:数据控制语言,进行授权与权限回收,如grant、revoke
DDL:数据定义语言,进行数据库、表的管理等,如create、drop
查看MySQL服务状态:
sudo service mysql status
停止MySQL服务:
sudo service mysql stop
启动MySQL服务:
sudo service mysql start
重启MySQL服务:
sudo service mysql restart
MySQL配置文件的介绍:
配置文件路径为: /etc/mysql/mysql.conf.d/mysqld.cnf
port表示端口号,默认为3306 bind-address表示服务器绑定的ip,默认为127.0.0.1 datadir表示数据库保存路径,默认为/var/lib/mysql log_error表示错误日志,默认为/var/log/mysql/error.log
常用数据类型如下:
整数:int,bit
小数:decimal
字符串:varchar,char
日期时间: date, time, datetime
枚举类型(enum)
常见的约束如下:
主键 primary key: 物理上存储的顺序. MySQL 建议所有表的主键字段都叫 id, 类型为 int unsigned.
非空 not null: 此字段不允许填写空值.
惟一 unique: 此字段的值不允许重复.
默认 default: 当不填写字段对应的值会使用默认值,如果填写时以填写为准.
外键 foreign key: 对关系字段进行约束, 当为关系字段填写值时, 会到关联的表中查询此值是否存在, 如果存在则填写成功, 如果不存在则填写失败并抛出异常.
1. 整数类型
类型 | 字节大小 | 有符号范围(Signed) | 无符号范围(Unsigned) |
---|---|---|---|
TINYINT | 1 | -128 ~ 127 | 0 ~ 255 |
SMALLINT | 2 | -32768 ~ 32767 | 0 ~ 65535 |
MEDIUMINT | 3 | -8388608 ~ 8388607 | 0 ~ 16777215 |
INT/INTEGER | 4 | -2147483648 ~2147483647 | 0 ~ 4294967295 |
BIGINT | 8 | -9223372036854775808 ~ 9223372036854775807 | 0 ~ 18446744073709551615 |
2. 字符串
类型 | 说明 | 使用场景 |
---|---|---|
CHAR | 固定长度,小型数据 | 身份证号、手机号、电话、密码 |
VARCHAR | 可变长度,小型数据 | 姓名、地址、品牌、型号 |
TEXT | 可变长度,字符个数大于 4000 | 存储小型文章或者新闻 |
LONGTEXT | 可变长度, 极大型文本数据 | 存储极大型文本数据 |
3. 时间类型
类型 | 字节大小 | 示例 |
---|---|---|
DATE | 4 | '2020-01-01' |
TIME | 3 | '12:29:59' |
DATETIME | 8 | '2020-01-01 12:29:59' |
YEAR | 1 | '2017' |
TIMESTAMP | 4 | '1970-01-01 00:00:01' UTC ~ '2038-01-01 00:00:01' UTC |
一、基础操作数据库的sql语句
# 显示当前时间 select now(); 登出(退出)数据库: quit 或 exit 或 ctrl + d 使用数据库 use 数据库名; 查看当前使用的数据库 select database(); 删除数据库-慎重 drop database 数据库名;
二、表结构操作的sql语句
查看当前数据库中所有表 show tables; 创建表: create table 表名( 字段1 字段类型 字段约束, 字段2 字段类型 字段约束, . 。 。 ) 修改表-添加字段 alter table 表名 add 列名 类型 约束 修改表-修改字段类型 alter table 表名 modify 列名 类型 约束; (modify 只能修改字段的类型或者约束,不能修改字段名) 修改表-重命名和字段类型 alter table 表名 change 原名 新名 约束及类型; 修改表-删除字段 alter table 表名 drop 列名; 删除外键约束: alter table 表名 drop foreign key 外键名; 查看创表SQL语句 show create table 表名; 查看创库SQL语句 show create database 库名; 删除表 drop table 表名;
三、表数据操作的SQL语句
1.查询数据 -- 1. 查询所有列 select * from 表名; --2.查询指定列 select 列1,字段...from 表名; 2.添加数据 --1.全列插入:值的顺序与表结构字段的顺序完全一致对应(填写的值与字段对应) insert into 表名 values(字段1数据,字段2数据,....) --2.部分插入:值的顺序与给出的列顺序对应 insert into 表名 (列1,列2,....) values(值1,值2,...) --全列多行插入 insert into 表名 values(值。。),(。。。)。。; --部分列多行插入 insert into 表名 (列n,列m...)values(值1,...),(值2,...) 注意: 1.主键列是自动增长的,如果在全列插入的时候需要占位通常使用空值(0或者null或者default) 2.在全列插入时,如果字段是有默认值可以使用default来占位,插入后的数据就是之前设置的默认值 3.修改数据 --1.update 表名 set 字段1=值1,字段2=值2 ... where 条件 例:update students set age = 10 ,name = 'jzj' where id = 6; 4.删除数据 delete from 表名 where 条件 例:delete from students where id = 5; 问题: 上面的操作称之为物理删除,一旦删除就很不容易恢复,我们可以使用逻辑删除的方式来解决上面的问题 --添加删除表的字段,0表示未删除,1表示已删除 alter table students add is_delete bit default 0;(添加is_delete字段) 数据量度单位,bit 是电脑记忆体中最小的单位 1byte=8bits --逻辑删除数据 update students set is_delete = 1 where id = 8;(1表示已删除) 逻辑删除,本质就是修改操作
SQL基础语句小结
删除某个数据为:delete from where
删除表/数据库为:drop table/database 名字
对于表结构操作:都要table这个词和对应的表名
主要的语句:alter table 表名 add/modify/change/drop
对于数据操作:增删改查
insert into 表名 (列) values(v1,v2...)
delete from 表名 where 条件
update 表名 set 列=值,...
select * from 表名 where //// select 列n,列m from 表名 where 条件
四、as与distinct关键字
1.as给字段起别名
select 字段1 as 1,字段2 as 2 from 表名
2.as给表起别名
-- 表名.字段名 select students.id,students.name,students.gender from students; -- 可以通过 as 给表起别名 select s.id,s.name,s.gender from students as s; 这里是单表查询是可以省略表名,这里只是举个例子,应用在这里是没有什么意义的 但是我们做关联表查询的时候,就必须要给表起别名了。
3.distinct关键字
distinct可以取出重复的数据行
运用的意义:这里通过取出重复的数据行,我们可以知道数据的种类,例如20部手机的品牌有几个,这样方便我们的统计与应用
select distinct name,gender from students;(这里的运用意义不大,展示语法)
五、where条件查询
where语句支持的运算符:
比较运算符
逻辑运算符
模糊查询
范围查询
空判断
一、比较运算符
等于: =
大于: >
大于等于: >=
小于: <
小于等于: <=
不等于: != 或 <>
二、逻辑运算符
and
or
not
案例:select * from 表名 where 条件1 and/or/not 条件2
多个条件判断想要作为一个整体,可以结合‘()’。
案例:select * from 表名 where not (age >= 10 and age <= 15);
三、模糊查询
like是模糊查询关键字
%表示任意多个任意字符
_表示一个任意字符
案例:select * from 表名 where name like '晋%' or name like '%杰' or name like '晋_'
四、范围查询
between .. and .. 表示在一个连续的范围内查询
in 表示在一个非连续的范围内查询
案例 :查询编号不是3至8的男生:
select * from students where (not id between 3 and 8) and gender='男';
五、空判断查询
判断为空使用: is null
判断非空使用: is not null
六、排序
排序查询语法:
select * from 表名 order by 列1 asc|desc [,列2 asc|desc,...]
语法说明:
先按照列1进行排序,如果列1的值相同时,则按照 列2 排序,以此类推
asc从小到大排列,即升序
desc从大到小排序,即降序
默认按照列值从小到大排序(即asc关键字)
七、分页查询
1.分页查询的语法
select * from 表名 limit start ,count
说明:
limit是分页查询关键字
start表示开始行索引,默认是0
count表示查询条数
案例:查询前三行男生信息:
select * from students where gender=1 limit 0,3;
简写:
select * from students where gender=1 limit 3;
分页查询特殊案例:
查询学生表,获取第n页数据(每页m个数据)
select * from students limit (n-1)*m,m
分析:
因为这里每页有m条数据所以第n页的开始索引就是(n-1)*m
八、聚合函数:
简介:聚合函数又叫组函数,通常是对表中的数据进行统计和计算,一般结合分组(group by)来使用,用于统计和计算分组数据
一、常用的聚合函数
count(col): 表示求指定列的总行数
max(col): 表示求指定列的最大值
min(col): 表示求指定列的最小值
sum(col): 表示求指定列的和
avg(col): 表示求指定列的平均值
特殊情况:
count:
返回这个字段非null数据的总行数:
select count(某个字段) from 表名 ;
返回总行数,包含null值记录
select count(*) from 表名;
avg:
--求男生的平均身高,聚合函数不统计null的值,所以会出错
例:select avg(height) from 表名 where gender = 1;
--求男生的平均身高,包含身高是null的
例:select avg( ifnull ( height ) ) from 表名 where gender = 1;
ifnull函数:表示判断指定字段的值是否为null ,如果为空使用自己提供的值
聚合函数的特点:
聚合函数是默认会忽略字段为null的记录,要想列值为null的记录也参与计算,必须使用ifnull函数对null值做替换
聚合函数里面必须填写参数:count(*),count(字段)
九、分组查询
简介:分组查询就是将查询结果按照字段进行分组,字段中数据相等的分为一组
语法:group by 列名 having 条件表达式 with rollup
说名:
列名:就是按照指定字段的值进行分组
having :条件表达式:用来过滤分组后的数据
with rollup:在所有记录的最后加上一条记录,显示select查询时聚合函数的统计和计算结果
例如:
一、group by 的使用
group by可用于单个字段分组,也可以用于多个字段的分组
select 字段1,字段2 from students group by 字段1,字段2;
二、group by + group_concat()的使用
group_concat(字段名): 统计每个分组指定字段的信息集合,每个信息之间使用逗号进行分割
select gender ,group_concat(name) from students group by gender;
三、group by + 聚合函数的使用
--统计不同性别的人的平均年龄
select gender,avg(age) from students group by gender;
--统计不同性别的人个数
select gender,count(*) from students group by gender;
四、group by + having 的使用
having的作用和where类似都是过滤数据的,但having时过滤分组数据的,所以只能用于group by
--根据gender字段进行分组,统计分组条数大于2的
select gender,count( * ) from students group by gender having count( * ) > 2;
五、group by + with rollup的使用
with rollup的作用是:在所有记录的最后增加一行,显示select查询时聚合函数的统计和计算结果
--根据gender字段进行分组,汇总总人数
select gender,count(*) from students group by gender with rollup;
--根据gender字段进行分组,汇总所有人的年龄
select gender,group_concat(age) from students group by gender with rollup;
十、连接查询
简介:实现多表查询,当查询的字段来自不同的表就可以使用连接查询来完成
连接查询主要分为:
1、内连接查询:
--查询两个表中符合条件的共有记录=
select 字段 from 表1 inner join 表2 on 表1.字段1 = 表2.字段2
案例:使用内连接查询学生表与班级表
select * from students s inner join classes c on s.cls_id = c.id;
说明:
inner join 就是内连接查询关键字
on 就是连接查询条件
2、左连接查询 ==> 右连接查询
--以左表为主根据条件查询右表数据,如果根据条件查询右表的数据不存在使用null值填充
select 字段 from 表1 left join 表2 on 表1.字段1 = 表2.字段2
说明:
左连接使用的时left join .. on
左连接以左表为主根据条件查询右表数据,右表数据不存在使用null值填充
3、自连接查询
自连接查询就是把一张表模拟成左右两张表,然后进行连表查询。
自连接就是一种特殊的连接方式,连接的表还是本身这张表
案例:查询安徽省下面的市的ID,title和安徽省的ID及title
select c.id,c.title,p.id,p.title from areas c inner join areas p on c.pid = p.id and p.title='安徽省' ;
案例:查询合肥市下面的所有县城信息
select * from areas c inner join areas p on c.pid = p.id and p.title='合肥市';
十一、子查询
在一个select语句中,嵌入了另外一个select语句,那么嵌入的select语句被称之为子查询语句,外部那个select语句则成为主查询
主查询和子查询的关系:
子查询是嵌入到主查询中
子查询是辅助主查询的,要么充当条件,要么充当数据源
子查询是可以独立存在的语句,是一条完整的 select 语句
案例:
1、查询大于平均年龄的学生
select * from students where age > (select avg(age) from students);
2、查询学生在班的所有班级名字(这里需要注意我们的逻辑删除不能为空)
select name from classes where id in(select id from students where cls_id is not null);
3、查找年龄最大同时身高最高的学生可能为空
select * from students where (age, height) = (select max(age), max(height) from students);
十二、数据库设计之三范式
1、原子性:强调列的原子性(最小单位不可再分)
2、有主键,非主键字段完全依赖主键(不能部分依赖)
3、非主键字段不能相互依赖(不能传递依赖)
E-R模型的介绍:
E-R模型即实体关系模型,描述数据库存储数据的结构模型,存在一对一,一对多,多对多关系
十三、外键SQL语句的编写
外键约束:对外键字段的值进行更新和插入时会和引用表中字段的数据进行验证,数据如果不合法则更新和插入会失败,保证数据的有效性
一、对于已经存在的字段添加外键约束
alter table students add constraint fk_cls_id foreign key(cls_id) references classes(id);
简写:
alter table students add foreign key(cls_id) references classes(id);
二、在创建数据表时设置外键约束
-- 创建学校表 create table school( id int not null primary key auto_increment, name varchar(10) ); -- 创建老师表 create table teacher( id int not null primary key auto_increment, name varchar(10), s_id int not null, foreign key(s_id) references school(id) );
三、删除外键约束
注意:
先要获取外键约束的名称,不是指我们设置的那个外键的字段名字
案例:show create table students;
获取名称之后根据名称来删除外键约束
alter table students drop foreign key fk_cls_id;
说明:如果我们一开始在建立外键的时候设置了
constraint fk_cls_id (指定我们的外键名称)
这就表示我们的外键约束的名称,就不用再先查看名称再删除了
练习:
查询类型cate_name为 '超级本' 的商品名称、价格
select name,price from goods where cate_name = '超级本';
显示商品的分类
select cate_name from goods group by cate_name;
求所有电脑产品的平均价格,并且保留两位小数
select round(avg(price),2) as avg_price from goods;
显示每种商品的平均价格
select cate_name,avg(price) from goods group by cate_name;
查询每种类型的商品中 最贵、最便宜、平均价、数量
select cate_name,max(price),min(price),avg(price),count(*) from goods group by cate_name;
查询所有价格大于平均价格的商品,并且按价格降序排序
select id,name,price from goods where price > (select round(avg(price),2) as avg_price from goods) order by price desc;
十四、将查询结果插入到其他表中
--查询goods表中商品的分类信息
select cate_name from goods group by cate_name;
--将查询结果插入到good_cates表中
insert into good_cates(name) select cate_name from goods group by cate_name;
将查询的结果放入goods_cates表中的name字段,首先得先建立一个含有name字段的goods_cates表
说明:
insert into .. select .. 表示: 把查询结果插入到指定表中,也就是表复制。
十四、使用连接更新表中的某个字段
--查看goods表中的商品分类名称对应的商品分类ID
select * from goods as g inner join good_cates as c on g.cate_name = c.name; #这里的on与where是通用的,建议用on
--将goods表中的分类名称改成商品分类表中对应的id
update goods g inner join good_cates c on g.cate_name = c.name set g.cate_name = c.id; #update (虚拟表) set 需要改造的字段 #这里就是将goods表中的cate_name字段的文字替换成good_cates中的id
连接更新表中数据使用: update .. join ..on 语句
十五、创建表并给某个字段添加数据
一、创建品牌表
--查询品牌信息
select brand_name from goods group by brand_name;
--通过create table ... select 来创建数据表并且同时插入数据
--创建商品分类表,注意:需要对brand_name 用as起别名并且与我们创建的字段名字一直,否则name字段就没有值
create table good_brands ( id int unsigned primary key auto_increment, name varchar(40) not null ) select brand_name as name from goods group by brand_name; #create table .. select 列名 .. 表示创建表并插入数据
二、更新goods表中的品牌信息
--将goods表中的品牌名称更改成品牌表good_brands中对应的品牌ID
update goods g inner join good_brands gb on g.brand_name = gb.name set g.brand_name = gb.id;
三、修改goods表结构
--查看表结构
desc goods;
--通过alter table 语句修改表结构
alter table goods change cate_name cate_id int not null ,change brand_name brand_id int not null;
十六、事务
事务的四大特征ACID:
原子性(Atomicity)
一致性(Consistency)
隔离性(Isolation)
持久性(Durability)
--查看数据库的存储引擎
show engines;
说明:
通过创表语句可以得知,goods表的存储引擎是InnoDB。
修改表的存储引擎使用: alter table 表名 engine = 引擎类型;
比如: alter table students engine = 'MyISAM';
开启事务:
begin 或者 start transaction
提交事务:commit
回滚事务:rollback
set autocommit = 0 表示取消自动提交事务模式,需要手动执行commit完成事务的提交
(待补充)
十七、索引
介绍:索引也叫做键,能够加快数据库的查询速度。当我们的数据量很大的时候,可以通过索引来提高数据库的查询速度。
查看表中已有的索引:
show index from 表名;
一、创建索引:
--创建索引的语法格式
alter table 表名 add index 索引名【可选】(列名,...)
--给name字段添加索引 my_name就是我们给这个索引起的索引名。后面是对应的字段。
alter table classes add index my_name (name)
二、删除索引
--删除索引的语法格式
alter table 表名 drop index 索引名
这里的索引名可以通过查看创建表的sql语句去看或者查看已有的索引列表
show create table classes ;show index from 表名;
alter table classes drop index my_name;
三、联合索引
联合索引又叫复合索引,即一个索引覆盖表中俩个或多个字段,一般用在多个字段一起查询的时候
-- 创建teacher表 create table teacher ( id int not null primary key auto_increment, name varchar(10), age int ); -- 创建联合索引 alter table teacher add index (name,age);
联合索引的好处:
--减少磁盘空间开销,因为每创建一个索引,其实就是创建一个索引文件,那么会增加磁盘空间的开销。
联合索引的最左原则:
就是在查询的过程中,遵循一个最左原则,就上面的例子index(name,age)支持name和(name+age)这两中查询,而不单独支持age查询,因为没用到创建的联合索引。
案例:
-- 下面的查询使用到了联合索引 select * from stu where name='张三' -- 这里使用了联合索引的name部分 select * from stu where name='李四' and age=10 -- 这里完整的使用联合索引,包括 name 和 age 部分 -- 下面的查询没有使用到联合索引 select * from stu where age=10 -- 因为联合索引里面没有这个组合,只有 name | name age 这两种组合
四、MySQL中索引的优点和缺点和使用原则
优点:
加快数据的查询速度
缺点:
创建索引会消耗时间和占用的磁盘空间,并随着数据量的增加所消耗的时间也会增加。
使用原则:
通过优缺点对比,不是索引越多越好,而是需要自己合理的使用。
对经常更新的表就避免对其进行过多索引的创建,对经常用于查询的字段应该创建索引,
数据量小的表最好不要使用索引,因为由于数据较少,可能查询全部数据花费的时间比遍历索引的时间还要短,索引就可能不会产生优化效果。
在一字段上相同值比较多不要建立索引,比如在学生表的"性别"字段上只有男,女两个不同值。相反的,在一个字段上不同值较多可是建立索引。
个人笔记整理(2)