Karen


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 搜索

mysql数据库CRUD

发表于 2018-08-07

mysql数据库CRUD

本文从基础开始介绍mysql数据库的增删改查等基础知识

下载安装mysql数据库

启动服务

  1. services.msg

  2. 管理——>服务——>启动mysql

  3. cmd——>net start mysql

  4. 偏好设置——>run(Mac)

####停止服务

  1. net stop mysql
  2. net restart mysql(重启)
    注:以管理员身份运行
    如果要卸载,需要用installer卸载,否则将会有残余以后无法再次下载使用mysql

启动客户端工具:
在安装社区版mysql后会自动帮我们安装一个mysql的客户端,进入的方式有两种:
mysql -u root -p 进入本机数据库(注意配置路径)
或者从开始菜单进入
showdatabases; 查看所有数据库(自带4个数据库,mysql程序相关的元数据信息,mysql自己要用的)
select version();查看目前使用的版本
? 获取帮助
quit/exit 退出

####SQL(Structured Query Language)
我们这里使用navicat for mysql可视化工具学习sql,sql语言是不区分大小写的

  • DDL(数据定义语言): create/ drop/ alter
  • DML(数据操纵语言): insert/ delete/ update
  • DQL(数据查询语言): select
  • DCL(数据控制语言): grant/ revoke/ begin/ commit/ rollback

####数据定义语言

#####如果指定的数据库存在则删除
drop database if exists XXX;

#####创建数据库并指定默认字符集
create database XXX default charset utf8;

#####切换到XXX数据库
use XXX;

#####关系型数据库通过二维表来创建

######创建学生表,定义字段

######主键(primary key)-能够标识唯一一条记录的列

1
2
3
4
5
6
7
8
9
create table tb_student
(
stuid int not null comment '学号',
sname varchar(10) not null comment '姓名',
ssex bit default 1,
stel char(11),
sbirth date,
primary key(stuid)
);

键的类型:int, varchar, bit……
非空约束:not null
默认值约束:default
备注:comment
指定字符集:charset utf8
指定排序规则:collation utf8_bin (如果没有指定会默认)
自增长的字段:int … auto_increment

字段的三大类数据类型:
数值型(包括整数小数)
字符串
时间日期型

为表指定存储引擎,指定字符集:
看到表的结构:desc tb_student

#####修改表
插入新的字段
alter table tb_student add columu asddr varchar(100);
删除字段
alter table tb_student drop columu stel;

#####插入记录
一次插入一条学生纪录
insert into tb_student values(1001, ‘小白’, 1, ‘1999-3-08’, ‘北京’);
选择性插入学生纪录,指定顺序
insert into tb_student (sname, stuid) values (‘小红’, 1002)
批量插入学生纪录
insert into tb_student values
(1001, ‘小童’, 0, ‘1995-7-02’, ‘江苏南京’),
(1002, ‘小灰灰’, 1, ‘1989-3-23’, ‘上海’),
(1003, ‘小白’, 1, ‘1997-8-30’,’湖南长沙’),
(1004, ‘小花’, 0, ‘1995-7-08’, ‘江苏南京’),
(1005, ‘小江’, 1, ‘1989-3-23’, ‘上海’),
(1006, ‘小飞’, 1, ‘1997-8-30’,’湖南长沙’);

#####删除数据
删除全表(一般不会使用)
delete from tb_student;
删除某一条记录
delete from tb_student where stuid=1003;

#####更新数据
没有加条件,全表所有人的生日和住址都会被改变
update tb_student set sbirth=’1999-2-03’, saddr=’四川成都’;
更新某一条数据(通常情况下更新和删除单条数据都是以主键作为条件)
update tb_student set sbirth=’1999-2-03’, saddr=’四川成都’ where stuid=1002;

在sql中一个=是相等的意思,如果想要赋值前面加set

批量更新数据

  • 使用or连接
1
update tb_student set saddr='统一地址' where stuid=1004 or stuid=1005 or stuid=1006;
  • 使用集合
1
update tb_student set addr='统一地址' where stuid in (1004, 1005, 1006);

例子1:

创建课程表和学生表

创建数据库

1
create database student default charset utf8;

创建课程表

1
2
3
4
5
6
7
create table tb_course
(
courseid int not null,
cname varchar(20) not null,
ccredit int not null,
primary key (courseid)
);

插入数据

1
2
3
4
5
insert into tb_course(courseid, cname, ccredit) values 
(001, 'python程序设计', 3),
(002, 'java', 2),
(003, 'linux操作系统', 1),
(004, '数据库基础', 1);

记录学生选课记录,还需要一张学生选课记录表(中间表)

分析学生表和课程表之间的关系,ER图(实体关系图)

ER图

专业的数据库建模工具:PowerDesigner

外键约束

创建一对一的人员表和身份证表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
create table tb_person
(
personid int not null auto_increment,
pname varchar (20) not null,
pbirth date,
primary key (personid)
);

create table tb_idcard
(
cardid char(18) not null,
cpolice varchar(20) not null,
cexpire date not null,
pid int not null,
primary key (cardid)
);

alter table tb_idcard add constraint fk_idcard_pid foreign key (pid) references tb_person (personid);

pid 只能参照人员表的主键personid,表示二者的一对一关系

fk_idcard_pid:表示foreignkey在idcard这张表中的pid字段

外键:一个外来的主键

参照完整性

录入数据

1
2
3
4
5
6
7
8
9
insert into tb_person (pname, pbirth) values
('小飞飞', '1992-09-01'),
('小可爱', '1992-10-01'),
('小红花'. '1982-09-01');

insert into tb_idcard values
('847584848373728323', '成都市武侯区公安局','2019-09-30', 1),
('818181818282738374', '成都市金牛区公安局','2022-09-30', 2),
('818184848373827283', '成都市锦江区公安局','2033-01-09', 3);

外键参照另一张表,有完整性约束,必须参照另一张表的主键,没有的主键也不能添加外键

建立一对一的关联关系

唯一性约束

1
alter table tb_idcard add constraint uk_idcard_pid unique(pid);

外键对应的记录不能重复添加,且有且仅有关联到另一张表的另一个唯一的主键,一对一的关联关系完成

如果没有唯一性约束就是一对多的关联关系了

且建立外键关系后,如需删除被参照的记录,需要先删除参照的记录行

外键列是加到多的那一边的

建立多对多的关联关系

建立第三张中间表,将两张表链起来

1
2
3
4
5
6
7
8
create table tb_sc
(
scid int not null auto_increment comment '专门作为主键的自增字段',
sid int not null comment '学号',
cid int not null comment '课程编号',
score float,
primary key (scid)
);

关系型数据库中也可以使用复合主键,primary key (sid, cid),或者用sid,cid,和选课时间三个键作为复合主键。但是实际开发中,不会用这样的主键,因为不可重复操作,可能导致麻烦很多,且影响你的表的范式级别。

建立关系
1
2
3
4
alter table tb_sc add constraint fk_sc_sid 
foreign key (sid) references tb_student (stuid);
alter table tb_sc add constraint fk_sc_cid
foreign key (cid) REFERENCES tb_course (courseid);
插入数据
1
2
3
4
5
6
7
insert into tb_sc (sid, cid, score) values
(1001, 001, 89),
(1002, 003, 90),
(1003, 001, 100),
(1004, 004, 97),
(1005, 002, 65),
(1006, 001, 80);

