12月4周报

多表查询的两种方法

  • 连表操作
# 就是将你想要用到的表连接在一起,形成一个大表,然后用这个大表查询你想要的数据

笛卡儿积
select * from emp,dep; # 会将所有的数据全部对应一边
select * from emp,dep where emp.dep_id=dep.id; # 这个就是将数据对应起来把表连接到一起

'''
笛卡尔积底层效率太低 连接的表越多就会出现冗长的数据 远离了我们的初衷 我们只需要把想要的数据连接在一起拿到想要的表数据就可以了
'''
# 内连接(知连接两张表中公有的数据部分)
inner join

# 左连接(以左表为基准 展示左表所有的数据 如果没有对应项则用NULL填充)
left join

# 右连接(以右表为基准 展示右表所有的数据 如果没有对应项则用NULL填充)
right join

# 全连接(以左右表为基准 展示所有数据 各自没有的全部NULL填充)
union

'''
学会了连表操作之后也就可以连接N多张表
	思路:将连接之后的表起别名当成一张表再去与其他表拼接 再起别名当一张表 再去与其他表拼接 其次往复即可
'''
  • 子查询
子查询类似于我们日常生活中解决问题的方式>>>:分步操作
将一条SQL语句用括号括起来当成另外一条SQL语句的查询条件

'''
很多时候表查询需要结合实际情况判断用哪种 更多时候甚至是相互配合使用
'''

小知识点补充说明

1.concat
# concat用于分组之前的字段拼接操作
2.concat_ws
# concat_ws拼接多个字段并且中间的连接符一致
3.exists
# SQL语句1 where exists (SQL语句2);
SQL语句2有结果才会执行SQL语句1 否则不执行SQL语句1 返回空数据

可视化软件Navicat

Navicat可以充当很多数据库软件的客户端 提供了图形化界面能够让我们更加快速的操作数据库

多表查询思路

'''
编写复杂的SQL不要想着一口气写完
	一定先明确思路 然后一步步写一步步查一步步补
'''

SQL注入问题

怪像1:输对用户名就可以登陆成功
怪像2:不需要对的用户名和密码也可以成功
    
这两个现象的出现是因为SQL注入:
    利用特殊符号符合组合产生特殊的含义 从而避开正常的业务逻辑
    
针对上述的SQL注入问题 核心在于手动拼接了关键数据
解决SQL注入问题也很简单 就是想办法过滤掉特殊符号
# execute 方法自带校验SQL注入的问题,自动处理特殊符号
# 交给execute处理即可

视图

视图就是通过查询得到一张虚拟表 然后保存下来下次直接使用
# 为什么要用试图
如果频繁使用一张虚拟表 可以不用重复查询
# 如何用试图
create view 视图名 as sql语句
1.视图虽然看似好用 但是会造成表的混乱,因为视图不是真正的数据源
2.视图只能用于数据的查询 不能做增、删、改的操作 可能会影响原始数据(视图里面的数据是直接来源于原始表 而不是拷贝一份)

触发器

# 触发器的概念
	在对表数据进行增、删、改的具体操作下,自动触发的功能
    
# 触发器作用 
	专门针对表数据的操作,定制个性化配套功能
    
# 触发器种类
	表数据新增之前、新增之后
    表数据修改之前、修改之后
    表数据删除之前、删除之后
    
# 触发器创建
create trigger 触发器名字 before\after insert\update\delete on 表名 for each row
begin
	SQL语句
end

# 触发器名字
一般采用下列形式
tri_after_insert_t1  给表t1增加之后触发
tri_after_update_t2  给表t2修改之后触发
tri_after_delete_t3  给表t3删除数据之后

# 临时修改SQL语句的结束符
	因为有些操作中需要使用分号

事务

# 事务的概念
	事务可以包含诸多SQL语句并且这些SQL语句
    要么同时执行成功、要么执行失败、这是事务的原子特性
    
# 事务的四大特性
事务的四大特性(ACID)
A:原子性
    一个事务是一个不可分割的整体,里面的操作要么都成立要么都不成立
C:一致性
    事务必须使数据库从一个一致性状态变到另外一个一致性 状态
I:隔离性
    并发编程中,多个事务之间是相互隔离的,不会彼此干扰
D:持久性
    事务一旦提交,产生的结果应该是永久性的,不可逆的
在SQL标准中定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改
InnoDB支持所有隔离级别
	set transaction isolation level 级别
1.read uncommitted(未提交读)事务中的修改即使没有提交,对其他事务也都是可见的,事务可以读取未提交的数据,这一现象也称之为"脏读"
2.read committed(提交读)
	大多数数据库系统默认的隔离级别
  一个事务从开始直到提交之前所作的任何修改对其他事务都是不可见的,这种级别也叫做"不可重复读"
3.repeatable read(可重复读)		# MySQL默认隔离级别
	能够解决"脏读"问题,但是无法解决"幻读"
  所谓幻读指的是当某个事务在读取某个范围内的记录时另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录会产生幻行,InnoDB和XtraDB通过多版本并发控制(MVCC)及间隙锁策略解决该问题
4.serializable(可串行读)
	强制事务串行执行,很少使用该级别

存储过程

可以看成是python中的自定义函数

# 无参函数
delimiter $$
create procedure p1()
begin
	select * from cmd;
end $$
delimiter ;

# 调用
call p1()


# 有参函数
delimiter $$
create procedure p2(
    in m int,  # in表示这个参数必须只能是传入不能被返回出去
    in n int,  
    out res int  # out表示这个参数可以被返回出去,还有一个inout表示即可以传入也可以被返回出去
)
begin
    select * from cmd where id > m and id < n;
    set res=0;  # 用来标志存储过程是否执行
end $$
delimiter ;

# 针对res需要先提前定义
set @res=10;  定义
select @res;  查看
call p1(1,5,@res)  调用
select @res  查看

"""
查看存储过程具体信息
	show create procedure pro1;
查看所有存储过程
	show procedure status;
删除存储过程
	drop procedure pro1;
"""

函数

可以看成是python中的内置函数

"ps:可以通过help 函数名    查看帮助信息!"
# 1.移除指定字符
Trim、LTrim、RTrim

# 2.大小写转换
Lower、Upper

# 3.获取左右起始指定个数字符
Left、Right

# 4.返回读音相似值(对英文效果)
Soundex

# 5.日期格式:date_format
'''在MySQL中表示时间格式尽量采用2022-11-11形式'''
CREATE TABLE blog (
    id INT PRIMARY KEY auto_increment,
    NAME CHAR (32),
    sub_time datetime
);

# 更多日期处理相关函数 
	adddate	增加一个日期 
	addtime	增加一个时间
	datediff计算两个日期差值

流程控制

# 分支结构
declare i int default 0;
IF i = 1 THEN
	SELECT 1;
ELSEIF i = 2 THEN
	SELECT 2;
ELSE
	SELECT 7;
END IF;

# 循环结构
DECLARE num INT ;
SET num = 0 ;
WHILE num < 10 DO
	SELECT num ;
	SET num = num + 1 ;
END WHILE ;

索引结构相关概念

索引就好比一本书的目录 它能让你更快的找到自己想要的内容
让获取的数据更有目的性 从而提高数据库检索数据的性能

索引在MySQL种也叫做"键",是存储引擎用于快速找到记录的一种数据结构
	* primary key
    * unique key
    * index key
1.上述的三个key都可以加快数据查询
2.primary key和unique key除了可以加快查询本身还自带限制条件而index key很单一就是用来加快数据查询
3.外键不属于索引键的范围 是用来建立关系的 与加快查询无关

索引加快查询的本质
	id int primary key auto_increment,
 	name varchar(32) unique,
  	province varchar(32)
 	age int
 	phone bigint
 	
	select name from userinfo where phone=18818888888;  # 一页页的翻
	select name from userinfo where id=99999;  # 按照目录确定页数找

索引可以加快数据查询 但是会降低增删的速度
通常情况下我们频繁使用某些字段查询数据
	为了提升查询的速度可以将该字段建立索引
  • 聚集索引
聚集索引(primary key)
	主键、主键索引
    
聚集索引是将主键与行记录存储在一起,当根据主键进行查询时,可直接在表中获取到数据,不用回表查询。InnonDB的所有的表都是索引组织表,主键与数据存放在一起。InnoDB选择聚集索引遵循以下原则:

在创建表时,如果指定了主键,则将其作为聚集索引。
如果没有指定主键,则选择第一个NOT NULL(非空)的唯一索引作为聚集索引。
如果没有唯一索引,则内部会产生一个6字节的rowID(主键值)作为主键
  • 辅助索引
辅助索引(unique,index)
	除主键意外的都是辅助索引
    查询数据的时候不可能都是用id作为筛选条件,也可能会用name,password等字段信息,那么这个时候就无法利用到聚集索引的加速查询效果。就需要给其他字段建立索引,这些索引就叫辅助索引

'''
  叶子结点存放的是辅助索引字段对应的那条记录的主键的值(比如:按照name字段创建索引,那么叶子节点存放的是:{name对应的值:name所在的那条记录的主键值})
数据查找 如果一开始使用的是辅助索引 那么还需要使用聚焦索引才可以获取到真实数据
  '''
  • 覆盖索引
只在辅助索引的叶子节点中就已经找到了所有我们想要的数据
	select name from user where name='gavin';
非覆盖索引:虽然查询的时候命中了索引字段name,但是要查的是age字段,所以还需要利用主键才去查找
	select age from user where name='gavin';

索引数据结构

索引底层其实是树结构>>>:树是计算机底层的数据结构
 
树有很多中类型
	二叉树、b树、b+树、B*树......

二叉树
	二叉树里面还可以细分成很多领域 我们简单的了解即可 
  	二叉意味着每个节点最大只能分两个子节点
B树
	所有的节点都可以存放完整的数据
B+\*树
	只有叶子节点才会存放真正的数据 其他节点只存放索引数据
 	B+叶子节点增加了指向其他叶子节点的指针
  	B*叶子节点和枝节点都有指向其他节点的指针

辅助索引在查询数据的时候最会还是需要借助于聚集索引
	辅助索引叶子节点存放的是数据的主键值

有时候就算采用索引字段查询数据 也可能不会走索引!!!
	最好能记三个左右的特殊情况

慢查询优化

explain

1)index		尽量避免
2)range		
3)ref
4)eq_ref
5)const
6)system
7)null

测试索引

准备

#1. 准备表
create table s1(
id int,
name varchar(20),
gender char(6),
email varchar(50)
);

#2. 创建存储过程,实现批量插入记录
delimiter $$ #声明存储过程的结束符号为$$
create procedure auto_insert1()
BEGIN
    declare i int default 1;
    while(i<3000000)do
        insert into s1 values(i,'jason','male',concat('jason',i,'@oldboy'));
        set i=i+1;
    end while;