通过这张中间表,学生和课程的多对多关系就建立起来了。

例子2

用户订单对应表

1
2
3
4
5
6
7
8
create table tb_user
(
username varchar(20) not null,
userpass varchar(20) not null,
nickname varchar(50) not null,
email varchar(255),
primary key(username)
);

如果关键字作为字段名称,可以加上反引号,就可以建立起来的

1
2
3
4
5
6
7
8
9
10
11
create table tb_order
(
orderid char(12) not null,
makedata datetime not null,
userid varchar(20) not null
);

alter table tb_order add primary key (orderid);
alter table tb_order add constraint fk_order_userid
foreign key (userid) references tb_user (username)
on delete restrict;

级联删除:删除用户时将所属订单全部删除

删除的几种情况:

cascade:级联删除

restrict:默认的情况,不让删除(一般都是这样设置)

set null:当删除用户时,订单中的用户id设置为空(加了非空约束,不成立)

删除基本不会用,只是标志为不可用了

及联更新:

允许修改的键不会设置为主键,可以修改的用户名不会设置为主键。

1
on updata cascade # 一般不用

一对多的数据关系:

插入数据:

1
2
3
4
5
6
7
insert into tb_user (username, userpass, nickname) values
('xiaohua', '123123', 'huahua'),
('xiaobai', '123456', 'abai');
insert into tb_order values
('112233445566', now(), 'xiaohua'),
('112233445567', now(), 'xiaobai'),
('112233445568', now(), 'xiaohua');

now()方法是mysql独有的,取到系统时间日期其他数据库没有

例子3:

多对多的读者管理系统

在可视化工具中建立,查看sql预览

建读者表:

1
2
3
4
5
6
7
8
create table tb_reader
(
readerid int not null auto_increment,
rname varchar(20) not null,
rtel char (11) not null,
remail varchar(255),
primary key (readerid)
);

只有主键能够自增

建书籍表:

可视化建表

同等对应的sql语句为:

1
2
3
4
5
6
7
8
9
create table tb_book 
(
bookid int not null,
bname varchar(50) not null,
bauthor varchar(255) not null,
bpublisher varchar(255) not null,
bpubdate date not null,
primary key (bookid)
);

建立外键(举个栗子)

可视化建立外键

同等sql语句为:

1
2
3
alter table tb_book add constraint fk_book_author foreign key (bauthor)  references tb_user(username) 
on delete cascade
on update cascade;

sql预览如图所示:

image-20180827204209018

外键约束如上

中间表:图书借阅记录表(表示多对多关系)
1
2
3
4
5
6
7
8
9
create table tb_borrow_record
(
recid int not null auto_increment,
rid int not null,
bid int not null,
borrowdate datetime not null,
returndate datetime,
primary key (recid)
);
建立外键约束
1
2
3
alter table tb_borrow_record add constraint fk_borrow_record_rid foreign key (rid) references tb_reader (readerid);
alter table tb_record add CONSTRAINT fk_record_bid
FOREIGN key (bid) references tb_book (bookid);

强制性要求还书日期大于借书日期

建立检查约束:保证数据的有效性(域完整性)
1
2
alter table tb_record add constraint ck_record_returndate 
check (returndate > borrowdate);

​ 写了没有报错,但是没有用。在MySQL中,和SQLite不生效(外键约束也米有用)。但是在oracle和db2和SQLserver等中支持

​ 在商业级应用中应该在程序里加这个检查,不是留给数据库检查

网络爬虫1--http协议和urllib

发表于 2018-08-07

爬虫初步

爬虫概念

都有哪些语言可以实现爬虫

​ (1)php, 号称世界上最好的语言,可以实现爬虫,但做的不好,天生对多进程和多线程支持的不好

​ (2)java,可以实现,而且做的非常好,是python爬虫最主要的竞争对手, 但语言不简洁,代码臃肿,重构成本高
(3)c、c++,也可以实现爬虫,非常强大,但是不是一个好的选择
(4)python,可以实现,号称世界上最优雅的语言,代码简洁,学习成本低,执行效率也好,而且还有一个非常强大的爬虫框架 scrapy

通用爬虫

​ 例子:百度、谷歌、360、搜狗、必应等等,搜索引擎

​ 工作:
(1)爬取互联网所有的数据
(2)对数据存储并且处理
(3)给用户提供检索服务
如何让百度抓取你的网站?
(1)静静地等待,百度会和DNS服务商合作
(2)主动提交自己的url
(3)在其它网站设置友情链接
我的网站不想让百度抓取?
君子协议,口头协议,robots协议
存放到网站的根目录下,限制搜索引擎可以爬取哪些,不可以爬取哪些

##### 如何提升网站排名(SEO)

​ (1)pagerank值排名,根据点击量、浏览量等,相当靠谱

​ (2)竞价排名

##### 通用爬虫缺点:

​ (1)抓取很多数据都是无效的

​ (2)不能根据自己的需求抓取数据

聚焦爬虫

​ 根据自己特定的需求,来抓取指定的数据

​ 如何实现聚焦爬虫?
网页的特点:
(1)网页都有自己唯一的url
(2)网页都是由html组成
(3)网页传输都是使用http、https协议

思路:

​ (1)给一个url

​ (2)模拟浏览器发送http请求
(3)从html结构中提取指定的数据,从字符串中根据规则提取指定数据

开发环境:

​ windows系统,python3.x(64位),sublime编辑器,pycharm,vscode

整体内容:

​ (1)涉及到的python库

​ urllib,requests,selenium,jsonpath,lxml等一些库
(2)解析内容
正则表达式解析,bs4解析,xpath解析,jsonpath解析
(3)采集动态html
DOM操作,动态的添加或者删除节点,selenium+phantomjs
(4)scrapy框架
异步高性能网络爬虫框架的学习
(5)scrapy-redis分布式部署
在scrapy的基础上,多了一套分布式部署的组件
(6)涉及到的爬虫-反爬虫-反反爬虫之间的斗争
反爬会伤害真实的用户,一般情况下,反爬也就这么两点:第一个UA,第二个封ip,第三个验证码,光学识别,打码平台
换思路解决问题:其他网站,手机端等

关于http协议

http和https的区别

​ HTTPS和HTTP的区别主要如下:
  1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
  2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
  3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
  4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

加密:公钥私钥

​ 客户端:123456用秘钥加密=======》服务端:用秘钥解密得到123456
秘钥相同称之为对称加解密
秘钥不相同称之为非对称加解密
客户端:123456用公钥加密=======》服务端:用私钥解密得到123456
http协议学习:

请求:包含请求行、请求头、请求内容

请求行:请求方式、请求资源、协议版本号

请求头:

  • accept:浏览器通过这个头告诉服务器,它所支持的数据类型

  • Accept-Charset: 浏览器通过这个头告诉服务器,它支持哪种字符集

  • Accept-Encoding:浏览器通过这个头告诉服务器,支持的压缩格式

  • Accept-Language:浏览器通过这个头告诉服务器,它的语言环境

  • Host:浏览器通过这个头告诉服务器,想访问哪台主机
    If-Modified-Since: 浏览器通过这个头告诉服务器,缓存数据的时间  

  • Referer:浏览器通过这个头告诉服务器,客户机是哪个页面来的 防盗链

  • Connection:浏览器通过这个头告诉服务器,请求完后是断开链接还是何持链接

  • X-Requested-With: XMLHttpRequest 代表是ajax的请求

    响应:响应行、响应头、响应内容