END$$ #$$结束
delimiter ; #重新声明分号为结束符号

#3. 查看存储过程
show create procedure auto_insert1\G 

#4. 调用存储过程
call auto_insert1();
# 表没有任何索引的情况下
select * from s1 where id=30000;
# 避免打印带来的时间损耗
select count(id) from s1 where id = 30000;
select count(id) from s1 where id = 1;

# 给id做一个主键
alter table s1 add primary key(id);  # 速度很慢

select count(id) from s1 where id = 1;  # 速度相较于未建索引之前两者差着数量级
select count(id) from s1 where name = 'jason'  # 速度仍然很慢


"""
范围问题
"""
# 并不是加了索引,以后查询的时候按照这个字段速度就一定快   
select count(id) from s1 where id > 1;  # 速度相较于id = 1慢了很多
select count(id) from s1 where id >1 and id < 3;
select count(id) from s1 where id > 1 and id < 10000;
select count(id) from s1 where id != 3;

alter table s1 drop primary key;  # 删除主键 单独再来研究name字段
select count(id) from s1 where name = 'jason';  # 又慢了

create index idx_name on s1(name);  # 给s1表的name字段创建索引
select count(id) from s1 where name = 'jason'  # 仍然很慢!!!
"""
再来看b+树的原理,数据需要区分度比较高,而我们这张表全是jason,根本无法区分
那这个树其实就建成了“一根棍子”
"""
select count(id) from s1 where name = 'xxx';  
# 这个会很快,我就是一根棍,第一个不匹配直接不需要再往下走了
select count(id) from s1 where name like 'xxx';
select count(id) from s1 where name like 'xxx%';
select count(id) from s1 where name like '%xxx';  # 慢 最左匹配特性

# 区分度低的字段不能建索引
drop index idx_name on s1;

# 给id字段建普通的索引
create index idx_id on s1(id);
select count(id) from s1 where id = 3;  # 快了
select count(id) from s1 where id*12 = 3;  # 慢了  索引的字段一定不要参与计算

drop index idx_id on s1;
select count(id) from s1 where name='jason' and gender = 'male' and id = 3 and email = 'xxx';
# 针对上面这种连续多个and的操作,mysql会从左到右先找区分度比较高的索引字段,先将整体范围降下来再去比较其他条件
create index idx_name on s1(name);
select count(id) from s1 where name='jason' and gender = 'male' and id = 3 and email = 'xxx';  # 并没有加速

drop index idx_name on s1;
# 给name,gender这种区分度不高的字段加上索引并不难加快查询速度

create index idx_id on s1(id);
select count(id) from s1 where name='jason' and gender = 'male' and id = 3 and email = 'xxx';  # 快了  先通过id已经讲数据快速锁定成了一条了
select count(id) from s1 where name='jason' and gender = 'male' and id > 3 and email = 'xxx';  # 慢了  基于id查出来的数据仍然很多,然后还要去比较其他字段

drop index idx_id on s1

create index idx_email on s1(email);
select count(id) from s1 where name='jason' and gender = 'male' and id > 3 and email = 'xxx';  # 快 通过email字段一剑封喉 

联合索引

select count(id) from s1 where name='jason' and gender = 'male' and id > 3 and email = 'xxx';  
# 如果上述四个字段区分度都很高,那给谁建都能加速查询
# 给email加然而不用email字段
select count(id) from s1 where name='jason' and gender = 'male' and id > 3; 
# 给name加然而不用name字段
select count(id) from s1 where gender = 'male' and id > 3; 
# 给gender加然而不用gender字段
select count(id) from s1 where id > 3; 

# 带来的问题是所有的字段都建了索引然而都没有用到,还需要花费四次建立的时间
create index idx_all on s1(email,name,gender,id);  # 最左匹配原则,区分度高的往左放
select count(id) from s1 where name='jason' and gender = 'male' and id > 3 and email = 'xxx';  # 速度变快

慢查询日志

设定一个时间检测所有超出该时间的sql语句,然后针对性的进行优化!

全文检索

MySQL的全文检索功能MYISAM存储引擎支持而InnoDB存储引擎不支持
一般在创建表的时候启用全文检索功能
create table t1(
	id int primary key auto_increment,
  content text
	fulltext(content)
)engine=MyISAM;

# match括号内的值必须是fulltext括号中定义的(单个或者多个)
select content from t1 where match(content) against('jason')
'''上述语句可以用like实现但是查询出来的结果顺序不同 全文检索会以文本匹配的良好程度排序数据再返回效果更佳'''

# 查询扩展
select note_text from productnotes where Math(note_text) Against('jason' with query expansion);
"""
返回除jason外以及其他jason所在行相关文本内容行数据
eg:
	jason is handsome and cool,every one want to be cool,tony want to be more handsome;
	二三句虽然没有jason关键字 但是含有jason所在行的cool和handsome
"""

# 布尔文本搜索
即使没有定义fulltext也可以使用,但是这种方式非常缓慢性能低下
select note_text from productnotes where Match(note_text) Against('jason' in boolean mode);

# 注意事项
1.三个及三个以下字符的词视为短词,全文检索直接忽略且从索引中排除
2.MySQL自身自带一个非用词列表,表内词默认均被忽略(可以修改该列表)
3.出现频率高于50%的词自动作为非用词忽略,该规则不适用于布尔搜索
4.针对待搜索的文本内容不能少于三行,否则检索不返回任何结果
5.单引号默认忽略

插入数据

数据库经常被多个用户访问,insert操作可能会很耗时(特别是有很多索引需要更新的时候)而且还可能降低等待处理的select语句性能
如果数据检索是最重要的(一般都是),则可以通过在insert与into之间添加关键字low_priority指示MySQL降低insert语句优先级
	insert low_priority  into 
  
insert还可以将一条select语句的结果插入表中即数据导入:insert select
eg:想从custnew表中合并数据到customers表中
  insert into customers(contact,email) select contact,email from custnew;

更新数据

如果使用update语句更新多列值,并且在更新这些列中的一列或者多列出现一个错误会导致整个update操作被取消,如果想发生错误也能继续执行没有错误的更新操作可以采用
	update ignore custmoers ...
  """
  update ignore  set name='jason1',id='a' where id=1;
  	name字段正常修改
  update set name='jason2',id='h' where id=1;
  	全部更新失败
  """

删除数据

delete语句从表中删除数据,甚至可以是所有数据但是不会删除表本身
并且如果想从表中删除所有的行不要使用delete可以使用truncate速度更快并且会重置主键值(实际是删除原来的表并重新创建一个表而不是逐行删除表中的数据)

主键

查看当前表主键自增到的值(表当前主键值减一)
	select last_insert_id();

外键

MySQL存储引擎可以混用,但是外键不能跨引擎即使用一个引擎的表不能引用具有使用不同引擎表的外键

重命名表

rename关键字可以修改一个或者多个表名
	rename table customer1 to customer2;
  rename table back_cust to b_cust,
  						 back_cust1 to b_cust1,
   						 back_cust2 to b_cust2;

事务扩展

MySQL提供两种事务型存储引擎InnoDB和NDB cluster及第三方XtraDB、PBXT

事务处理中有几个关键词汇会反复出现
  事务(transaction)
  回退(rollback)
  提交(commit)
  保留点(savepoint)
		为了支持回退部分事务处理,必须能在事务处理块中合适的位置放置占位符,这样如果需要回退可以回退到某个占位符(保留点)
    创建占位符可以使用savepoint
    	savepoint sp01;
    回退到占位符地址
    	rollback to sp01;
    # 保留点在执行rollback或者commit之后自动释放

安全管理

1.创建用户
	create user 用户名 identified by '密码';
 	"""修改密码"""
  	set password for 用户名 = Password('新密码');
    set password = Password('新密码');  # 针对当前登录用户
2.重命名
	rename user 新用户名 to 旧用户名; 
3.删除用户
	drop user 用户名;
4.查看用户访问权限
	show grants for 用户名;
5.授予访问权限
	grant select on db1.* to 用户名;
  # 授予用户对db1数据库下所有表使用select权限
6.撤销权限
	revoke select on db1.* from 用户名;
"""
整个服务器
	grant all/revoke all
整个数据库
	on db.*
特定的表
	on db.t1
"""

隔离级别

在SQL标准中定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改
InnoDB支持所有隔离级别
	set transaction isolation level 级别

1.read uncommitted(未提交读)
	事务中的修改即使没有提交,对其他事务也都是可见的,事务可以读取未提交的数据,这一现象也称之为"脏读"
2.read committed(提交读)
	大多数数据库系统默认的隔离级别
  一个事务从开始直到提交之前所作的任何修改对其他事务都是不可见的,这种级别也叫做"不可重复读"
3.repeatable read(可重复读)		# MySQL默认隔离级别
	能够解决"脏读"问题,但是无法解决"幻读"
  所谓幻读指的是当某个事务在读取某个范围内的记录时另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录会产生幻行,InnoDB和XtraDB通过多版本并发控制(MVCC)及间隙锁策略解决该问题
4.serializable(可串行读)
	强制事务串行执行,很少使用该级别

读锁(共享锁)
	多个用户同一时刻可以同时读取同一个资源互不干扰
写锁(排他锁)
	一个写锁会阻塞其他的写锁和读锁
死锁
  1.多个事务试图以不同的顺序锁定资源时就可能会产生死锁
  2.多个事务同时锁定同一个资源时也会产生死锁
	# Innodb通过将持有最少行级排他锁的事务回滚

事务日志

事务日志可以帮助提高事务的效率 
	存储引擎在修改表的数据时只需要修改其内存拷贝再把该修改记录到持久在硬盘上的事务日志中,而不用每次都将修改的数据本身持久到磁盘
  事务日志采用的是追加方式因此写日志操作是磁盘上一小块区域内的顺序IO而不像随机IO需要次哦按的多个地方移动磁头所以采用事务日志的方式相对来说要快的多
  事务日志持久之后内存中被修改的数据再后台可以慢慢刷回磁盘,目前大多数存储引擎都是这样实现的,通常称之为"预写式日志"修改数据需要写两次磁盘

MVCC多版本控制

MVCC只能在read committed(提交读)、repeatable read(可重复读)两种隔离级别下工作,其他两个不兼容(read uncommitted:总是读取最新  serializable:所有的行都加锁)

InnoDB的MVCC通过在每行记录后面保存两个隐藏的列来实现MVCC
	一个列保存了行的创建时间
  一个列保存了行的过期时间(或删除时间)  # 本质是系统版本号
每开始一个新的事务版本号都会自动递增,事务开始时刻的系统版本号会作为事务的版本号用来和查询到的每行记录版本号进行比较

例如
刚插入第一条数据的时候,我们默认事务id为1,实际是这样存储的
    username		create_version		delete_version
    jason				  1					