响应行里面,常见的状态码
  • 200:请求成功 处理方式:获得响应的内容,进行处理

  • 301:请求到的资源都会分配一个永久的URL,这样就可以在将来通过该URL来访问此资源 处理方式:重定向到分配的URL

  • 302:请求到的资源在一个不同的URL处临时保存 处理方式:重定向到临时的URL

  • 304:请求的资源未更新 处理方式:丢弃,使用本地缓存文件

  • 403:禁止 处理方式:丢弃

  • 404:没有找到 处理方式:丢弃

  • 405:请求方式不对

  • 500:服务器内部错误 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。

响应头

Location: 服务器通过这个头,来告诉浏览器跳到哪里

  • Server:服务器通过这个头,告诉浏览器服务器的型号

  • Content-Encoding:服务器通过这个头,告诉浏览器,数据的压缩格式

  • Content-Length: 服务器通过这个头,告诉浏览器回送数据的长度

  • Content-Language: 服务器通过这个头,告诉浏览器语言环境

  • Content-Type:服务器通过这个头,告诉浏览器回送数据的类型

  • Refresh:服务器通过这个头,告诉浏览器定时刷新

  • Content-Disposition: 服务器通过这个头,告诉浏览器以下载方式打数据

  • Transfer-Encoding:服务器通过这个头,告诉浏览器数据是以分块方式回送的

  • Expires: -1 控制浏览器不要缓存

  • Cache-Control: no-cache

  • Pragma: no-cache

响应内容:html、css、js、图片

抓包工具

(1)谷歌浏览器自带抓包工具
右键开发者工具==》network
XHR: XMLHttpReqeust 前端要想发送ajax请求,通过它创建对象,发送请求
query_string_parameters : 请求字符串,get参数
formdata : 如果是post参数
(2)专业工具,fiddler,charles……
专业抓包工具,比谷歌强在了跳转的时候很多请求都能抓取到
前端要像发送ajax请求,创建对象调用对象方法需要通过XHR

urllib库

​ urllib库是自带的python库,模拟发送http请求
在python 2系列中使用:urllib urllib2
在python 3系列中使用:urllib

urllib库的使用

  1. urllib.request 模拟发送请求

    • urlopen(url) : 向url发送请求,得到响应对象

      1
      2
      3
      4
      5
      6
      7
      import urllib.request
      url = 'http://www.baidu.com/'

      response = urllib.request.urlopen(url)

      print(response)
      print(response.read())

可以看到结果如下:

urllib.request.urlopen-result

  • print(response.read().decode(‘utf8’)):得到了二进制的格式,下一步我们需要使用decode将二进制格式解码为字符串格式

    response属性和方法
  • print(response.url):拿到请求的url

  • print(response.headers):拿到请求的headers

  • print(response.status):拿到请求的状态码

  • urllib.parse: 处理参数或者url

  • urllib.error: 如何处理异常

保存到文件

​ 将抓取的数据保存到文件有两种方式:

第一种方式:通过with打开文件(注意统一编码格式)

  1. 1
    2
    3
    4
    5
    6
    7
    # 将获取的响应内容保存到文件中
    # with open('baidu1.html', 'a', encoding='utf8') as fp:
    # fp.write(response.read().decode('utf8'))

    # 以二进制的格式保存
    # with open('baidu2.html', 'wb') as fp:
    # fp.write(response.read())

第二种方式:直接以二进制的格式写入

1
2
# 实现发送请求,将内容写入文件
# urllib.request.urlretrieve(url, 'baidu3.html')
    • urlretrieve(url, filepath) : 向url发送请求,直接将响应写入到filepath中
  • 编码:

    • 字符串格式==》字节格式

      encode(‘utf8’)

    • 字节格式==》字符串格式

      decode(‘gbk’)

爬取图片的保存

​ 下载图片:得到图片的src属性,就可以将图片下载到本地

​ 有两种方式,主要是对图片是做二进制的处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import urllib.request

url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1533639915215&di=1bbd3901c9991b363ac0211dc861a909&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F225a5f3f75d1d4c59532704782eebd25d323fd801e57a-VlY5c4_fw658'

# 第一种方式,发送请求,获取响应

response = urllib.request.urlopen(url)

with open('meinv.jpg', 'wb') as fp:

fp.write(response.read())

# 第二种方式,

urllib.request.urlretrieve(url, 'meinv2.png')

​

爬虫-url

发表于 2018-07-30

urllib是python内置的HTTP请求库,包含以下4个模块:

  • request:请求模块,模拟发送请求,需要给库方法传入url
  • error:异常处理模块,如果出现错误可以捕获,进行重试或其他操作
  • parse:工具模块,提供给了很多url处理方法,比如拆分,解析,合并等
  • rotbotparser:识别网站的robot.txt文件

urlopen()

请求方法:

response = urllib.request.urlopen(‘https://www.python.org')

未命名

发表于 2018-07-17

NoSQL入门

NoSQL概述

1998年提出,原意是No SQL! 2008年受到重视,因为在2008正式进入Big Data时代。Not Only SQL!互补的关系。

高可用,分区容忍性。

####分类:

  • K-V: 键值对数据库,比如:Redis。以键值对形式保存(存取性能特别好)
  • Document:文档数据库,比如:MongoDB。查找方便,可扩展性强,传统关系型数据库扩容很困难。
  • Graph: 图数据库,网状结构。比如:Neo4j。适合社交性软件,一度二度人脉,类似脉脉。
  • 列簇:列簇数据库,把相关数据放到列里面。比如:HBase.适合分布式存储,数据的规约处理

CAP定理(CAP theorem)http://www.runoob.com/mongodb/nosql.html

在计算机科学中, CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer’s theorem), 它指出对于一个分布式计算系统来说,不可能同时满足以下三点:

  • 一致性(Consistency) (所有节点在同一时间具有相同的数据)
  • 可用性(Availability) (保证每个请求不管成功或者失败都有响应)
  • 分隔容忍(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作)

CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。

因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:

  • CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。

  • CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。

  • AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。

    ​

    传统应用和金融类应用考虑的是CA,互联网和移动互联网时代的应用更注重AP

主流NoSQL数据库

Redis概述

特点:高速缓存,在内存中运行,持久化才保存到硬盘中

内存的读写速率大概是:G赫兹,一秒2-4G DDR:双倍速通道

​ 机械硬盘:一秒 50兆左右

​ 固态硬盘:几百兆

###Redis入门

查看Linux系统中是否有redis服务器和客户端工具:redis-server –version/redis-cli –version

#####修改redis配置文件:

  • ​ bind 172.16.252.192:绑定内网地址

  • ​ port 6379:端口默认是6379(信息隐藏技术)走的是TCP,端口是0-65535

  • ​ tcp-backlog 511:队列大小

  • ​ daemonize no:改成yes的话开机自启,随系统启动。守护进程(不改)

  • ​ logfile “”:日志文件的位置

  • ​ databases 16:默认开启16个数据库

  • ​ save 900 1

    203 save 300 10
    204 save 60 10000:持久化的机制:
    