可以看到,我们在content列插入了kobe这条数据,在create_version这列存储了1,1是这次插入操作的事务id。
然后我们将jason修改为jason01,实际存储是这样的
    username		create_version		delete_version
    jason		          1				      2
    jason01				  2
可以看到,update的时候,会先将之前的数据delete_version标记为当前新的事务id,也就是2,然后将新数据写入,将新数据的create_version标记为新的事务id
当我们删除数据的时候,实际存储是这样的
	username		create_version		delete_version
    jason01				 2				      3
"""
由此当我们查询一条记录的时候,只有满足以下两个条件的记录才会被显示出来:
   1.当前事务id要大于或者等于当前行的create_version值,这表示在事务开始前这行数据已经存在了。
   2.当前事务id要小于delete_version值,这表示在事务开始之后这行记录才被删除。
"""

转换表的引擎

主要有三种方式,并各有优缺点!
# 1.alter table
	alter table t1 engine=InnoDB;
  """
  	适用于任何存储引擎 但是需要执行很长时间 MySQL会按行将数据从原表赋值到一张新的表中,在复制期间可能会消耗系统所有的IO能力,同时原表会加读锁
  """
# 2.导入导出
	"""
	使用mysqldump工具将数据导出到文件,然后修改文件中相应的SQL语句
		1.引擎选项
		2.表名
	""" 	
# 3.insert ... select
	"""
	综合了第一种方案的高效和第二种方案的安全
		1.先创建一张新的表
		2.利用insert ... select语法导数据
	数据量不大这样做非常合适 数据量大可以考虑分批处理 针对每一段数据执行事务提交操作避免产生过多的undo
	"""
  ps:上述操作可以使用pt-online-schema-change(基于facebook的在线schema变更技术)工具,简单方便的执行上述过程

前端与后端的概念

前端
	任何与用户直接打交道的操作界面 都可以称之为前端>>>:接待员
后端
	不直接与用户打交道 主要负责内部真正的业务逻辑的执行>>>:幕后操作者
        
前端三剑客
	HTML			网页的骨架
    CSS				网页的样式
    JavaScript  	网页的动态
    
# 比喻说明
  HTML:网页的骨架
    	刚出生的新生儿,啥也没穿
    CSS:网页的样式
    	长了肉,穿上小衣服,变好看了
    JavaScript:网页的动态效果
         学会走和跳,开始活动起来    

HTTP简介

# 哪些可以充当客户端
1.自己写的python代码(TCP客户端)
2.浏览器
"""
CS架构和BS结构:BS本质上也是CS
"""

# 问题
我们自己写的TCP服务端与浏览器之间通信了,但是浏览器没有识别
# 无法访问此网站127.0.0.1 拒绝了我们的连接请求

# 推导
不同的服务端数据的组织策略不一样 但是浏览器又要做到统一处理
所以最佳的解决措施就是制定一个标准:HTTP协议
    
# HTTP协议
规定了服务端和浏览器之间的数据交互格式以及其他事项

HTTP协议

# 四大特性
	1.基于请求响应
    	客户端发送请求 服务端回应响应
    2.基于TCP、IP作用于应用层之上的协议
    	该协议属于应用层
    3.无状态
    	服务端不会保存客户端的状态
    4.无\短连接
    	客户端与服务端不会长久保持连接
        
# 数据模式
请求格式:客户端给服务端发送消息应该遵循的数据格式
    1.请求首行(请求方法、协议版本)
    2.请求头(k:v形式)
    3.换行(不能省略)
    4.请求体(存放敏感信息 并不是所有的请求方式都有请求体)
    
响应格式:服务端给客户端发送消息应该遵循的数据格式
    1.响应首行(响应状态码,协议版本)
    2.响应头(k:v形式)
    3.换行(不能省略)
    4.请求体(让浏览器展示给)
    
# 响应状态码
	用数字来表达一些文字意义(类似于暗号)
    1xx:服务端已经接收到了你的请求正在处理 客户端可以继续发送或者等待
    2xx:200 OK 请求成功 服务端发送了对应的响应
    3xx:302(临时) 304(永久) 重定向(想访问网页A但是自动调整到网页B)
    4xx:403访问权限不够   404(请求资源不存在)
    5xx:服务端内部错误
    # 在公司中我们还会自定义更多的响应状态码 通常以10000起步
    eg:聚合数据

HTML简介

1.直接发送手写的数据
2.转为发送文件里面的数据
3.编写HTML出现特殊的现象

超文本标记语言:所见即所得(没有任何逻辑 是什么就是什么)

HTML概览

1.HTML注释语法
   <!--注释内容--!>
    
2.HTML文档结构
   <html>    固定格式 html包裹
       <head>主要放跟浏览器交互的配置</head>
       <body>主要放给用户查看的内容</body>
    </html>
    
3.HTML标签分类
	1.双标签
        <h1></h1>
    2.自闭合标签:单标签
        <img/> 一般有特殊功能   

预备知识

1.网页信息数据一般也会存放于文件中
	.htlm
2.pycharm支持前端所有类型的文件编写
    内置有自动补全的功能 我们只需要专注于标签名的编写即可
3.html文件的打开
	内置有自动调用浏览器的功能

head内常见标签

1.title网页小标题

2.meta定义网页员信息(很多配置)
<meta name="keywords" content="查询关键字">
<meta name="description" content="网页简介">

3.style内部支持编写css代码

4.link引入外部css文件

5.script支持内部编写js代码也可以引入外部js文件

body内基本标签

1.标题系列标签
	h1~h6
    
2.段落标签
	p
    
3.其他标签
	u 下划线
    i 斜体
    s 删除线
    b 加粗
 
4.换行与分割线
	br 换行
    hr 分割线
    
"""
标签的分类
	行内标签 u i s b
		内部文本多大就占多大
	块儿级标签 h系列 p
		独占一行
"""

常见符号

1.&nbsp; 空格

2.&gt; 大于

3.&lt; 小于
    
4.&amp; &符

5.&yen; ¥

6.&copy; © (版权)

7.&reg;		® (注册)

body内部布局标签

div
	块儿级标签
span
	行内标签
    
"""
标签之间可以相互嵌套 并且理论上可以无限套娃
	块儿级标签内部可以嵌套块儿级标签和行内标签
		p标签虽然是块儿级标签 但是它的内部也不能嵌套块儿级标签
	行内标签内部只能嵌套行内标签
"""

body内常用标签

"""
标签括号内填写的 什么=什么 称之为的标签的属性
	1.默认属性
		标签自带的 编写的时候有自动提示
	2.自定义属性
		用户自定义 编写不会有提示甚至会飘颜色
"""
a标签    链接标签
	href
    1.填写网址		       具备跳转功能
    2.填写其他标签的id值     具备锚点功能

'''
target
	默认_self原网页跳转
	_blank新建网页跳转
'''

img标签   图片标签
	src
    1.填写图片地址
    title
    鼠标悬浮在图片上自动展示文本信息
    alt
    图片加载失败提示的信息
    width\height
    图片的尺寸 两者调整一个即可 等比例缩放

列表标签

无序列表
<ul>
	<li></li>
</ul>

有序列表
<ol type='1'>
	<li></li>
</ol>

标题列表
<dl>
	<dt>大标题</dt>
    <dd>小标题</dd>
</dl>

表格标签

1.先写基本骨架
    <table>
        <thead></thead>
        <tbody></tbody>
    </table>
    
2.再写表头及表单数据
    <table>
        <thead>
        <tr> # 一个tr标签就表示一行
            <th>编号</th> # th主要用于表头字段中 用来加粗显示
            <th>姓名</th>
            <th>年龄</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <td>1</td>
            <td>jason</td>
            <td>18</td>
        </tr>
        </tbody>
    </table>

表单标签

可以获取到用户的数据并发送给服务端

form标签
	action	控制数据的提交地址
  	method	控制数据的提交方法

    
input标签(类似于前端的变形金刚)
	type属性
       text					    普通文本
       password					密文展示
   	   date						日期选项
       email		 			邮箱格式
       radio					单选
       checkbox					多选
       file						文件
       file(multiple)			上传多文件
    
    
       submit					触发提交动作
    	reset					重置表单内容
       button					暂无任何功能

    
select标签	下拉框
select(multiple) 多选
option标签	一个个选项
  

textarea标签	获取大段文本

input标签应该有name属性
	name属性相当于字典的键 input标签获取到的用户数据相当于字典的值
	点击发送就会组织成字典的形式发送给服务端 这样才具有明确意义

CSS层叠样式表

主要用来调节html标签的各种样式

标签的两大重要属性>>>:区分标签
	1.class属性
		分门别类 主要用于批量查找
	2.id属性
		精确查找 主要用于点对点
        
# css语法结构
	选择器{
        样式名1:样式值1;
        样式名2:样式值2
    }
    
# css注释语法
	/*注释内容*/
    
# 引入css的多种方式
1.head内style标签内部编写(学习时使用)
 <style>
        h1{
            color: pink;
        }
</style>
 
2.head内link标签引入外部css文件(标准方式)
	<link rel="stylesheet" href="mycss.css">

3.标签内部通过style属性直接编写(不推荐)
	也称之为'行内式', 不推荐使用 因为这样会增加耦合度

#css是用来调整HTML标签样式的
	同一个页面上有很多相同的标签 但需要不同的样式  

CSS选择器

1.标签选择器
 直接按标签名查找标签  
	<style>
        h1 {color:pink; 
        /*让所有h1标签内部所有的字体颜色变为粉色*/}
    </style>
    
2.类选择器(范围内查找)
  通过标签的class属性查找标签(关键字加句点符)
    <style>
    	.c1 {
            color:pink;
          }
    </style>

3.id选择器(精确查找)
  通过标签的id属性查找标签
         #d1 {
            color:pink;
          }
<h1 id='d1'>守得云开见月明</h1>

4.通过选择器
  直接选择页面所有的标签
          * {
             color:pink;
          }

CSS组合选择器

关系网
针对标签的上下层以及嵌套有另外的说法
	父标签 后代标签 子标签 弟弟标签 哥哥标签 祖宗标签
    
后代选择器(空格)
儿子选择器(大于)
毗邻选择器(加号)
弟弟选择器(小波浪号)

分组与嵌套

多个选择器合并查找
div,p,span{  
       color:blue;
}

混合使用
#d1,c1,span{
      color:blue;
}

查找class含有c1的div
div.c1{
    color:blue;
}

查找id是d1的div
div#d1{
    color:blue;
}

查找含有c1样式值里面的含有c2样式值的p标签
.c1 p.c2{
    color:antiquewhite;  
}

属性选择器

按照属性名查找
[username]{
    color:red;
}

属性名是username并且值是jason的标签
[username='jason']{
    color:red;
}

属性名是username并且值是jason的div标签
div[username='jason']{
    color:red;
}

伪类选择器