​ (含义是:In the example below the behaviour will be to save:
190 # after 900 sec (15 min) if at least 1 key changed
191 # after 300 sec (5 min) if at least 10 keys changed
192 # after 60 sec if at least 10000 keys changed
193 #
194 # Note: you can disable saving completely by commenting out all “save” lines. It is also

​ possible to remove all the previously conf igured save

197 #   points by adding a save directive with a single empty      string argument)
  • ​ requirepass 1qaz2wsx:设置密码,可以通过redis控制你的Linux系统

  • ​ maxclients 10000:最大允许10000客户端连接

  • ​ appendonly yes:AOF持久化机制

#####参考命令:

绑的是内网,连的是公网

  • 开启redis:redis-server redis_628.conf
  • 拿到后台运行:bg %1
  • 查看后台应用:jobs
  • 查看进程:ps -ef | grep redis
  • 查看端口是否被占用:netstat -nap | grep redis
  • 连接客户端:redis-cli -h 172.16.252.192
    ​ auth 1qaz2wsx:认证
  • redis设置过期时间:set username karen ex 30
  • ttl username:time to live查看存活时间

    -1:永不超时
    

    -2:查无此键

  • expire username 120:设置超时时间

  • 手动保存:save
  • 后台保存:bgsave
  • 模糊查找:keys *2
  • 恢复你的数据的方法:

    rdb:保存的数据

    aof:记得你的指令(优选),用你敲过的命令来恢复数据

  • 判断有没有这个键:exists foo

    1有,0没有

  • 退出

    ​ quit

    ​ shutdown /save/nosave:关机,默认保存

  • redis值的类型:字符串,哈希表,列表,集合,有序集合

  • redis也有事务,发布订阅

  • redis-benchmark -h 172.16.252.192 :redis 基准测试(相当于跑分软件)

  • Z:暂停,C:停止

实现对数据的高速访问,经常要用的数据放到内存中,使用redis数据库,因为关系型数据库有锁所以越到后面更新越慢

Redis的数据类型

字符串

单个键对应的数据不能超过512兆

  • append:增加
  • strlen:看长度
  • setrange:字符串的替换,把指定的范围改为你想要的内容

​ 120.79.137.184:6379> get name
“wangwang”
120.79.137.184:6379> strlen name
(integer) 8
120.79.137.184:6379> setrange name 5 hellokitty
(integer) 15
120.79.137.184:6379> get name
“wangwhellokitty”

  • incr :增加1
  • incrby number 50:增加50
  • decr:减少1
  • decrby:减少 量
  • getset:拿到之前的并重置建对应的值
哈希表

最好的用来保存对象,以键值对的形式,在字典中又放了字典

  • hset:见名知意
  • hget:同上
  • hgetall:同上
  • hdel:同上
  • hexists:判断字段是否存在
  • hkeys:看所有的
  • hlen:长度
  • hincrby:加字段的值
  • hincrbyfloat:加字段浮点数
  • hvals:拿一个键对应的所有值
列表

模拟栈和队列

队列:左边取,右边放,

栈:先进后出,后进先出,

受限队列:用ltrim

  • lpush:放东西,从左往右放
  • lpop:取东西,从左往右取,元素已经取走了
  • rpush:从右边放
  • rpop:从右边取
  • lrange:从左边往右边取,元素没有取走

​ lrange mylist 2 5:从左往右取2-5

  • lrange mylist3 0 -1:全部取完
  • ltrim:保留,限定只取某一个范围,截取的部分被保留,其他元素已经取走了
集合

元素是没有下标的,自动去重,可以做交并叉运算

元素是离散的,没有序

  • sadd set1 apple orange orange:放元素
  • scard set1:查看键的大小,多少值
  • smembers set1:取出键,无序的
  • sinter set1 set2:查看交集
  • sunion set1 set2:查看并集
  • sdiff set1 set2:求差集

​ set1里面有,set2里面没有的

​ sdiff set2 set1: 2有1没有

  • spop set1:取元素,默认取一个,顺序不一,根据内部生成的码来取,取走了
  • srandmember set2 2 :随机取两个,没取走
  • sismember set2 grape:判断元素是否在集合中
有序集合(Zset)

跟集合比较可以排序,在放元素进入时,绑定score大小决定他的顺序

用在动态排位,动态榜单应用

  • zadd players 100 zhao 85 qian 200 sun 120 lee 180 zhou:放元素
  • zrange players 0 -1:正向排序取出所有
  • zrevrange players 0 -1:反向排序取出所有
  • zrevrange players 0 -1 withscores:分数也会显示
  • zcard players:有多少元素
  • zcount players 150 200:计数,在150到200中的元素有多少个

#####GEO地理位置类型

Redis3加入的新类型

LBS应用:location-based service:基于位置的服务

根据位置算距离有多远,范围内的搜索

  • geoadd:加元素,要加经纬度坐标
  • geopos:坐标
  • georadius:在半径内
  • geodist:算距离

#####事务

  • multi:开启
  • exec:提交
  • discard:回滚

#####线程安全问题:

redis是线程安全的还是不安全的?redis是单线程+多路I/O复用的工作模式,异步io模式,多个读写操作并发的进行,单线程保持安全,支持多线程操作。所以redis和关系型数据库一样都是安全的。

第二类丢失更新,没有保护数据,多线程访问,后面覆盖前面的

线程之间共享数据很容易,但多个进程之间是相互隔离的,多进程中有一个模块,quaue实现多个进程互相通信

多进程可以利用cpu的多核特性

python有??解释器,64.只能用一个核

多线程最重要的两个好处:

​ 第一:改善性能,占用更多的cpu资源,占用cpu更多的时间

​ 第二:改善用户体验,耗时的任务就可以扔到单独的线程或进程中去做

进程和线程是可以设置优先级

python中优化性能的方法:协程,微线程,单线程加异步io

#####选择数据类型:

一般的用字符串(图片,文件……),存对象用哈希表,队列或者栈用列表,去重用set,动态排位用Zset。

####端口映射

公网访问内网:在路由器上做端口映射-请求走到路由器,路由器通过端口决定将对该端口的请求映射到内网哪一台主机上

内网访问公网:NAT地址转换 - 内网地址映射为公网地址(看到的是你的路由器地址)

路由器会话:网络地址转换

python连接redis

使用的是redis-py一个开源项目,位于GitHub

####多台redis服务器,读写分离,主从操作

主从复制,主机写,从机复制

info replication:查看自己的角色

配置文件redis.conf

做为奴隶:

​ slaveof 120.77.222.217 6379:做120.77.222.217的奴隶端口是6379

​ masterauth 1qaz2wsx:master的密码

​ slaveof no one:回到master角色

如果master宕机就启动自动监控程序,哨兵(故障的自动切换)

配置文件:sentinel.conf

​ sentinel monitor mymaster 127.0.0.1 6379 2:监控master,端口,投票数量

​ sentinel auth-pass :哨兵也需要密码

​ sentinel down-after-milliseconds mymaster 30000:缓冲时间为30秒

​ sentinel failover-timeout mymaster 180000:180秒内恢复以前的master回来只能作为奴隶,180秒后就从本主从中剔除(通过修改配置文件)

最好把所有的从机和主机的密码保持一致,避免更新密码

打开防火墙端口

Redis集群
关于集群:多个节点当成一个节点来使用

避免单点故障:将单个节点做成多个节点

负载均衡服务器:配置在节点的前面,eg.轮询算法(RR),哈希码算法(Hash)(比如对5求余数),看负载看连接数(MCC) +Keepalived 双活服务(相当于热备份:如果负载均衡服务器挂了)

负载均衡可以用硬件也可以用软件做,Nginx/LVS不论用哪个都要用双活备份

######redis的集群

先要安装Ruby的编程语言环境

因为redis有一段脚本:redis-trib.rb

MongoDB概述

未命名

发表于 2018-07-17
1
title: 正则表达式总结
语法 解释
\b 是正则表达式规定的一个特殊代码(好吧,某些人叫它元字符,metacharacter),代表着单词的开头或结尾,也就是单词的分界处。虽然通常英文的单词是由空格,标点符号或者换行来分隔的,但是\b并不匹配这些单词分隔字符中的任何一个,它只匹配一个位置。
* 同样是元字符,不过它代表的不是字符,也不是位置,而是数量——它指定*前边的内容可以连续重复使用任意次以使整个表达式得到匹配
.* 连在一起就意味着任意数量的不包含换行的字符
\d 一位数字(0,或1,或2,或……)
0\d{2}-\d{8} \d必须连续重复匹配2次(8次)
\s 任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格等
\w 字母或数字或下划线或汉字等
\d+ 1个或更多连续的数字
* 匹配重复任意次(可能是0次)
+ 则匹配重复1次或更多次
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
{5,12} 则是重复的次数不能少于5次,不能多于12次
^和$ 的意义就变成了匹配行的开始处和结束处
\ 如果你想查找元字符本身的话,来取消这些字符的特殊意义
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
[aeiou] 任何一个英文元音字母
[.?!] 标点符号(.或?或!)
[0-9] 同\d
[a-z0-9A-Z_] 同\w
练习:
(?0\d{2}[) -]?\d{8} 匹配电话
(? 0 \d{2} [) -]? \d{8}
(能出现一次或零次 0 两个数字 )空格- 三选一 8个数字
\ 如果满足其中任意一种规则都应该当成匹配,具体方法是用\ 把不同的规则分隔开
小括号 来指定子表达式(也叫做分组)
例子2:
((2[0-4]\d\ 25[0-5]\ [01]?\d\d?).){3}(2[0-4]\d\ 25[0-5]\ [01]?\d\d?) 匹配ip地址
((2[0-4]\d\ 25[0-5]\ [01]?\d\d?).){3} 分块分析 (2[0-4]\d\ 25[0-5]\ [01]?\d\d?) 第二块
(2[0-4]\d\ 25[0-5]\ [01]?\d\d?) 第一块
2[0-4]\d 2,0-4中的任意一个,任意一个数字
25[0-5] 25,0-5中的任意一个
[01]?\d\d? 01中的任意一个重复零次或一次,任意数字,任意数字重复零次或一次
{3} 以上或者选项重复3次
2[0-4]\d\ 25[0-5]\ [01]?\d\d? 第二块
2[0-4]\d 25[0-5] [01]?\d\d?
2,0-4中的一个,一个任意数字 25,0-5中的任意一个 01中的任意一个重复零次或一次,数字,数字零次或一次
3位 3位 1位或者2位或者3位
IP地址中每个数字都不能大于255 eg: 127.0.0.10 245.245.
245.245
254.245.04.092
深入:
反义: 对比(右侧)
\W 匹配任意不是字母,数字,下划线,汉字的字符 \w 匹配字母或数字或下划线或汉字
\S 匹配任意不是空白符的字符 \s 匹配任意的空白符
\D 匹配任意非数字的字符 \d 匹配数字
\B 匹配不是单词开头或结束的位置 \b 匹配单词的开始或结束
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符 [aeiou] 任何一个英文元音字母
<a[^>]+> 匹配用尖括号括起来的以a开头的字符串
后向引用 用于重复搜索前面某个分组匹配的文本
匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理
默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推
例子:
\b(\w+)\b\s+\1\b 用来匹配重复的单词
\b (\w+) \b \s+
占位符 一个字母数字下划线或汉字 占位符 一个或多个空白符
指定分组的组名
(?\w+) 名字就是word
等同于(?’Word’\w+)
反向引用: \k\
分类 代码/语法 说明
捕获 (exp) 匹配exp,并捕获文本到自动命名的组里
(?\exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?’name’exp)
(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号
零宽断言 (?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(?<!exp) 匹配前面不是exp的位置
注释 (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读
零宽断言 查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言)
零宽度正预测先行断言(?=exp) 断言自身出现的位置的后面能匹配表达式exp
\b\w+(?=ing\b) 匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I’m singing while you’re dancing.时,它会匹配sing和danc
零宽度正回顾后发断言(?<=exp) 断言自身出现的位置的前面能匹配表达式exp
(?<=\bre)\w+\b 会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading
负向零宽断言
贪婪匹配 通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符
懒惰匹配 匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复
因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复
IgnoreCase(忽略大小写) 匹配时不区分大小写。
Multiline(多行模式) 更改^和$的含义,使它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串的开头和结尾匹配。(在此模式下,$的精确含意是:匹配\n之前的位置以及字符串结束前的位置.)
Singleline(单行模式) 更改.的含义,使它与每一个字符匹配(包括换行符\n)。
IgnorePatternWhitespace(忽略空白) 忽略表达式中的非转义空白并启用由#标记的注释。
ExplicitCapture(显式捕获) 仅捕获已被显式命名的组。
平衡组/递归匹配 平衡组语法是由.Net Framework支持的;其它语言/库不一定支持这种功能,或者支持此功能但需要使用不同的语法。

未命名

发表于 2018-07-17

管理后台的制作


建立管理后台的应用
管理后台模型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from django.db import models

class UserModel(models.Model):

username = models.CharField(max_length=32, unique=True) # 名称

password = models.CharField(max_length=256) # 密码

email = models.CharField(max_length=64, unique=True) # 邮箱

# False 代表女

sex = models.BooleanField(default=False) # 性别

icon = models.ImageField(upload_to='icons') # 头像

is_delete = models.BooleanField(default=False) # 是否删除

class Meta:
db_table = 'axf_users'
class UserTicketModel(models.Model):

user = models.ForeignKey(UserModel) # 关联用户

ticket = models.CharField(max_length=256) # 密码

out_time = models.DateTimeField() # 过期时间
class Meta:
db_table = 'axf_users_ticket'
url映射
1
2
3
4
5
6
7
8
9
10
11
12
13
from django.conf.urls import url

from user import views

urlpatterns = [

# 登录
url(r'^login/', views.login, name='login'),
# 注册
url(r'^register/', views.register, name='register'),
# 注销
url(r'^logout/', views.logout, name='logout'),
]
控制器(views)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
from datetime import datetime, timedelta

from django.contrib.auth.hashers import make_password, check_password

from django.http import HttpResponseRedirect

from django.shortcuts import render

from django.core.urlresolvers import reverse

from user.models import UserModel, UserTicketModel

from utils.functions import get_ticket


def register(request):
"""
注册
"""
if request.method == 'GET':

return render(request, 'user/user_register.html')

if request.method == 'POST':

username = request.POST.get('username')
email = request.POST.get('email')
password = request.POST.get('password')
icon = request.FILES.get('icon')
# 需要验证参数都不为空
if not all([username, email, password, icon]):
# 验证不通过,提示参数不能为空,返回页面错误提示
msg = '参数不能为空'
return render(request, 'user/user_register.html', {'msg': msg})
# 加密password
password = make_password(password)
# 创建
UserModel.objects.create(username=username,
password=password,
email=email,
icon=icon
)
return HttpResponseRedirect(reverse('user:login'))


def login(request):
"""
登录
"""
if request.method == 'GET':
return render(request, 'user/user_login.html')

if request.method == 'POST':

username = request.POST.get('username')
password = request.POST.get('password')
# 验证用户是否存在
user = UserModel.objects.filter(username=username).first()
if user:
# 验证密码是否正确
if check_password(password, user.password):
# 1. 保存ticket在客户端
ticket = get_ticket()
response = HttpResponseRedirect(reverse('axf:mine'))
out_time = datetime.now() + timedelta(days=1)
response.set_cookie('ticket', ticket, expires=out_time)
# 2. 保存ticket到服务端的user_ticket表中
UserTicketModel.objects.create(user=user,
out_time=out_time,
ticket=ticket)
return response
else:
msg = '密码错误'
return render(request, 'user/user_login.html', {'msg': msg})
else:
msg = '用户不存在'
return render(request, 'user/user_login.html', {'msg': msg})


def logout(request):
"""
注销
"""
if request.method == 'GET':
# 注销,删除当前登录的用户的cookies中的ticket信息
response = HttpResponseRedirect(reverse('user:login'))
response.delete_cookie('ticket')

return response

未命名

发表于 2018-07-17

关于使用git

git本地

下载并安装git

创建git版本库

  1. 新建空目录
  2. 初始化仓库:git init
  3. 添加到仓库 :git add filename
  4. 将文件提交到仓库: git commit -m “wrote a file”

    commi可以一次提交很多文件,所以你可以多次add不同的文件
    

本地文件修改后提交

  1. 修改文件后查看状态:git status
  2. 查看两个文件的改变:git diff

    要随时掌握工作区的状态,使用git status命令。
    

    如git status告诉你有文件被修改过,用git diff 可以查看修改内容。

版本回退

1.查看提交的历史版本:git log

​ 以一行的方式看(不看详情):git log –pretty=oneline

​ HEAD表示当前版本

​ HEAD^表示上一个版本

​ HEAD^^上上个版本

​ HEAD~100往前一百个版本

2.回退到上一个版本:git reset –hard HEAD^

​ 后悔了,回退到最新的一个版本:git reset –hard 版本号(要自己保存的)

3.如果自己不造:Git提供了一个命令用来记录你的每一次命令:git reflog

​ 让HEAD指向哪个版本号,你就把当前版本定位在哪

工作区和暂存区

  1. 当建立文件后,没添加到暂存区就是untracked

  2. 修改后的文件是Changes not staged for commit

  3. 添加到暂存区后没有交托给分支Changes to be committed

管理修改

查看工作区和版本库里面最新版本的区别:git diff HEAD – filename

每次修改,如果不用git add到暂存区,那就不会加入到commit中。

撤销修改

  1. 丢弃工作区的修改:git checkout -- readme.txt

  2. 命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

    ​ 一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

    ​ 一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

    ​ 总之,就是让这个文件回到最近一次git commit或git add时的状态。

  3. 可以把暂存区的修改撤销掉(unstage),重新放回工作区:git reset HEAD <file>

  4. 除了提交到远程版本库的内容都可以修改

    ​ 场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。

    ​ 场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令 git reset HEAD <file>,就回到了场景1,第二步按场景1操作。

    ​ 场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。

删除文件

  1. 删除工作区的文件:rm filename
  2. 删除版本库中的该文件:git rm filename 并确认:git commit -m “reason”
  3. 从版本库里面恢复:git checkout –filename

远程仓库

  1. 如果本地主目录没有.ssh目录,创建获得ssh公钥和密钥: ssh-keygen -t rsa -C “youremail@example.com“
  2. 在github里添加自己的ssh公钥

添加远程库

  1. Create a new repo

  2. 远程库关联:git remote add origin git@github.com:karen2066/learngit.git

  3. 把本地库的所有内容推送到远程库上:git push -u origin master

    ​ 实际上是把当前分支master推送到远程

  4. 把本地master分支的最新修改推送至GitHub: git push origin 分支名

从远程库克隆

  1. 新建GitHub仓库
  2. 克隆一个本地库: git clone git@github.com:karen2066/gitskills.git
  3. git还听个http协议的地址,但这种方式需要输入口令

分支管理

新建分支:git checkout -b dev

​ 这条命令等于: git branch dev + git checkout dev 两条命令

查看当前分支: git branch

​ 当前分支前面会标一个*号

切换分支:git checkout master

合并分支的工作:git merge dev(dev是分支名称)

​ git merge命令用于合并指定分支到当前分支

删除分支:git branch -d dev

当分支提交冲突时:

​ master上修改,再提交,解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交(再往前提交一个版本相当于就是合并)

查看分支合并的情况:git log

查看分支合并图:git log –graph

分支管理策略

Git的分支管理模式:Fast forward,

如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

禁止使用快速合并模式:git merge –no-ff -m “merge with no-ff” dev

master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活

加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并

bug分支

把当前工作现场“储藏”起来,等以后恢复现场后继续工作:git stash

查看刚才保存的工作现场:git stash list

恢复现场,但不删除stash内容:git stash apply

恢复现场,同时删除stash内容:git stash pop

可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash: git stash apply stash@{0}

Feature分支

每添加一个新功能新建一个feature分支

丢弃一个没有被合并过的分支,强制删除分支: git branch -d feature-vulcan

多人协作

查看远程库的信息:git remote

查看远程库详情:git remote -v

推送分支

推送分支,就是把该分支上的所有本地提交推送到远程库: git push origin master、git push origin dev……

原则:

  • master分支是主分支,因此要时刻与远程同步;

  • dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;

  • bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;

  • feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

    抓取分支

    创建远程origin的dev分支到本地:git checkout -b dev origin/dev

    ​ 另一种:在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;

    当提交到远程库有冲突时,先Git pull 把最新的origin/dev抓取下来, 本地合并解决冲突再推送

    设置dev和origin/dev的链接:git branch –set-upstream-to=origin/ dev

    再Git pull拉取

多人协作的工作模式通常是这样:

  1. 首先,可以试图用git push origin <branch-name>推送自己的修改;
  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
  3. 如果合并有冲突,则解决冲突,并在本地提交;
  4. 没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!

如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>。

这就是多人协作的工作模式,一旦熟悉了,就非常简单。

Rebase

把分叉的提交变成直线

git rebase

  • rebase操作可以把本地未push的分叉提交历史整理成直线;

  • rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。

    ####标签管理

    标签是版本库的一个快照,tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。

    #####创建标签

    切换到需要打标签的分支上:git branch/git checkout master

    打标签:git tag

    查看所有标签:git tag

    对以前的版本打标签:git tag v0.9 f52c633(commit id)

    查看commit id:git log –pretty=oneline –abbrev-commit

    ​ 注意,标签不是按时间顺序列出,而是按字母排序的

    查看标签信息:git show v0.9(tag名)

    创建带有说明的标签,用-a指定标签名,-m指定说明文字:git tag -a v0.1 -m “version 0.1 released” 1094adb

注意:标签总是和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。

##### 操作标签

删除:git tag -d v0.1

推送某个标签到远程:git push origin

一次性推送全部尚未推送到远程的本地标签:git push origin –tags

如果标签已经推送到远程,要删除远程标签:

​ 先从本地删除:git tag -d v0.9

​ 从远程删除:git push origin :refs/tags/v0.9

忽略某些文件

创建.gitignore文件,把要忽略的文件名填进去

忽略文件的原则是:

  1. 忽略操作系统自动生成的文件,比如缩略图等;
  2. 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
  3. 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。

你想添加一个文件到Git,但发现添加不了,原因是这个文件被.gitignore忽略了:如果你确实想添加该文件,可以用-f强制添加到Git:git add -f App.class

哪个规则写错了可以用git check-ignore命令检查:git check-ignore -v App.class

​ Git会告诉我们,.gitignore的第3行规则忽略了该文件,于是我们就可以知道应该修订哪个规则。

####配置别名

给status配置别名: git config –global alias.st status

配置文件

每个仓库的Git配置文件都放在.git/config文件中:cat .git/config

​ 别名就在[alias]后面,要删除别名,直接把对应的行删掉即可

当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中:cat .gitconfig

开源Git:

点“Fork”就在自己的账号下克隆了一个bootstrap仓库,然后,从自己的账号下clone:(一定要从自己的账号下clone仓库,这样你才能推送修改。如果从bootstrap的作者的仓库地址`git@github.com:twbs/bootstrap.git`克隆,因为没有权限,你将不能推送修改。)

可以在GitHub上发起一个pull request

未命名

发表于 2018-07-17

购物app_首页


settings配置

确保以下配置得到处理:settings.py文件中的installed_app的配置,databases的配置,templates的配置,static的配置, login_url = ‘/login/‘,工程的init.py中初始化pymysql,install_as_mysqldb。

1
2
3
4
5
6
7
8
9
10
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app',
'user',
]
url配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django.conf.urls import url, include
from django.contrib import admin

from django.contrib.staticfiles.urls import static

from axf import settings

urlpatterns = [
url(r'^admin/', admin.site.urls),
# url映射到项目的url,采用url反向解析
url(r'^axf/', include('app.urls', namespace='axf')),
url(r'^user/', include('user.urls', namespace='user')),
]
# 加载静态文件
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

#####

项目url
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from django.conf.urls import url, include
from django.contrib import admin
from django.contrib.staticfiles.urls import static
from axf import settings

urlpatterns = [
url(r'^admin/', admin.site.urls),
# 与应用的url建立映射关系
url(r'^axf/', include('app.urls', namespace='axf')),
# 与user的应用建立映射关系
url(r'^user/', include('user.urls', namespace='user')),
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
应用url
1
2
3
4
5
6
7
8
from django.conf.urls import url

from app import views

urlpatterns = [
# 首页
url(r'^home/', views.home, name='home')
]
控制器(views)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
'''
a)banner轮播模型定义

b)导航栏模型定义

c)必购模型定义

d)商店模型定义
'''

from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.core.urlresolvers import reverse

from app.models import MainWheel, MainNav, MainMustBuy, \
MainShop, MainShow, FoodType, Goods

def home(request):
'''
首页视图函数
'''
# GET请求
if request.method == 'GET':
# 拿到以下数据
mainwheels = MainWheel.objects.all()
mainnavs = MainNav.objects.all()
mainbuys = MainMustBuy.objects.all()
mainshops = MainShop.objects.all()
mainshows = MainShow.objects.all()
# 将后端数据传到前端给html页面渲染
data = {
'title': '首页',
'mainwheels': mainwheels,
'mainnavs': mainnavs,
'mainbuys': mainbuys,
'mainshops': mainshops,
'mainshows': mainshows,
}
return render(request, 'home/home.html', data)
home.html渲染
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
{% extends 'base_main.html' %}
<!-- 页面继承base_main这个页面-->
{% load static %}
<!-- 加载静态资源-->
{% block extCSS %}
{{ block.super }}
<link rel="stylesheet" href="{% static 'app/home/home.css' %}">
{% endblock %}

{% block EXTJS %}
<script type="text/javascript" src="{% static 'app/home/js/home.js' %}"></script>
{% endblock %}
<!-- heml页面body里的部分 -->
{% block content %}
<div id="home">
{# 顶部轮播 #}
<div class="swiper-container" id="topSwiper">
<div class="swiper-wrapper">
<!--处理轮播banner图-->
{% for wheel in mainwheels %}
<div class="swiper-slide">
<a href="#">
<img src="{{ wheel.img }}" alt="">
</a>
</div>
{% endfor %}
<!-- 处理结束 -->
</div>
<!-- 如果需要分页器 -->
<div class="swiper-pagination"></div>
</div>
{# 导航 #}
<div class="topMenu">
<nav>
<ul>
<!-- 处理导航数据 -->
{% for nav in mainnavs %}
<li>
<img src="{{ nav.img }}" alt="">
<span>{{ nav.name }}</span>
</li>
{% endfor %}
<!--处理结束-->
</ul>
</nav>
</div>
{# 必购 #}
<div id="swiperMenu" class="swiper-container">

<ul class="swiper-wrapper">
<!-- 处理必购商品信息 -->
{% for buys in mainbuys %}
<li class="swiper-slide">
<img src="{{ buys.img }}" alt="">
</li>
{% endfor %}
<!-- 处理结束 -->

</ul>

</div>
{# 商店 #}
<div class="CVS">
<!--处理第一个店铺的数据的图片-->
{% for shops in mainshops %}
{% ifequal forloop.counter 1 %}
<h2>
<img src="{{ shops.img }}" alt="">
</h2>
{% endifequal %}
{% endfor %}
<!--处理结束-->

<fieldset>
{% for shops in mainshops %}
{% if forloop.counter > 1 and forloop.counter < 4 %}
<!--处理第二个到第四个数据-->
<a href="#">
<img src="{{ shops.img }}" alt="">
</a>
{% endif %}
<!--处理结束-->
{% endfor %}
</fieldset>
<ul>
<!--处理第五个到第八个数据-->
{% for shops in mainshops %}
{% if forloop.counter > 3 and forloop.counter < 8 %}
<li>
<a href="#">
<img src="{{ shops.img }}" alt="">
<span>{{ shops.name }}</span>
</a>
</li>
{% endif %}
{% endfor %}
<!--处理结束-->
</ul>
<ol>
<!--处理第八个到第十二个数据-->
{% for shops in mainshops %}
{% if forloop.counter > 7 and forloop.counter < 12 %}
<li>
<a href="#">
<img src="{{ shops.img }}" alt="">
</a>
</li>
{% endif %}
{% endfor %}
<!--处理结束-->
</ol>
</div>
{# 主要显示 #}

<div class="mainInfo">
<!--商品展示-->
{% for shows in mainshows %}
<section>
<h3><span></span><a href="#">更多&gt;</a></h3>

<div>
<a href="#">
<img src="{{ shows.img }}" alt="">
</a>
</div>

<ul>

<li>
<a href="#">
<img src="{{ shows.img1 }}" alt="">
<p class="description">
{{ shows.longname1 }}
</p>
<span>¥{{ shows.price1 }}</span>
<s>¥{{ shows.marketprice1 }}</s>
</a>
<button>
<span>+</span>
</button>
</li>
<li>
<a href="#">
<img src="{{ shows.img2 }}" alt="">
<p class="description">
{{ shows.longname2 }}
</p>
<span>¥{{ shows.price2 }}</span>
<s>¥{{ shows.marketprice2 }}</s>
</a>
<button>
<span>+</span>
</button>
</li>
<li>
<a href="#">
<img src="{{ shows.img3 }}" alt="">
<p class="description">
{{ shows.longname3 }}
</p>
<span>¥{{ shows.price3 }}</span>
<s>¥{{ shows.marketprice3 }}</s>
</a>
<button>
<span>+</span>
</button>
</li>
</ul>
</section>
{% endfor %}
<!--商品展示结束-->
</div>
</div>
{% endblock %}
js文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$(function(){

initTopSwiper();

initMenuSwiper();

})


function initTopSwiper(){

var swiper = new Swiper("#topSwiper", {
loop: true,
pagination:".swiper-pagination",
autoloop: 4000
})
}


function initMenuSwiper(){
var swiper = new Swiper("#swiperMenu", {
slidesPerView: 3
})
}

未命名

发表于 2018-07-17

购物app_个人中心


url配置
项目url
应用url
控制器(views)
个人中心的html页面
js配置

未命名

发表于 2018-07-17

关系型数据入门

关系型数据概述

  1. 数据持久化。
  2. 数据库发展史。
  3. 关系型数据库特点。
  4. E-R图。
  5. 关系型数据库产品。

MySQL简介

1.为什么要使用关系型数据库:见特点

2.关系型数据库的三个特点:

  • 集合论加关系代数

  • 用二维表承载数据,有行有列

  • 编程语言sql,ddl,dml,dql,dcl

    ####mysql的特点:

    比非关系型数据库,在数据强一致性和安全性方面,或者对于数据要求特别高的(比如金融机构等),mysql数据库在底层有锁机制,能够更好的保存,管理数据。

    windows下面是默认的是150个链接

    Linux系统可以配置链接客户端数量,改配置文件

    开启事务

    1.敲begin;或者start transaction;开启事务环境,可以回滚,提交commit后是真正删除。事务环境要么全成功,要么全失败

    2.只能一个用户操作这一行,排他锁,排队操作,不一定是行级锁,有可能是整个表,但读取数据时是使用的共享锁,都可以读;

    3.如果希望读数据的时候也用排他锁:begin;查询语句后面加for update;

    select * from tbdept for update,另一用户也在事务环境中for update

    事务隔离级别,事务传播级别

  1. 安装和配置。
  2. 常用命令。

SQL详解

  1. DDL
  2. DML
  3. DQL

Python数据库编程

#####MySQLdb

在python2中使用,目前在python3中使用的是PyMySQL

#####PyMySQL

能够对数据进行CRUD操作

####Linux系统下安装mysql:

  • 使用rpm包管理工具(redhat包管理工具)
  • 安装:ls | xargs rpm -ivh

  • 卸载:rpm -qa | grep mysql | xargs rpm -e

  • 改配置:vim /etc/my.conf

    ​ 绑定ip地址:bind-address=

    ​ 绑定端口:port=

    ​ 指定最大链接数:max_connections=

    ​ 不输密码就可以登录:skip-grant-tables

    在centos7下:

  • 启动:systemctl start mysqld

  • 状态:systemctl status mysqld

  • 开机自启:systemctl enable mysqld

  • 查看是否启动(进程):ps -ef | grep mysqld

  • 查看端口是否被占用:netstat -nap | grep 3306

####mysql的客户端工具的使用

  • mysql -u root-p :本机进到客户端工具

  • mysql -u root -h (地址) -p:链接远端

  • 查看帮助信息

    查看帮助信息:? contents

    查看数据类型:? data types

    查看整数:? int

    查看show这个命令怎么用:? show

####SQL

  1. DDL

    create / drop / alter

  2. DML

    insert / delete / update

  3. DQL

    select / as / where / like / regexp /group by / order by asc/desc

  4. DCL

    grant(授权) / revoke(召回权限) / begin / commit / rollback

    ​

####Python —>MySQL

PyMySQL的使用
  • 创建链接,connect创建链接对象

  • 打开数据库连接

  • 运用pymysql里面的connet方法

  • db = pymysql.connect(“localhost”,”testuser”,”test123”,”TESTDB” )

  • 服务器(云就写公网),用户名,密码,数据库名字

  • 编码黑洞:拉丁一语系的编码,就是存不下,全是问号,还原不了(乱码可以还原)

    ​ big5:大5码,繁体中文

    ​ gb2312:国标扩

    ​ gb18030:国标,少数民族也可以

    ​ latin1:iso-8859-1:默认选择了拉丁一语系编码,造成编码黑洞

  • cursor:读取数据可以滑动

  • 使用 cursor() 方法创建一个游标对象connection

    ​ pymysql.connext(host……)

  • cursor指定host,port(默认3306,当默认时可不写),user,passwd(password) db(database),charset.

  • cursor.execute()执行
  • cursor.fetchall():拿所有
  • fetchone():拿一条

  • cursor.rowcount

    ​ cursor = db.cursor()

  • 查询时转换成字典:cursorclass=DictCursor

  • 查询时别名

  • 手动提交:commit()

  • 自动提交:autocommit=True

  • 装的时候叫pillow,用的时候交PIL

####pycharm中库或者插件安装办法:

  • ​ 红灯泡自动修复错误
    ​ 终端
    ​ +号安装

安装虚拟环境:virtualenv –no-site-package venv

6.28

在函数中如何拿到链接mysql数据库的方法:

  • 第一种方式:将连接语句设置为全局变量,全局作用域,这是非常不好的做法,因为全局变量的影响范围太广,有时无法有效控制

    语法:global con

  • 第二种方式:将连接语句使用参数传递给需要使用的方法中

    语法:add_new_contacter(con)

抽取常量

####sql语句:limit %s offset %s

含义:查看多少条;从第几条开始,(跳过几条),

查看数量,偏移量,

####类:enumerate

for index, row in enumerate(cursor.fetchall()): ???

显示一个编号,for循环在range中有编号,自定义的列表是没有编号的

####关于安全占位符

安全在于,它会自动补全引号。只有一个占位符也是传递元组,安全占位符only接收元组

#####复用代码的最佳方式:封装,写成类或者函数

####作用域:

  • LEGB的查找方式:
  • global和nonlocal两层含义:用全局中的(修改也是),第二是全局没有它放到全局中

####面向对象

  • 数据抽象:属性(名词)

    初始化方法绑定属性
    
  • 行为抽象:方法(动词)

    花括号占位符
    

三种创建方式:

  1. 三步走:定义类,创建对象,调用对象(给对象发消息)

  2. 两步走:创建对象,给对象发消息

  3. 一步走:给对象发消息(document对象,window对象)

    ​

#####怎么把将字典变成对象

​ 创建对象:构造器,跟类名完全一致,调构造器时会自动初始化,需要传参,将字典传入关键字参数

​ 将字典处理成关键字参数传入构造器

ORM概述

1234
karen2066

karen2066

35 日志
8 标签
© 2018 karen2066
由 Hexo 强力驱动
|
主题 — NexT.Gemini v5.1.4