"""a标签补充说明 针对没有点击过的网址 默认是蓝色 点击过后为紫色"""
# 鼠标悬浮——鼠标移动到p标签上方 字体颜色修改为选定颜色
	 a:hover {
            color: orange;
        }

# input获取焦点(被点击)之后采用的样式
# 鼠标选中之后,选中框变成指定的颜色
input:focus {  
			  background-color: red;	
    }

伪元素选择器

1.修改首个字体样式(first-letter)
<p>守得云开见月明 静待花开终有时</p>

p:first-letter {
            color:pink;  /* 修改字体的颜色*/
            font-size: 40px;  /* 修改字体的尺寸为40像素*/
        }

2.在文本开头增加内容(before)
 p:before {  
            content:'lalala';  /* 增加的内容 */
            color:green;
            }

3、在文本末尾增加内容(after)
  p:after { 
            content: 'wuhu';  /* 增加的内容 */
            color: blue;
            }

选择器优先级

1.选择器相同 导入方式不同
	就近原则
2.选择器不同 导入方式相同
	内联样式 > id选择器 > 类选择器 > 标签选择器

CSS文字样式

# 文字字体
  (更改字体font-family)
p {
   font-family: 华文楷体;
}

# 字体大小(font-size)
p {
    font-size: 25px;
   }

# 字体粗细(font-weight)
font-weight: lighter;  /*变细*/
font-weight: bolder;  /*加粗*/
    
# 字体颜色
方式一:
 p {
     color: brown;
    }  

方式二:
  p {
     color:rgb(128, 0, 128);
    }  

# 通过光学三原色红绿蓝调配, 范围(0~255)
rgba()最后一个参数还可以控制透明度 0~1
方式三:
    p {
    color:#bd961a;
        }  
# 根据色卡自己找颜色
"""
  1、微信、QQ自带的截图功能内有提取颜色的功能
  2、pycharm提供的取色器
"""

CSS文字属性

# 文字对齐
text-align: center;  /*居中*/
text-align: left;  /*左对齐*/
text-align: right;  /*右对齐*/
   
# 文字装饰(重点)
"""
 a标签默认带下划线, 并且还有颜色(没有点击时为蓝色, 点击之后为紫色)
"""
 /* 去除下面的线*/
text-decoration: none;

/* 删除线 */
text-decoration: line-through;

/* 上边线 */
text-decoration: overline;

/* 下边线 */
text-decoration: underline;

# 首行缩进
/* 首行缩进 */
text-indent: 20px;

"""
 可以使用浏览器做样式的动态调整
  查找标签的css, 然后左键选中,通过方向键上下动态修改数值
"""

CSS背景属性

# 背景颜色 (background-color)
    background-color: black;
   
# 背景图片
background-image:url("图片地址");
background-repeat: no-repeat; 不填充
background-repeat: repeat-x;  横向填充
background-repeat: repeat-y;  纵向填充

# 图片位置设置
background-position: center center; 居中
background-position: top;  朝上  
background-position: bottom; 最下
left 左, right 右 

# 控制背景附着
background-attachment: fixed;  背景附着
    
"""
 当多个属性名具有相同的后缀,我们就可以整合在一起, 写一个前缀名就可以
 background: black url('1.png') no-repeat center center;
"""

CSS边框

# 自定义边框的边
border-left/top/right/bottom-color:black; 边框的颜色
border-left/top/right/bottom-width:5px; 边框的距离
border-left/top/right/bottom-style:solid; 边框的呈现形式,实线、虚线等
'''
solid		实线边框
dotted		点状虚线边框
dashed		矩形虚线边框
'''

#统一调整一条边的边框
border-left: 3px solid black;

    
# 统一调整每个边的边框
# 直接控制四个边框的形式
border: 10px solid black;
    
# 画圆
border-radius:50%

display属性

"""
行内标签是无法设置长宽 只有块儿级可以设置
"""
display:none  彻彻底底的隐藏标签(页面上不会显示 也不会保留标签的位置)
    
visibility:hidden  隐藏的不彻底

盒子模型

我们可以将标签看成一个盒子(快递盒)

1.快递包里面的实际物体          content(内容)
2.物体与内部盒子墙的距离        padding(内边距、内填充)
3.快递盒的厚度                border(边框)
4.快递盒之间的距离             margin(外边框)

# body标签默认自带8px的margin值 写网页的时候要改掉
margin-top:0;     上
margin-right:0;   右
margin-bottom:0;  下
margin-left:0;    左
# 简写
margin: 20px; 上下左右
margin: 20px 40px; 上下  左右
margin: 10px 20px 30px; 上  左右  下
margin: 10px 20px 30px 40px; 上 下 左 右
    
# margin和padding用法一致

针对标签的嵌套 水平方向可以居中
margin:0 auto;

img

浮动

# 浮动就是用来做页面布局的
浮动的现象
	float:left\right;
   
# 浮动带来的影响
	浮动的元素是脱离正常文档流的 会造成父标签塌陷

# 如何解决浮动的影响
	clear
clear: left;  规定元素左边不允许其他元素浮动
clear: right;  规定元素右边不允许其他元素浮动
 
# 解决浮动带来的影响终极方法
	先提前写好样式类
    	.clearfix:after {
            content: '';
            display: block;
            clear: both;
        }
	谁塌陷了 就给谁添加clearfix样式类就可以了
 
ps:浏览器会优先展示文本内容(如果被挡住)

溢出

# 当文本内容超出了标签了最大范围
 overflow:hidden; ———— 直接隐藏多出来的文本内容
 overflow:auto; ————— 提供滚轮条查看(滚轮条较宽)
 overflow:scroll; ————— 提供滚轮条查看(滚轮条较窄)
    
# 头像实操
 div {
            height: 150px;
            width: 150px;
            border: 5px solid white;
            border-radius: 50%;
            overflow: hidden;
        }
div img {
            max-width: 100%;
        }

定位

# 标签在默认情况下都是无法通过定位的参数来移动

# 针对定位有四种状态
1.静态       static 
标签默认的状态 无法定位移动

2.相对定位    relative
基于标签原来的位置

3.绝对定位    absolute
基于某个定位过的父标签做定位

4.固定定位    fixed
基于浏览器窗口固定不动

# 定位操作
position (后面跟定位属性单词)
left\right\top\bottom(上下左右设置参数)
绝对定位
  当没有父标签或者父标签没有定位时,则以body为准,相当于变成了相对定位
    
固定定位
  右下方回到底部
   position: fixed;
   right: 0;
   bottom: 50px;

z-index属性

"""
  前端的页面可以看成三维坐标系, Z轴指向用户
"""
动态弹出的分层界面, 我们称之为模态框
# 调整颜色透明度
rgba(128,128,128,0.5) 
最后一个参数就是透明度的度数
body {
            margin: 0;
        }
.cover {
            background-color: rgba(127,127,127,0.5);
            position: fixed;
            left: 0;
            bottom: 0;
            right: 0;
            top: 0;
            z-index: 100;
        }
.modal {
            height: 200px;
            width: 400px;
            background-color: white;
            z-index: 101;
            position: fixed;
            left: 50%;
            top: 50%;
            margin-left: -200px;
            margin-top: -100px;
        }

简易博客页面搭建

1.分析页面结构
	利用布局标签div和span搭建架子
2.先编写网页骨架
	HTML
3.再编写CSS
4.最后编写JS

image-20221203170826173

HTML界面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>blogs</title>
    <link rel="stylesheet" href="blogs.css">
</head>
<body>
    <div class="blog-left">
        <div class="blog-avatar">
            <img src="111.jpg" alt="">
        </div>
        <div class="blog-title">
            <span>super小赵的博客</span>
        </div>
        <div class="blog-info">
            <span>书中借我大义 天地还我春秋</span>
        </div>
        <div class="blog-link">
            <ul>
                <li><a href="">关于我</a></li>
                <li><a href="">微信号公众号</a></li>
                <li><a href="">微博</a></li>
            </ul>
        </div>
        <div class="blog-course">
            <ul>
                <li><a href="">#Python</a></li>
                <li><a href="">#Golang</a></li>
                <li><a href="">#JavaScript</a></li>
            </ul>
        </div>
    </div>
    <div class="blog-right">
        <div class="article-list">
            <div class="article-title">
                <span class="title">雕刻和打磨自身的重要性</span>
                <span class="date">2022-12-2</span>
            </div>
            <div class="article-desc">
                <span>道阻且长 行则将至 坚持运动保持身材 心静则生智 心乱则生愚</span>
            </div>
            <div class="article-end">
                <span>#修身养性</span>
                <span>#德才兼备</span>
            </div>
        </div>
    </div>
</body>
</html>

CSS界面

/*这是博客园首页的样式表*/

/*页面通用设置*/
/* 给页面添加颜色*/
body {
    margin: 0;
    background-color: #eeeeee;
}
/* a标签去取下划线*/
a {
    text-decoration: none;
}
/* 列表修改,去取小圆点和页面距离为0*/
ul {
    list-style-type: none;
    padding-left: 0;
}

/*首页左侧样式*/
/* 比例调整*/
.blog-left {
    float: left;
    width: 20%;
    height: 100%;
    background-color:black;
    position: fixed;
    left: 0;
    top: 0;
}
/* 头像框*/
.blog-avatar {
    border: 6px solid rgb(54,54,40);
    height: 200px;
    width: 200px;
    border-radius: 50%;
    margin: 20px auto;
    overflow: hidden;
}
.blog-avatar img{
    max-width: 100%;
}
/* 修改简介*/
.blog-title , .blog-info  {
    color: white;
    text-align: center;
    margin: 10px auto;
    font-weight: bolder;
}
.blog-link,.blog-course{
    text-align: center;
    margin: 60px auto;
}
.blog-link ul>li,.blog-course ul>li{
    padding: 5px;
}
.blog-link a,.blog-course a{
    color: white;
    font-size: 24px;
}
.blog-link a:hover,.blog-course a:hover{
    color: rebeccapurple;
}


/*首页右侧样式*/
/* 比例调整*/
.blog-right {
    float: right;
    width: 80%;
    height: 100%;
}

.article-list {
    background-color: white;
    margin: 20px 50px 20px 20px;
    box-shadow: 20px 20px 20px rgba(0,0,0,0.8);
}

.article-list .article-title .title {
    font-size: 36px;
    font-weight: bolder;
    border-left:8px solid orange;
}

.article-list .article-title .date {
    font-size: 18px;
    font-weight: bolder;
    float: right;
    margin: 15px 15px;
}

.article-desc {
    font-size: 24px;
    font-weight: lighter;
    text-indent: 10px;
    border-bottom: 2px solid black;
}

.article-end{
    padding:10px 10px 10px 20px;
    font-weight: bolder;
}

.article-end span:hover{
    color: rebeccapurple;
}
posted @ 2022-12-04 21:20  Super小赵  阅读(19)  评论(0编辑  收藏  举报
****************************************** 页脚Html代码 ******************************************