网站技术细节

来源:互联网 发布:淘宝绑定别人的银行卡 编辑:程序博客网 时间:2024/04/29 01:23
lnmp + http cache jq + config

linux:order + shell
 * http://blog.csdn.net/learner811/article/details/47177219
 * + lofter ==>shell detail 1~5



php:正则+算法+类+字符

正则:电话号 邮箱 ip
$pattern = '/^1[3|5|7|8|][0-9]{9}$/';
$pattern = '/^\w ([- .]\w )*@\w ([-.]\w )*\.\w ([-.]\w )*$/';
+
$email = "/([a-z0-9]*[-_\.]?[a-z0-9] )*@([a-z0-9]*[-_]?[a-z0-9] ) [\.][a-z]{2,3}([\.][a-z]{2})?/i";
$tel = "/13[123569]{1}\d{8}|15[1235689]{1}\d{8}|188\d{8}/";
$ip = "(((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|([01]?\d\d?)))";
preg_match_all($pattern,$mobile,$match);

print_r($match);


算法:排序+查找  

类:__construct, __destruct , __call, __callStatic,__get, __set, __isset, __unset , __sleep, __wakeup, __toString, __set_state, __clone and __autoload 

字符:

html过滤:htmlspecialchars htmlentities addslashes stripslashes strip_tags

变量(声明 命名 可变变量 引用赋值  | 类型转换| 局部 全局 静态)  

常量(定义和使用 |区别变量|预定义)  

运算符(优先级) 

表达式 

函数参数:(值 引用 默认 可变长) 




mysql:数据类型 CURD  常见工具  sql语句

数据类型:整型  浮点型  字符 日期 

库 表 列 索引 (CURD )

create drop rename/engine/character... select(sql)

alter table  tablenameadd      column  columnname  columntype 

alter table  tablenamedrop      columncolumnname columntype 

alter table  tablenamechange        columncolumnname  newColumnNamecolumntype

alter table  tablenamemodify    columncolumnname  columntype


alter table  tablenameadd      indextype  indexName(columnname)   

alter table  tablename drop      indexName 


常见:mysqlbinlog(按时间和地点恢复)  mysqladmin(密码找回) mysqldump(备份)  

50个语句  

索引(结构+3星)

简单  where

复杂

连表    inner  + outer  | union 

子查询 exists   not/in

聚合查询  group by ...

1、整型

MySQL数据类型含义(有符号)tinyint(m)1个字节 范围(-128~127)smallint(m)2个字节 范围(-32768~32767)mediumint(m)3个字节 范围(-8388608~8388607)int(m)4个字节 范围(-2147483648~2147483647)bigint(m)8个字节 范围(+-9.22*10的18次方)

取值范围如果加了unsigned,则最大值翻倍,如tinyint unsigned的取值范围为(0~256)。 
int(m)里的m是表示SELECT查询结果集中的显示宽度,并不影响实际的取值范围,没有影响到显示的宽度,不知道这个m有什么用。

2、浮点型(float和double)

MySQL数据类型含义float(m,d)单精度浮点型 8位精度(4字节) m总个数,d小数位double(m,d)双精度浮点型 16位精度(8字节) m总个数,d小数位

设一个字段定义为float(5,3),如果插入一个数123.45678,实际数据库里存的是123.457,但总个数还以实际为准,即6位。

3、定点数

浮点型在数据库中存放的是近似值,而定点类型在数据库中存放的是精确值。 
decimal(m,d) 参数m<65 是总个数,d<30且 d<m 是小数位。

4、字符串(char,varchar,_text)

MySQL数据类型含义char(n)固定长度,最多255个字符varchar(n)固定长度,最多65535个字符tinytext可变长度,最多255个字符text可变长度,最多65535个字符mediumtext可变长度,最多2的24次方-1个字符longtext可变长度,最多2的32次方-1个字符

char和varchar:
1.char(n) 若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉。所以char类型存储的字符串末尾不能有空格,varchar不限于此。 
2.char(n) 固定长度,char(4)不管是存入几个字符,都将占用4个字节,varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),所以varchar(4),存入3个字符将占用4个字节。 
3.char类型的字符串检索速度要比varchar类型的快。

varchar和text: 
1.varchar可指定n,text不能指定,内部存储varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),text是实际字符数+2个字节。 
2.text类型不能有默认值。 
3.varchar可直接创建索引,text创建索引要指定前多少个字符。varchar查询速度快于text,在都创建索引的情况下,text的索引似乎不起作用。

5.二进制数据(_Blob)

1._BLOB和_text存储方式不同,_TEXT以文本方式存储,英文存储区分大小写,而_Blob是以二进制方式存储,不分大小写。 
2._BLOB存储的数据只能整体读出。 
3._TEXT可以指定字符集,_BLO不用指定字符集。

6.日期时间类型

MySQL数据类型含义date日期 '2008-12-2'time时间 '12:25:36'datetime日期时间 '2008-12-2 22:06:44'timestamp自动存储记录修改时间

若定义一个字段为timestamp,这个字段里的时间数据会随其他字段修改的时候自动刷新,所以这个数据类型的字段可以存放这条记录最后被修改的时间。

数据类型的属性

MySQL关键字含义NULL数据列可包含NULL值NOT NULL数据列不允许包含NULL值DEFAULT默认值PRIMARY KEY主键AUTO_INCREMENT自动递增,适用于整数类型UNSIGNED无符号CHARACTER SET name指定一个字符集

表列出了各种数值类型以及它们的允许范围和占用的内存空间。

类型
大小
范围(有符号)
范围(无符号)
用途
TINYINT
1 字节
(-128,127)
(0,255)
小整数值
SMALLINT
2 字节
(-32 768,32 767)
(0,65 535)
大整数值
MEDIUMINT
3 字节
(-8 388 608,8 388 607)
(0,16 777 215)
大整数值
INT或INTEGER
4 字节
(-2 147 483 648,2 147 483 647)
(0,4 294 967 295)
大整数值
BIGINT
8 字节
(-9 233 372 036 854 775 808,9 223 372 036 854 775 807)
(0,18 446 744 073 709 551 615)
极大整数值
FLOAT
4 字节
(-3.402 823 466 E+38,1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38)
0,(1.175 494 351 E-38,3.402 823 466 E+38)
单精度
浮点数值
DOUBLE
8 字节
(1.797 693 134 862 315 7 E+308,2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)
0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)
双精度
浮点数值
DECIMAL
对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2
依赖于M和D的值
依赖于M和D的值
小数值

 

INT 类型

  在 MySQL 中支持的 5 个主要整数类型是 TINYINT,SMALLINT,MEDIUMINT,INT 和 BIGINT。这些类型在很大程度上是相同的,只有它们存储的值的大小是不相同的。

  MySQL 以一个可选的显示宽度指示器的形式对 SQL 标准进行扩展,这样当从数据库检索一个值时,可以把这个值加长到指定的长度。例如,指定一个字段的类型为 INT(6),就可以保证所包含数字少于 6 个的值从数据库中检索出来时能够自动地用空格填充。需要注意的是,使用一个宽度指示器不会影响字段的大小和它可以存储的值的范围。

  万一我们需要对一个字段存储一个超出许可范围的数字,MySQL 会根据允许范围最接近它的一端截短后再进行存储。还有一个比较特别的地方是,MySQL 会在不合规定的值插入表前自动修改为 0。

  UNSIGNED 修饰符规定字段只保存正值。因为不需要保存数字的正、负符号,可以在储时节约一个“位”的空间。从而增大这个字段可以存储的值的范围。

  ZEROFILL 修饰符规定 0(不是空格)可以用来真补输出的值。使用这个修饰符可以阻止 MySQL 数据库存储负值。

FLOAT、DOUBLE 和 DECIMAL 类型

  MySQL 支持的三个浮点类型是 FLOAT、DOUBLE 和 DECIMAL 类型。FLOAT 数值类型用于表示单精度浮点数值,而 DOUBLE 数值类型用于表示双精度浮点数值。

  与整数一样,这些类型也带有附加参数:一个显示宽度指示器和一个小数点指示器。比如语句 FLOAT(7,3) 规定显示的值不会超过 7 位数字,小数点后面带有 3 位数字。

  对于小数点后面的位数超过允许范围的值,MySQL 会自动将它四舍五入为最接近它的值,再插入它。

  DECIMAL 数据类型用于精度要求非常高的计算中,这种类型允许指定数值的精度和计数方法作为选择参数。精度在这里指为这个值保存的有效数字的总个数,而计数方法表示小数点后数字的位数。比如语句 DECIMAL(7,3) 规定了存储的值不会超过 7 位数字,并且小数点后不超过 3 位。

  忽略 DECIMAL 数据类型的精度和计数方法修饰符将会使 MySQL 数据库把所有标识为这个数据类型的字段精度设置为 10,计算方法设置为 0。

  UNSIGNED 和 ZEROFILL 修饰符也可以被 FLOAT、DOUBLE 和 DECIMAL 数据类型使用。并且效果与 INT 数据类型相同。

字符串类型

  MySQL 提供了 8 个基本的字符串类型,可以存储的范围从简单的一个字符到巨大的文本块或二进制字符串数据。

类型
大小
用途
CHAR
0-255字节
定长字符串
VARCHAR
0-255字节
变长字符串
TINYBLOB
0-255字节
不超过 255 个字符的二进制字符串
TINYTEXT
0-255字节
短文本字符串
BLOB
0-65 535字节
二进制形式的长文本数据
TEXT
0-65 535字节
长文本数据
MEDIUMBLOB
0-16 777 215字节
二进制形式的中等长度文本数据
MEDIUMTEXT
0-16 777 215字节
中等长度文本数据
LOGNGBLOB
0-4 294 967 295字节
二进制形式的极大文本数据
LONGTEXT
0-4 294 967 295字节
极大文本数据

CHAR 和 VARCHAR 类型

  CHAR 类型用于定长字符串,并且必须在圆括号内用一个大小修饰符来定义。这个大小修饰符的范围从 0-255。比指定长度大的值将被截短,而比指定长度小的值将会用空格作填补。

  CHAR 类型可以使用 BINARY 修饰符。当用于比较运算时,这个修饰符使 CHAR 以二进制方式参于运算,而不是以传统的区分大小写的方式。

  CHAR 类型的一个变体是 VARCHAR 类型。它是一种可变长度的字符串类型,并且也必须带有一个范围在 0-255 之间的指示器。CHAR 和 VARCHGAR 不同之处在于 MuSQL 数据库处理这个指示器的方式:CHAR 把这个大小视为值的大小,不长度不足的情况下就用空格补足。而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度(增加一个额外字节来存储字符串本身的长度)来存储值。所以短于指示器长度的 VARCHAR 类型不会被空格填补,但长于指示器的值仍然会被截短。

  因为 VARCHAR 类型可以根据实际内容动态改变存储值的长度,所以在不能确定字段需要多少字符时使用 VARCHAR 类型可以大大地节约磁盘空间、提高存储效率。

  VARCHAR 类型在使用 BINARY 修饰符时与 CHAR 类型完全相同。

TEXT 和 BLOB 类型

  对于字段长度要求超过 255 个的情况下,MySQL 提供了 TEXT 和 BLOB 两种类型。根据存储数据的大小,它们都有不同的子类型。这些大型的数据用于存储文本块或图像、声音文件等二进制数据类型。

  TEXT 和 BLOB 类型在分类和比较上存在区别。BLOB 类型区分大小写,而 TEXT 不区分大小写。大小修饰符不用于各种 BLOB 和 TEXT 子类型。比指定类型支持的最大范围大的值将被自动截短。

 

日期和时间类型

  在处理日期和时间类型的值时,MySQL 带有 5 个不同的数据类型可供选择。它们可以被分成简单的日期、时间类型,和混合日期、时间类型。根据要求的精度,子类型在每个分类型中都可以使用,并且 MySQL 带有内置功能可以把多样化的输入格式变为一个标准格式。

类型
大小
(字节)
范围
格式
用途
DATE
3
1000-01-01/9999-12-31
YYYY-MM-DD
日期值
TIME
3
'-838:59:59'/'838:59:59'
HH:MM:SS
时间值或持续时间
YEAR
1
1901/2155
YYYY
年份值
DATETIME
8
1000-01-01 00:00:00/9999-12-31 23:59:59
YYYY-MM-DD HH:MM:SS
混合日期和时间值
TIMESTAMP
8
1970-01-01 00:00:00/2037 年某时
YYYYMMDD HHMMSS
混合日期和时间值,时间戳

DATE、TIME 和 TEAR 类型

  MySQL 用 DATE 和 TEAR 类型存储简单的日期值,使用 TIME 类型存储时间值。这些类型可以描述为字符串或不带分隔符的整数序列。如果描述为字符串,DATE 类型的值应该使用连字号作为分隔符分开,而 TIME 类型的值应该使用冒号作为分隔符分开。

  需要注意的是,没有冒号分隔符的 TIME 类型值,将会被 MySQL 理解为持续的时间,而不是时间戳。

  MySQL 还对日期的年份中的两个数字的值,或是 SQL 语句中为 TEAR 类型输入的两个数字进行最大限度的通译。因为所有 TEAR 类型的值必须用 4 个数字存储。MySQL 试图将 2 个数字的年份转换为 4 个数字的值。把在 00-69 范围内的值转换到 2000-2069 范围内。把 70-99 范围内的值转换到 1970-1979 之内。如果 MySQL 自动转换后的值并不符合我们的需要,请输入 4 个数字表示的年份。

DATEYIME 和 TIMESTAMP 类型

   除了日期和时间数据类型,MySQL 还支持 DATEYIME 和 TIMESTAMP 这两种混合类型。它们可以把日期和时间作为单个的值进行存储。这两种类型通常用于自动存储包含当前日期和时间的时间戳,并可在需要执行大量数据库事务和需要建立一个调试和审查用途的审计跟踪的应用程序中发挥良好作用。

  如果我们对 TIMESTAMP 类型的字段没有明确赋值,或是被赋与了 null 值。MySQL 会自动使用系统当前的日期和时间来填充它。

 

复合类型

  MySQL 还支持两种复合数据类型 ENUM 和 SET,它们扩展了 SQL 规范。虽然这些类型在技术上是字符串类型,但是可以被视为不同的数据类型。一个 ENUM 类型只允许从一个集合中取得一个值;而 SET 类型允许从一个集合中取得任意多个值。

 

ENUM 类型

  ENUM 类型因为只允许在集合中取得一个值,有点类似于单选项。在处理相互排拆的数据时容易让人理解,比如人类的性别。ENUM 类型字段可以从集合中取得一个值或使用 null 值,除此之外的输入将会使 MySQL 在这个字段中插入一个空字符串。另外如果插入值的大小写与集合中值的大小写不匹配,MySQL 会自动使用插入值的大小写转换成与集合中大小写一致的值。

   ENUM 类型在系统内部可以存储为数字,并且从 1 开始用数字做索引。一个 ENUM 类型最多可以包含 65536 个元素,其中一个元素被 MySQL 保留,用来存储错误信息,这个错误值用索引 0 或者一个空字符串表示。

  MySQL 认为 ENUM 类型集合中出现的值是合法输入,除此之外其它任何输入都将失败。这说明通过搜索包含空字符串或对应数字索引为 0 的行就可以很容易地找到错误记录的位置。

SET 类型

  SET 类型与 ENUM 类型相似但不相同。SET 类型可以从预定义的集合中取得任意数量的值。并且与 ENUM 类型相同的是任何试图在 SET 类型字段中插入非预定义的值都会使 MySQL 插入一个空字符串。如果插入一个即有合法的元素又有非法的元素的记录,MySQL 将会保留合法的元素,除去非法的元素。

  一个 SET 类型最多可以包含 64 项元素。在 SET 元素中值被存储为一个分离的“位”序列,这些“位”表示与它相对应的元素。“位”是创建有序元素集合的一种简单而有效的方式。并且它还去除了重复的元素,所以 SET 类型中不可能包含两个相同的元素。

  希望从 SET 类型字段中找出非法的记录只需查找包含空字符串或二进制值为 0 的行。




mysql -h 主机地址 -u 用户名 -p 用户密码

grant all privileges on wpj1105.* to sunxiao@localhost identified by '123'; #all privileges 所有权限
drop database if exists wpj1105;
drop table if exists student;

#创建表
create table student(
id int auto_increment primary key,
name varchar(50),
sex varchar(20),
date varchar(50),
content varchar(100),
name varchar(20) not null default 'NoName', #设定默认值
age int unsigned, #不能为负值(如为负值 则默认为0)
sno int unique #不可重复
)ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;

change>modify
#修改表的名字
alter table c rename to a;
#向表中增加一个字段(列)
alter table test add column columnname varchar(20);
#修改表中某个字段的名字
alter table test change name uname varchar(50);
#表position 修改列test
alter table position modify test char(20) not null;
#表position 修改列test 默认值
alter table position alter test set default 'system';
#表position 去掉test 默认值
alter table position alter test drop default;
#表position 去掉列test
alter table position drop column test;
#表depart_pos 删除主键
alter table depart_pos drop primary key;
#表depart_pos 增加主键
alter table depart_pos add primary key PK_depart_pos
(department_id,position_id);


alter table 表名 add index 索引名 (字段名1[,字段名2 …]);
alter table employee add index emp_name (name);
加主关键字的索引
alter table employee add primary key(id);
加唯一限制条件的索引
alter table employee add unique emp_name2(cardnumber);
删除某个索引
alter table employee drop index emp_name;

ALTER TABLE tablename CONVERT TO CHARACTER SET charset_name;
ALTER TABLE tablename engine=innoDB;

CHECK TABLE、REPAIR TABLE-myisam、ANALYZE TABLE和OPTIMIZE TABLE

#mysqldump -u 用户名 -p 密码 数据库名 表名 > output.sql
mysqladmin -uroot -proot password newpassword
mysqlimport -uroot -proot 数据库名 >output.txt
source output.sql
mysqlbinlog —start-position=100 —stop-position=200 -d database route | mysql -u root -p
mysqlbinlog —start-datetime=‘2000-12-12' —stop-datetime=‘2086-12-12' -d database route | mysql -u root -p

1.导出整个数据库
mysqldump -u user_name -p123456 database_name > outfile_name.sql
2.导出一个表
mysqldump -u user_name -p database_name table_name > outfile_name.sql
3.导出一个数据库结构
mysqldump -u user_name -p -d –add-drop-table database_name > outfile_name.sql
-d 没有数据 –add-drop-table 在每个create语句之前增加一个drop table
4.带语言参数导出
mysqldump -uroot -p –default-character-set=latin1 –set-charset=gbk –skip-opt database_name > outfile_name.sql
5.导出数据库中的某张数据表的表结构(不含数据)
mysqldump -u username -p -d dbname tablename > tablename.sql
例如,将aaa库备份到文件back_aaa中:
mysqldump -u root -p --opt aaa > back_aaa

#导入.sql文件命令(例如D:/mysql.sql)
source d:/mysql.sql; #或者 /. d:/mysql.sql;
#用文本方式将数据装入数据库表中(例如D:/mysql.txt)
load data local infile "D:/mysql.txt" into table MYTABLE;
mysqlimport -uroot -p404 test /home/pw/dept.txt/home/pw/emp.txt
mysqladmin -uroot -p123 password 456;
mysqlcheck -a -c -o -r -m --all-databases -uroot -p

mysqlbinlog 重放
3.2 按指定位置恢复:
mysqlbinlog --start-position=185 --stop-position=338 -d 库名 e:/log/logbin.000001 >c:\\test1.txt | mysql -u root -p
3.3 按指定时间恢复:
mysqlbinlog --start-datetime="2010-01-07 11:25:56" --stop-datetime="2010-01-07 13:23:50" -d 库名e:/log/logbin.000001 >c:\\test1.txt| mysql -u root -p
4.2 当前使用的binlog文件
show binlog events \g;



====================表结构=======================
Student(sid,Sname,Sage,Ssex) 学生表
Course(cid,Cname,tid) 课程表
SC(sid,cid,score) 成绩表
Teacher(tid,Tname) 教师表

表关系:学生 sid 分数 cid 课程 tid/id 老师


================complex============================

join + group by + 临时表

48、查询两门或两门以上不及格课程的同学的学号及其平均成绩 
    select *,count(cid) ,avg(score)from sc  where score<60 group by sid having count(cid)>=2;

10、查询没有学全所有课的同学的学号、姓名; 
    select *,count(*),student.sname from sc join student using(sid)  group by sid having (count(*) < (select count(*) from course));

21、查询不同老师所教不同课程平均分从高到低显示 
  select *,avg(score) from sc join course join teacher on (sc.cid=course.cid and course.tid =teacher.tid) group by teacher.tid,course.cid order by avg(score) desc;


14、查询和“1002”号的同学学习的课程(的个数)完全相同的其他同学学号和姓名; 

    #此条SQL有问题
    -- select sid from SC where cid in (select cid from SC where sid='S002') 
    -- group by sid having count(*)=(select count(*) from SC where sid='S002'); 

    select *,count(*) from SC  
    group by sid having count(*)=(select count(*) from sc where sid='S002');


    7、查询学过“叶平”老师所教的所有课的同学的学号、姓名; 

 select * from student join sc join course join teacher  on ( student.sid=sc.sid and  sc.cid = course.cid and course.tid = teacher.id)  where teacher.tname='张三'   group by sc.sid   having (count(*) = (select count(*) from course join teacher on teacher.id = course.tid where teacher.tname = '张三'))

ok:
select * from student join sc using(sid) where sc.cid in   
(
    select cid from course join teacher using(tid) where tname=‘叶平
) group by student.sid having count(cid)=  (select count(cid) from course join teacher using(tid) where tname=‘叶平’)



18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分 
   select sc.sid,sc.minscore,sc2.maxscore from (select *,min(score) as minscore from sc group by cid) sc join  (select *,max(score) as maxscore from sc group by cid) sc2 on sc.cid= sc2.cid;

ok:
select cid,max(score) ,min(score) from sc group by cid;



4、查询姓“李”的老师的个数;  #去重后也能分辨不同的李姓老师,但是如果老师姓名相同就会去掉重复的,不完全了
  select count(distinct(Tname)) 
  from Teacher
  where Tname like '李%'; 



1、查询“C01”课程比“C02”课程成绩高的所有学生的学号; 
分治法 ,两张表自连接比较,两个条件是互斥的,因此要分开,但又要相连
select a.sid from
(select sid,score from SC where cid=‘C01') a,
(select sid,score   from SC where cid=‘C02') b 

where a.score<b.score and a.sid=b.sid;



5、查询没学过“叶平”老师课的同学的学号、姓名; 
    分治法,多表in
    select Student.sid,Student.Sname 
    from Student  
    where sid not in 
    (select distinct( SC.sid) from SC,Course,Teacher where  SC.cid=Course.cid and Teacher.tid=Course.tid and Teacher.Tname='叶平');

ok:
select * from student where sid not in (select sc.sid from course join teacher join sc on (course.cid=sc.cid and course.tid=teacher.tid)  where tname=‘叶平’)


6、查询学过“C01”并且也学过编号“C02”课程的同学的学号、姓名; 
分治法,自连接
select * from sc where cid = 'C01' and exists( select * from sc sc2 where sc2.cid='C02' and sc2.sid=sc.sid);
ok:
select * from (select * from sc where cid in ('C01' ,'C02')) a group by sid having count(cid)=2;


40、查询选修“叶平”老师所授课程的学生中,成绩最高的学生姓名及其成绩 
    select Student.Sname,score 
    from Student,SC,Course C,Teacher 
    where Student.sid=SC.sid and SC.cid=C.cid and C.tid=Teacher.tid and Teacher.Tname='张三' and
    SC.score=(select max(score)from SC where cid=C.cid ); 

ok:
select sid,max(score) from sc join course using(cid)  where sc.cid in (select course.cid from course join teacher using(tid) where teacher.tname='张三') group by course.tid;




23、统计列印各科成绩,各分数段人数:课程ID,课程名称,[100-85],[85-70],[70-60],[ <60] 
##  CASE
#   WHEN  THEN
#   WHEN  THEN
#   ELSE  DONE
SELECT SC.cid as 课程ID, Cname as 课程名称 
    ,SUM(CASE WHEN score BETWEEN 85 AND 100 THEN 1 ELSE 0 END) AS 优
    ,SUM(CASE WHEN score BETWEEN 70 AND 85 THEN 1 ELSE 0 END) AS 良 
    ,SUM(CASE WHEN score BETWEEN 60 AND 70 THEN 1 ELSE 0 END) AS 中
    ,SUM(CASE WHEN score < 60 THEN 1 ELSE 0 END) AS 不合格
FROM SC,Course 
where SC.cid=Course.cid 
GROUP BY SC.cid,Cname; 


17、按平均成绩从高到低显示所有学生的“数据库”、“企业管理”、“英语”三门的课程成绩,按如下形式显示: 学生ID,,数据库,企业管理,英语,有效课程数,有效平均分
    
    ##内部的预选列,没有连表,只是和总表做了一个连接查询,注意其中的表命名,是以总表 t 为准的
    SELECT sid as 学生ID 
        ,(SELECT score FROM SC WHERE SC.sid=t.sid AND cid='C01') AS C01
        ,(SELECT score FROM SC WHERE SC.sid=t.sid AND cid='C02') AS C02 
        ,(SELECT score FROM SC WHERE SC.sid=t.sid AND cid='C03') AS C03 
        ,COUNT(*) AS 有效课程数, AVG(t.score) AS 平均成绩 
    FROM SC AS t 
    GROUP BY sid 
    ORDER BY avg(t.score)  


24、查询学生平均成绩及其名次 
    --   SELECT 1 (SELECT COUNT( distinct 平均成绩) 
    --           FROM (SELECT sid,AVG(score) AS 平均成绩 
    --                   FROM SC 
    --               GROUP BY sid 
    --               ) AS T1 
    --         WHERE 平均成绩 > T2.平均成绩) as 名次, 
    --   sid as 学生学号,平均成绩 
    -- FROM (SELECT sid,AVG(score) 平均成绩 
    --         FROM SC 
    --     GROUP BY sid 
    --     ) AS T2 
    -- ORDER BY 平均成绩 desc; 

#精简版
select (select count(distinct 平均成绩) 
  from  (select avg(score) 平均成绩 
    from sc 
    group by sid) t1  
  where t1.平均成绩>t2.平均成绩) as 名次,平均成绩
from (select avg(score) 平均成绩 from sc  group by sid) as t2



#连接:
#内联:等值 不等值 自然连接(两张相同的表相乘)==》带了where就合内联差不多了
#外联:左外连 右外连 全连接 ==>左右各自保留,没有为空
#交叉联接:两张不同的表相乘
#
结果相同 ,join会用到 join buffer,能用join尽量用join,两个表匹配相同数据拉出,left join 左表会all,
EXPLAIN
SELECT * FROM teacher LEFT  JOIN course USING(tid);

EXPLAIN
SELECT * FROM teacher   JOIN course USING(tid)



22、查询如下课程成绩学生成绩单:
    [学生ID],[学生姓名],C01,C02,C003 
    #left join  ifnull  
      SELECT   
      SC.sid , 
        Student.Sname , 
      T1.score AS C01, 
      T2.score AS C02, 
      T3.score AS C03, 
      ifnull(T1.score,0) ifnull(T2.score,0) ifnull(T3.score,0) as 总分 
   
      FROM Student,SC  
            LEFT JOIN SC AS T1 
                      ON SC.sid = T1.sid AND T1.cid = 'C01' 
            LEFT JOIN SC AS T2 
                      ON SC.sid = T2.sid AND T2.cid = 'C02' 
            LEFT JOIN SC AS T3 
                      ON SC.sid = T3.sid AND T3.cid = 'C03' 
      WHERE Student.sid=SC.sid 
      GROUP BY Student.sid
      

    mysql> select * from student join sc using (sid); 等效于  mysql> select * from student cross join sc using (sid);
    ------ ------- ------ ------ ----- -------
    | sid  | SName | SAge | SSex | cid | score |
    ------ ------- ------ ------ ----- -------
    | S001 | Tom   |   20 | 0    | C01 |    78 |
    | S001 | Tom   |   20 | 0    | C02 |    60 |
    | S001 | Tom   |   20 | 0    | C03 |    97 |
    | S002 | Lucy  |   21 | 1    | C01 |    56 |
    | S003 | Jim   |   18 | 0    | C01 |    55 |
    | S004 | Brush |   21 | 0    | C01 |    55 |
    | S005 | Kim   |   21 | 1    | C02 |    33 |
    | S005 | Kim   |   21 | 1    | C01 |    50 |
    ------ ------- ------ ------ ----- -------

      mysql> select * from student left join sc using (sid);
      ------ ------- ------ ------ ------ -------
      | sid  | SName | SAge | SSex | cid  | score |
      ------ ------- ------ ------ ------ -------
      | S001 | Tom   |   20 | 0    | C01  |    78 |
      | S001 | Tom   |   20 | 0    | C02  |    60 |
      | S001 | Tom   |   20 | 0    | C03  |    97 |
      | S002 | Lucy  |   21 | 1    | C01  |    56 |
      | S003 | Jim   |   18 | 0    | C01  |    55 |
      | S004 | Brush |   21 | 0    | C01  |    55 |
      | S005 | Kim   |   21 | 1    | C02  |    33 |
      | S005 | Kim   |   21 | 1    | C01  |    50 |
      | S006 | Fka   |   21 | 0    | NULL |  NULL |
      | S007 | Cidy  |   21 | 1    | NULL |  NULL |
      | S008 | YouNi |   21 | 0    | NULL |  NULL |
      | S009 | Cidy  |   22 | 0    | NULL |  NULL |
      ------ ------- ------ ------ ------ -------


      mysql> select * from sc right join student using (sid);
        ------ ------- ------ ------ ------ -------
        | sid  | SName | SAge | SSex | cid  | score |
        ------ ------- ------ ------ ------ -------
        | S001 | Tom   |   20 | 0    | C01  |    78 |
        | S001 | Tom   |   20 | 0    | C02  |    60 |
        | S001 | Tom   |   20 | 0    | C03  |    97 |
        | S002 | Lucy  |   21 | 1    | C01  |    56 |
        | S003 | Jim   |   18 | 0    | C01  |    55 |
        | S004 | Brush |   21 | 0    | C01  |    55 |
        | S005 | Kim   |   21 | 1    | C02  |    33 |
        | S005 | Kim   |   21 | 1    | C01  |    50 |
        | S006 | Fka   |   21 | 0    | NULL |  NULL |
        | S007 | Cidy  |   21 | 1    | NULL |  NULL |
        | S008 | YouNi |   21 | 0    | NULL |  NULL |
        | S009 | Cidy  |   22 | 0    | NULL |  NULL |
        ------ ------- ------ ------ ------ -------



=====================curd==========================


mysql update/delete==>inner join
case when then end
union+in
insert select | insert into select


46、查询全部学生都选修的课程的课程号和课程名

     select  cid ,count(*) from  sc group  by  cid having count(*) = (select count(*) from student );


13、把“SC”表中“叶平”老师教的课的成绩都更改为此课程的平均成绩;

    #理解内容:udpate多张表,where条件放最后面,同时还有case end写法 | 但是这里报错,不能select后再update or delete
    update Course join Teacher join SC on( Course.cid=SC.cid and Course.tid=Teacher.id )
      set
      score=(select avg(SC_2.score) from SC SC_2 where SC_2.cid=SC.cid )  where Teacher.Tname='张三'

      #case end写法
      UPDATE mytable
    SET myfield = CASE id
        WHEN 1 THEN '2'
        WHEN 2 THEN '3'
        WHEN 3 THEN '4'
    END
WHERE id IN (1,2,3)



//select 放在数据更新之前

sql server中,我们可是使用以下update语句对表进行更新:
update a set a.xx= (select yy from b) ;
但是在mysql中,不能直接使用set select的结果,必须使用inner join:
update a inner join (select yy from b) c set a.xx = c.yy


update sc join
 (select  sid,avg(score)  as score  from sc join course join teacher on(course.cid=sc.cid and teacher.tid=course.tid)  where tname=‘叶平’)  temp 
on sc.sid= temp .sid 
set sc.score = temp.score 



15、删除学习“张三”老师课的SC表记录;

    delete sc.* from  sc join course join teacher on (teacher.id = course.tid and  sc.cid = course.cid)where tname = '张三';


16、向SC表中插入一些记录,这些记录要求符合以下条件:没有上过编号“C02”课程的同学学号、2、号课的平均成绩;

    #题意不明,写法了解下,就是找出对应的字段,也是insert 的一种写法,有点儿像 'insert into select '
 Insert into Table2(a, c, d) select a,c,5 from Table1

    Insert SC 
    select sid,'C02',(Select avg(score) 
    from SC where cid='C02') avg from Student 
    where sid not in (Select sid from SC where cid='C02'); 

 InsertTable2select a,c,5 from Table1


25、查询各科成绩前三名的记录:(不考虑成绩并列情况)

      #mysql这个版本不支持待limit 的子查询
      SELECT t1.sid as 学生ID,t1.cid as 课程ID,Score as 分数
      FROM SC t1
      WHERE score IN (SELECT score
              FROM SC
              WHERE t1.cid= cid
            ORDER BY score DESC limit 3
              )
      ORDER BY t1.cid;



ok:
 (SELECT * FROM sc  WHERE  cid= 1 ORDER BY score LIMIT 3)
UNION
 (SELECT * FROM sc  WHERE  cid=2 ORDER BY score LIMIT 3)
UNION
 (SELECT * FROM sc  WHERE  cid=3 ORDER BY score LIMIT 3)
UNION
 (SELECT * FROM sc  WHERE  cid=4 ORDER BY score LIMIT 3) 


================simple=============================
2、查询平均成绩大于60分的同学的学号和平均成绩;
    select sid,avg(score)
    from sc
    group by sid having avg(score) >60;

3、查询所有同学的学号、姓名、选课数、总成绩;
  select Student.sid,Student.Sname,count(SC.cid),sum(score)
  from Student left Outer join SC on Student.sid=SC.sid
  group by Student.sid,Sname


ok:

select s.sid,s.sname,count(sc.cid),sum(sc.score) from students join sc on  s.sid=sc.sid group by sc.sid 



26、查询每门课程被选修的学生数
  select cid,count(sid) from sc group by cid;

27、查询出只选修了一门课程的全部学生的学号和姓名
  select SC.sid,Student.Sname,count(cid) AS 选课数
  from SC ,Student
  where SC.sid=Student.sid group by SC.sid ,Student.Sname having count(cid)=1;


ok:

select s.sid,s.sname from student s join sc  on s.sid=sc.sid  group by sc.sid having count(cid)=1;


28、查询男生、女生人数
    Select count(Ssex) as 男生人数 from Student group by Ssex having Ssex='男';
    Select count(Ssex) as 女生人数 from Student group by Ssex having Ssex='女';



ok:
select ssex,count(*) from student group by ssex;


30、查询同名同性学生名单,并统计同名人数
  select Sname,count(*) from Student group by Sname having  count(*)>1;;

32、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列
    Select cid,Avg(score) from SC group by cid order by Avg(score),cid DESC ;

   
33、查询平均成绩大于85的所有学生的学号、姓名和平均成绩
    select Sname,SC.sid ,avg(score)
    from Student,SC
    where Student.sid=SC.sid group by SC.sid,Sname having    avg(score)>85;

41、查询各个课程及相应的选修人数
    select count(*) from sc group by cid;

44、统计每门课程的学生选修人数(超过10人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列  
    select  cid as 课程号,count(*) as 人数
    from  sc  
    group  by  cid
    having count(*)>10
    order  by  count(*) desc,cid  


45、检索至少选修两门课程的学生学号
    select  sid  
    from  sc  
    group  by  sid
    having  count(*)  >=2





缓存


redis

通用:计数(加减 1 or more) 计时(设定时长和时间点  和 剩余时间) 统计(个数 移动 随机) 存取(批量和限时)删除(指定和所有)

数据:存取  长度 区间  排序(string+pre  list-+left right   hash+keys vals  set+inter union diff   zset+sort)


memcahe: curd  stats  server(add start)  | memcached :批量 精准 细粒度cas



一、Redis



//存取 时效 加减1 键名操作 事务 持久化
//get set setex setex delete mset mgetgetMultiple=>multi flushdb flushall     (ex nx m+)
//ttl persist setTimeout=>expire expireAt|                                              (+4)
//incr incrby decr decrby                                                                        (number)
//keys randomKey type dbsize rename renameNx move exists            (key use)


//string:getSet get/setRange append strlen                           (get set)       
//hash h m/set m/get del keys vals getall len exists incrby    (field 0=>1 2=>3 4=>5 )                    
//list:l r push/x pop set get | l range/trim/rem/insert lsize |rpoplpush   (in out  range(save del get insert)  lists)
+
//set s add rem move pop sort inter/store union/store diff-前面的差集/store randMember memberscontains=>sismember size=>scared     (inter union diff | add rem  pop | member(contain size rand))
//zset z add rem |rev/range rem/rangebyscore score rank |count incrby size |union/inter(add and multiple)
(key score meber | score member | score member … ... )


//multi(顺序处理) exec(执行) discard(丢弃) watch(乐观锁 不许改动) unwatch  pipeline(批处理)
//save bgsave lastsave bgrewriteaof slaveof info auth
//ttl -2 是过期了,-1是持久有效 


//sort
sort key (desc) limit 0 5  
sort by  get  store 




$r = new Redis;
$r->connect('127.0.0.1',6379);
$r->auth('password');

$option = $r->ping();
$r->set('key','val');
$val = $r->get('key');
// echo $val;
$r->setnx('key','val');
$nx = $r->get('key');

$r->setex('keys',3,'vals');
$time = $r->ttl('keys');
//echo $time;

$num = $r->delete('key');
//echo $num;

$r->persist('keys');
$val = $r->get('keys');
//echo $val;


$r->mset(array('key1'=>'val1','key2'=>'val2','key3'=>'val3','key4'=>'val4','key5'=>'val5'));
$val = $r->get('key3');
// echo $val;

$vals = $r->getMultiple(array('key1','key2','key3','key4','key5'));
// echo '<pre>';
// print_r($vals);

$have = $r->exists('key2');
// echo($have);

//$number = $r->set('num',1);
$numNow = $r->incr('num');
$numNow = $r->incrby('num',10);
// echo $numNow;


//事务失败后不能回滚,造成部分执行完毕,事务只能保证操作的原子性,但不能保证数据原子性,因此采用乐观锁,watch/unwatch
$r->watch('num');
$r->multi()->incrby('num',100)->exec(); //or $r->multi()->incrby('num',100)->discard();
$num = $r->get('num');
// echo $num;



// $r->flushDB();
// $r->flushAll();
$keyss = $r->randomKey();
echo $keyss;


$r->select(0);
$r->set('x',42);
$r->move('x',1);
$r->select(1);
$val = $r->get('x');
// echo $val;

$r->set('name1','zy');
$r->set('name2','zy');
$r->set('name3','zy');
$r->set('name4','zy');
$r->set('name','zy');
$r->rename('name','myname');
$r->get('myname');
$r->renameNx('myname','myname2');

$r->setTimeout('x',30);
$time = $r->ttl('x');
// echo $time;

$r->expireAt('x',time() 301);
$time = $r->ttl('x');
//echo $time;


$key = $r->keys('*');
// print_r($key);

$db = $r->dbSize();
// var_dump($db);
echo '<pre>';

$r->bgrewriteaof();
// $r->slaveof('127.0.0.1',6380);



$r->save();;
$r->bgsave();
$unix = $r->lastSave();
$date = date('Y-m-d H:i:s',$unix);
// echo $date;
// print_r($operate);
$info = $r->info());

var_dump($r->type('myname'));



//string
$r->set('string','str');
$len = $r->strlen('string');
$r->set('insert','insertVals');
$r->append('string','insert');
// $val = $r->get('string');
// echo $val;
$r->set('abc','def');
$vals = $r->getSet('string','abc');
echo $vals;
$change = $r->get('string');
echo $change;

//hash

$r->hmset('student',array('wangming'=>80,'xiaohong'=>85,'ligang'=>90));
$r->hdel('student','ligang');
$vals = $r->hmget('student',array('xiaohong','wangming'));
var_dump($vals);

$val = $r->hget('student','xiaohong');
echo $val;

$exists = $r->hexists('student','wangming');
var_dump($exists);

$len = $r->hlen('student');
echo $len;

$r->hincrBy('student','xiaohong',10);
$score=$r->hget('student','xiaohong');
var_dump($score);


$keys = $r->hkeys('student');
$vals = $r->hvals('student');
$all = $r->hgetall('student');
echo '<pre>';
var_dump($keys);
var_dump($vals);
var_dump($all);

//zset
$r->zadd('set',0,'123');
$r->zadd('set',1,'456');
$r->zadd('set',2,'789');
$r->zadd('set',3,'1231');
$r->zrem('set','789');
$r->zadd('set',42,'1232');
$count = $r->zcount('set',0,42);
$size = $r->zsize('set');
$r->zincrby('set',2000,'123');

$rangeScore = $r->zremrangeByScore('set',0,1);
$scores = $r->zscore('set','123');
var_dump($scores);


$rank = $r->zrank('set','789');
var_dump($rank);
echo $size;
var_dump($count);
echo '<pre>';
$range = $r->zRevrange('set',0,-1);
var_dump($range);



二、Memcached

// append prepend getDelayed fetch fetchall setMulti getMulti addServers getServerByKey setByKey cas--写锁的set setOptions
//set = add replace
$m = new Memcached();
$m->addServer('127.0.0.1',11211);
$m->set('foo','bar');
$m->setOption(Memcached::OPT_COMPRESSION,false);
$m->append('foo','def');
$m->prepend('foo','000');
$mess = $m->get('foo');


$m->set('int',11);
$m->set('int',22);
$m->set('string','ok');
$m->set('hash','0xdsfdf');
$m->getDelayed(array('int','string'),true);
// while ($re = $m->fetch()) {
// print_r($re);
// }

$re = $m->fetchAll();
// print_r($re);


$items = array('key1'=>'val1','key2'=>'val2','key3'=>'val3');
$m->setMulti($items,true);
$mess = $m->getMulti(array('key1','key2','key3'),$cas);
//print_r($mess);


$m->addServers(array(
array('127.0.0.1',11211),
array('127.0.0.1',11212)

));


for ($i=0; $i <10 ; $i ) {
$key = 'key_'.$i;
$m->set($key,1);
}
for ($i=0; $i < 10; $i ) {
$key = 'key_'.$i;
$server = $m->getServerByKey($key);
// print_r($server);
}

$list = $m->getServerList();
// var_dump($list);


$m->setByKey('127.0.0.1','orderKey',1);



do {
$ips = $m->get('ip_block',null,$cas);//加上$cas后面才能用
if ($m->getResultCode()==Memcached::RES_NOTFOUND) {
$ips = $_SERVER['REMOTE_ADDR'];
$m->add('ip_block',$ips);
}else{
$m->cas($cas,'ip_block',$ips);//加了写锁的set
}
} while ($m->getResultCode()!=Memcached::RES_SUCCESS);

var_dump($ips);


//list
$r = new Redis;
$r->connect('127.0.0.1',6379);
echo '<pre>';
// $r->lpush('list','key1');
// $r->rpush('list','key2');
// $r->rpush('list','key3');
// $r->rpush('list','key5');

// $r->lpush('list2','2key1');
// $r->rpush('list2','2key2');
// $r->rpush('lis2t','2key3');
// $r->rpush('list2','2key5');


// $r->rp
// $r->linsert('list',Redis::BEFORE,'key1','def');
$range = $r->lrange('list',0,-1);
$range2 = $r->lrange('list2',0,-1);
// $trim = $r->ltrim('list',2,10);
$size = $r->lsize('list');
$lget = $r->lget('list',0);

// echo $size;
// var_dump($range);

$val = $r->rpoplpush('list','list2');
echo $val;
var_dump($range);
var_dump($range2);



//set
$r->sadd('set',123);
$r->sadd('set',456);
$r->sadd('set',789);
$r->srem('set',789);

$r->sadd('set2',123);
$r->sadd('set2',456);
$r->sadd('set2',789);

$r->smove('set2','set','789');

$set = $r->smembers('set');
$set2 = $r->smembers('set2');

$pop = $r->spop('set2');
$set2 = $r->smembers('set2');
echo '<pre>';
// echo $pop;
$num = $r->ssize('set');
$contain = $r->scontains('set','456');
$member = $r->srandMember('set');
// var_dump($member);
// var_dump($contain);
// echo $num;

var_dump($set);
// var_dump($set2);



$r->sadd('int',1);
$r->sadd('int',2);
$r->sadd('int',3);
$r->sadd('int',4);
$r->sadd('int',5);
$r->sadd('int',6);
$desc = $r->sort('int',array('sort'=>'desc'));
var_dump($desc);



$r->sadd('int2',5);
$r->sadd('int2',6);
$r->sadd('int2',7);
$r->sadd('int2',8);
$r->sadd('int2',9);
$r->sadd('int2',10);

$inter = $r->sinter('int','int2');
$uinon = $r->sunion('int','int2');
$diff = $r->sdiff('int2','int');

$diff = $r->sdiffstore('diffstore','int2','int');
// var_dump($inter);
// var_dump($uinon);
// var_dump($diff);

$re = $r->smembers('diffstore');
echo 'diffstore';
var_dump($re);

三、Memcache
set(key,val,compress,timeout) get delete flush flush_all close add replace
new connect
increment decrement
addServer(host,port,persist,weight,timeout,retry_intval,status,failecallback)

./memcached -m 256 -c 1000 -P -l 127.0.0.1 -p 11211 -u root -d /tmp/memcached.pid

getVersion getStats hit/cmd.. getExtendedStats getStatus


http:
 function MyCurl($url, $postfield='', $proxy='', $timeout=3, $format=0, $host=''){
        $proxy=trim($proxy);
        $user_agent ='Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)';
        $ch = curl_init(); // 初始化CURL句柄
        if(!empty($proxy)){
            curl_setopt ($ch, CURLOPT_PROXY, $proxy);//设置代理服务器
        }
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_URL, $url); //设置请求的URL
        //curl_setopt($ch, CURLOPT_FAILONERROR, 1); // 启用时显示HTTP状态码,默认行为是忽略编号小于等于400的HTTP信息
        //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);//启用时会将服务器服务器返回的“Location:”放在header中递归的返回给服务器
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);// 设为TRUE把curl_exec()结果转化为字串,而不是直接输出
        curl_setopt($ch, CURLOPT_POST, 0);//启用POST提交
        if($postfield){
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postfield); //设置POST提交的字符串
        }
        //curl_setopt($ch, CURLOPT_PORT, 80); //设置端口
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); // 超时时间
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);//HTTP请求User-Agent:头
        //curl_setopt($ch,CURLOPT_HEADER,1);//设为TRUE在输出中包含头信息
        //$fp = fopen('example_homepage.txt', 'w');//输出文件
        //curl_setopt($ch, CURLOPT_FILE, $fp);//设置输出文件的位置,值是一个资源类型,默认为STDOUT (浏览器)。
        $http_header = array(
                    'Accept-Language: zh-cn',
                    'Connection: Keep-Alive',
                    'Cache-Control: no-cache'
                    );
        if($host != false){
            $http_header[] = 'Host:'.$host;
        }
        curl_setopt($ch,CURLOPT_HTTPHEADER,$http_header);//设置HTTP头信息
        $data = curl_exec($ch); //执行预定义的CURL
        $info=curl_getinfo($ch); //得到返回信息的特性
        $httpCode =curl_getinfo($ch,CURLINFO_HTTP_CODE);
        $errorNo = curl_errno($ch);

        curl_close($ch);
        if(0==$format)
        {
            return $data;
        }
        elseif(1==$format)
        {
            return array(
                'data' => $data,
                'info' => $info,
                'errorNo' => $errorNo,
                'errorMsg' => '',
                'httpCode' => $httpCode
            );
        }

        if( $httpCode != '200' )
        {
            return $data;
        }
        else
        {
            return $httpCode;
        }
}



 
linux :+http://blog.sina.com.cn/s/blog_477071c50102vjde.html
 * 运维监控(nagios cacti)+测试(ab)
 * +第三方搜索(sphinx xunsou es)
 * +(数据+文件+代码)同步+异步(pcntl gearman curl ajax))
 * +负载均衡(http dns drdb) |代理(lvs,keepalived,haproxy,nginx,apache,heartbeat)
 * +存储(nfs mfs)
 
nginx 负载均衡亲测
在http节点里添加:
#定义负载均衡设备的 Ip及设备状态
upstream myServer {
server 127.0.0.1:9090 down;
server 127.0.0.1:8080 weight=2;
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup;
}
在需要使用负载的Server节点下添加
proxy_pass http://myServer;
upstream 每个设备的状态:
down 表示单前的server暂时不参与负载
weight 默认为1.weight越大,负载的权重就越大。
max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误
fail_timeout:max_fails 次失败后,暂停的时间。
backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻


http {
upstream my {
server tt.web.svn ;
}
server {
listen 8082;
root /var/www/html/eol_souky/code/trunk;
location / {
proxy_pass http://my;
#proxy_set_header X-Real-IP $remote_addr;
#root html;
index index.html index.htm index.php;
}
}
}

apache 负载均衡亲测
listen 8090
NameVirtualHost 192.168.1.104:8090
<VirtualHost 192.168.1.104:8090> #服务器IP地址
ServerAdmin sys-005@163.com
ProxyRequests Off #开启反向代理
ProxyMaxForwards 100
ProxyPreserveHost On
ProxyPass / balancer://proxy/

<Proxy balancer://proxy>
ProxySet lbmethod=bytraffic
Order Deny,Allow
Allow from all
BalancerMember http://192.168.1.60/ loadfactor=1
BalancerMember http://192.168.1.104:8082/ loadfactor=9 status= H
</Proxy>

</VirtualHost>




varnish
varnish
/usr/local/varnish/sbin/varnishd -f /etc/default.vcl -a 0.0.0.0:8080 -s malloc,256m -T 127.0.0.1:2000

#nginx
http {
server{
listen 80;
server_name my.souky.eol.cn;
location / {
proxy_pass http://127.0.0.1:8080;
}
}

server {
listen 8086;
server_name localhost;
root /var/www/html;
}

server {
listen 8010;
server_name my.souky.eol.cn;
root /var/www/html/eol_souky/code/trunk;
location / {
index index.html index.htm index.php;
}
}


##varnish
backend web1 {
.host = "127.0.0.1";
.port = "8010";
}
backend web2 {
.host = "127.0.0.1";
.port = "8086";
}

director test_director random{
{.backend = web2;.weight = 2;}
{.backend = web1;.weight = 8;}
}



sub vcl_recv
{
if (req.http.host ~ "my.souky.eol.cn") {
# set req.http.host = "my.souky.eol.cn";
# set req.backend = test_director;
set req.backend = test_director;
}


配置文件--启动脚本--生成日志--命中率查看--调优管理

模式
varnish是基于内存的缓存,vcl管理配置(receive--> look up->miss hit->fetch pass->fetch->delivery pipe),可以用stat等管理,比起squid有速度快、并发量高的特点

http
公用变量有,请求到达后可用,varnish向后端主机请求,cache或主机端请求,客户端应答几个节点都是http信息,如状态码、IP、端口、头部信息、新鲜度、缓存、url等。

缓存
配置vcl流程是,选择IP和端口,调用vcl_recv,根据http方法选择模式,根据域名和后缀进行缓存,添加header标识判断缓存是否命中;也能用来给多台web主机设定,选择一台用来指定负载权限,重点设计缓存,比如什么时候清除、什么时候读取和不读取、刷新缓存、缓存时间以及压缩内容

工具
varnishd启动参数(-T管理程序地址端口,-a varnish侦听地址端口,-s存储类型和容量 -f使用的配置文件)和日志,通过telnet和varnish清除不需要的缓存,查看varnish进程和缓存效果(curl -I url)来观察命中率和缓存效果,php脚本监测(命中与否、缓存和淘汰|过期数、累计请求数、缓存区头信息和正文长度等),通过这个来调优(linux系统--内核参数net ulimit varnish- thread pools min max timeout lru depth)

功用:图片防盗链 静态文件压缩






异步 : rabbitmq curl gearman pcntl_fork ajax

流程:vhosts-->connection-->channel-->exchange-->queue-->bind-->consume(callback)
类型 持久化 队列 消息响应 每次只发一条qos

send 交换机->publish(消息,路由)
$ex->setName($e_name);
$ex->publish($message . date('H:i:s'), $k_route[i%2]). //指定交换机,发布信息从指定的路由
receive 队列—> bind(交换机,路由)
$exchange->setName($exchangeName);
$queue->bind($exchangeName, $routeKey); //交换机通过路由绑定队列



一个Gearman请求的处理过程涉及三个角色:Client -> Job -> Worker。
Client:请求的发起者,可以是C,PHP,Perl,MySQL UDF等等。 dobackground 字符串
Job:请求的调度者,用来负责协调把Client发出的请求转发给合适的Work。
Worker:请求的处理者,可以是C,PHP,Perl等等。 while无限循环


准备工作已经完毕,试验开始
1、启动job
gearmand -d

2、启动worker
php -c /etc/php5/apache2/php.ini worker.php

3、启动client(新开终端中打开)
php -c /etc/php5/apache2/php.ini client.php

屏幕显示字符串的长度 “5”

这里,有几点需要说明一下:
1、这里直接用php cli方式运行,添加-c参数是为了加载php.ini配置文件,以加载gearman扩展
2、worker应该做成守护进程(CLI模式),可以开启多个,这样client发起的任务就会分发到各个worker分别来执行(自动负载均衡 )
这个例子由于太过简单,即使开启多个worker也无法看出效果,不过可以通过终止其中一个,可以看出系统自动切换到其他worker继续正常执行
3、同理,client也是可以开启多个的(模型请参考之前的那边日志)
4、同时,job也可以开启多个,以避免单点故障



$pid = pcntl_fork();
//父进程和子进程都会执行下面代码
if ($pid == -1) {
//错误处理:创建子进程失败时返回-1.
die('could not fork');
} else if ($pid) {
//父进程会得到子进程号,所以这里是父进程执行的逻辑
pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。
} else {
//子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
}


<?php
while(1)//循环采用3个进程
{
//declare(ticks=1);
$bWaitFlag= FALSE; // 是否等待进程结束
//$bWaitFlag = TRUE; // 是否等待进程结束
$intNum= 3; // 进程总数
$pids= array(); // 进程PID数组
for($i= 0; $i<$intNum; $i )
{
$pids[$i] = pcntl_fork();// 产生子进程,而且从当前行之下开试运行代码,而且不继承父进程的数据信息
if($pids[$i] == -1)
{
echo"couldn't fork". "\n";
}
elseif(!$pids[$i])
{
sleep(1);
echo"\n"."第".$i."个进程 -> ". time(). "\n";
//$url=" 抓取页面的例子
//$content = file_get_contents($url);
//file_put_contents('message.txt',$content);
//echo "\n"."第".$i."个进程 -> " ."抓取页面".$i."-> " . time()."\n";
exit(0);//子进程要exit否则会进行递归多进程,父进程不要exit否则终止多进程
}
if($bWaitFlag)
{
pcntl_waitpid($pids[$i], $status, WUNTRACED);echo"wait $i -> ". time() . "\n";
}
}
sleep(1);
}
?>


fork之后,操作系统会复制一个与父进程完全相同的子进程,虽说是父子关系,但是在操作系统看来,他们更像兄弟关系,这2个进程共享代码空间,但 是数据空间是互相独立的,子进程数据空间中的内容是“fork时”父进程的完整拷贝,指令指针也完全相同,但只有一点不同,如果fork成功,子进程中fork的返回值 是0,父进程中fork的返回值是子进程的进程号,如果fork不成功,父进程会返回错误。
可以这样想象,2个进程一直同时运行,而且步调一致,在fork之后,他们分别作不同的工作,也就是分岔了。这也是fork为什么叫fork的原因。

<?php
declare (ticks = 1);
$num = 5;//最大子进程数
$child = 0;//当前子进程数

//信号处理函数
function sig_handler($sig)
{
global $child;
switch ($sig) {
case SIGCHLD:
$child--;
echo 'SIGCHLD received! now we have '.$child.' process'.PHP_EOL;
break;
case SIGINT:
$child--;
echo 'SIGINT received! now we have '.$child.' process'.PHP_EOL;
break;
case SIGTERM:
$child--;
echo 'SIGTERM received! now we have '.$child.' process'.PHP_EOL;
break;
default:
# code...
break;
}
}

//安装信号处理器
pcntl_signal(SIGTERM, "sig_handler");//进程被kill时发出的信号
// pcntl_signal(SIGHUP, "sig_handler");//终端关闭时发出的信号
pcntl_signal(SIGINT, "sig_handler");//中断进程信号,如Ctrl C
pcntl_signal(SIGCHLD, "sig_handler");//进程退出信号

while(true)
{
$child ;
$parentpid = getmypid();
$pid = pcntl_fork();//一分为二,父进程和子进程都会执行以下代码
if($pid == -1)
{
exit("can not fork!");//出错
}else if($pid > 0){
//父进程处理代码
echo 'I am parent.my pid is'.$pid.' and my parent pid is'.$parentpid.PHP_EOL;
if($child >= $num)
{
pcntl_wait($status);//挂起,while语句不会继续执行。等待子进程结束,防止子进程成为僵尸进程
}
}else if($pid == 0){
//子进程代码
echo 'I am child, and my parent pid is '.$parentpid." my pid is ".getmypid()." now have $child process".PHP_EOL;
//执行具体代码
pcntl_exec('/usr/bin/php', array('/var/www/test/mywork.php'));

}
pcntl_signal_dispatch();//分发信号,使安装的信号处理器能接收。
//低于php5.3该函数无效,但有开头的declare (ticks = 1);表示每执行一条低级指令,
//就检查一次信号,如果检测到注册的信号,就调用其信号处理器
sleep(rand(3,5));//防止100%占用
}



http://blog.sina.com.cn/s/blog_640738130100u1pp.html
第一步:调用curl_multi_init
第二步:循环调用curl_multi_add_handle
这一步需要注意的是,curl_multi_add_handle的第二个参数是由curl_init而来的子handle。
第三步:持续调用curl_multi_exec
第四步:根据需要循环调用curl_multi_getcontent获取结果
第五步:调用curl_multi_remove_handle,并为每个字handle调用curl_close
第六步:调用curl_multi_close
这里有一个网上找的简单例子,其作者称为dirty的例子,(稍后我会说明为何dirty):

$connomains = array(
"http://www.cnn.com/",
"http://www.canada.com/",
"http://www.yahoo.com/"
);

$mh = curl_multi_init();

foreach ($connomains as $i => $url) {
$conn[$i]=curl_init($url);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,1);
curl_multi_add_handle ($mh,$conn[$i]);
}

do { $n=curl_multi_exec($mh,$active); } while ($active);

foreach ($connomains as $i => $url) {
$res[$i]=curl_multi_getcontent($conn[$i]);
curl_close($conn[$i]);
}

print_r($res);

把上面do的那段改成下面这样:
do {
$mrc = curl_multi_exec($mh,$active); } while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
因为$active要等全部url数据接受完毕才变成false,所以这里用到了curl_multi_exec的返回值判断是否还有数据,当有数据的时候就不停调用curl_multi_exec,暂时没有数据就进入select阶段,新数据一来就可以被唤醒继续执行。这里的好处就是CPU的无谓消耗没有了。
另外:还有一些细节的地方可能有时候要遇到:
控制每一个请求的超时时间,在curl_multi_add_handle之前通过curl_setopt去做:
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
判断是否超时了或者其他错误,在curl_multi_getcontent之前用:curl_error($conn[$i]);
http://blog.sina.com.cn/s/blog_640738130100u1pp.html





代码同步: svn 多版本库 多用户 多目录 | 命令 | 启动和配置 | hg流程和.hgignore..
流程:
1)部署服务—>配置文件—>日常使用
2)update->add->ci
命令行:
1)启动服务:
svnserve -d -r path
svnadmin create 版本库
2)配置文件:authz passwd svnserve
3)日常使用
add ci delete | ls log info diff
import export co lock/unlock update
revert switch resolved up

svnserve -d -r svn://localhost/svn
cd /var/www/html/svn
svnadmin create svna
svnadmin create svnb

svn co svn://localhost/svna ./
svn update
svn add file
svn del file
svn ci -m check
svn export svn://localhost/svna
svn lock file | svn unlock file
svn diff -r 5 ./here | ls info log


svn revert filename/dir (只是回退修改,不能回退版本,用update svn update -r 2)
svn resolved filename
svn import -m 'import' ./ookk svn://localhost/svna/ookk

svn sw svn://localhost/svna/branch ./ookk --ignore-ancestry (指向相同版本库的不同文件夹)
├── a
├── branch
│ ├── new
│ └── ookk
├── new
├── newnenew
└── ookk
├── new
└── ookk
├── new
└── ookk



19、新建一个分支copy
svn copy branchA branchB -m "make B branch" // 从branchA拷贝出一个新分支branchB
20、合并内容到分支merge
svn merge branchA branchB



mercrucial 流程
hg clone 我的线上
hg pull 主干线上
hg update 更新
hg update yuezh20140526
hg merge 我的default分支
hg ci -u -m 改变 yuezh20140526分支
hg push 我的线上

hg branch 分支
hg branches
[paths]default = https://hg.int.jumei.com/Finance_Group/yuezh-forkmaster = https://hg.int.jumei.com/Finance_Group/financedefault-push = https://yuezh@hg.int.jumei.com/Finance_Group/yuezh-fork
[auth]finance.prefix = https://hg.int.jumei.com/Finance_Group/yuezh-forkfinance.username = yuezhfinance.password = 123456
[hostfingerprints]hg.int.jumei.com = f2:8e:56:15:16:5e:de:fb:28:9c:18:8a:48:66:4a:09:e1:5b:3c:df






文件同步:rsync--数据同步实时,单向 ( inotify--异步触发 unison-双向同步)
数据库同步:mysql主从(互为主从)


Rsync:
rsync -vzrtopg —delete —progress 用户名@服务端IP::模块名 客户端同步文件位置 存放密码文件

客户端启动-mac:rsync -vzrtopg --delete --progress rsync@192.168.1.60::data /home/zhouy/rsync --password-file=/etc/rsync.pass



服务端启动-linux:rsync --daemon --config=/etc/rsyncd.conf
服务端配置:
uid=nobody
gid = nobody
pid file = /usr/local/rsync/rsyncd.pid
transfer logging = true
log format = %h %o %f %l %b
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
[code]
max connections = 5
path=/var/www/html
ignore errors
read only = no
write only = no
hosts allow = *
hosts deny = 10.5.3.77
auth users = rsync

secrets file = /etc/rsync.pass


[data]
max connections = 5
path=/Users/zhouyue/pack
ignore errors
read only = no
write only = no
hosts allow = *
hosts deny = 10.5.3.77
auth users = rsync

secrets file = /etc/rsync.pass


说明 :
服务端密码 /etc/rsync.pass 是 rsync:password
客户端密码 --password-file=/etc/rsync.pass 是 password

数据同步:mysql 主从
数据库主从同步之前要有相同的数据库
主库和从库要进行配置,有时候需要 set global server_id = 。。。这个是配置问题,待查
master
server-id = 2
log-bin=mysql-bin
log-slave-updates
slave-skip-errors=1062
binlog-do-db=sync
binlog-ignore-db=mysql

slave
server-id = 3
relay-log=mysqld-relay-bin

设置命令:
1.master ——grant replication slave on *.* to 用户名@192.168.0.2 identified by '密码'

2.master——show master status\G
*************************** 1. row ***************************
File: mysql-bin.000143
Position: 1208
Binlog_Do_DB: sync
Binlog_Ignore_DB: mysql
Executed_Gtid_Set:
1 row in set (0.00 sec)

3.slave——change master to master_host = '192.168.1.60',master_user=‘用户名',master_password='密码',master_log_file ='mysql-bin.000143',master_log_pos = 318;
'
4. slave——start slave 查看状态
Slave_IO_Running: Yes
Slave_SQL_Running: Yes



spinx 索引(增量 实时 索引和并) 分布式
1.安装mmseg coreseek
2.测试coreseek搜索和mmseg分词(创建全文索引 命令行检索 开启守护进程)
3.
--创建sphinx统计表,计数器(counter_id max_id);
--创建sphinx与mysql配置文件
-索引数据源 :匹配的字段,查询范围,替换计数器的数字,查询语句,查询范围
-索引 :分词字符集配置 索引文件路径
-增量索引 同上
-searchd服务:日志 进程号 最大匹配数量
4.脚本每5分钟跑一次增量索引,服务器空闲(半夜2:00)索引合并



指令:
1.找到启动的searchd服务,并关掉
ps -ef | grep searchd
kill -9 2407
2.启动新的searchd服务
/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/bin/new.conf
3.创建主索引
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/bin/new.conf --all --rotate
4.mysql添加数据
5.创建增量索引:/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/bin/new.conf delta --rotate
6.测试增量索引
/usr/local/coreseek/bin/search -c /usr/local/coreseek/bin/new.conf 熊猫
7.合并索引
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/bin/new.conf --merge goods delta --rotate --merge-dst-range deleted 0 0

说明:一般地,增量索引每5分钟跑一次,合并索引凌晨2:00合并一次就行了

实时 和并索引


添加自动运行脚本:
Java代码
$cd /usr/local/coreseek/etc/
$vi delta.sh
$/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conf delta --rotate >> /usr/local/coreseek/var/log/delta.log
$vi test1.sh /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conf --merge test1 delta --rotate >> /usr/local/coreseek/var/log/test1.log
$crontab -e * /1 * * * * /usr/local/coreseek/etc/delta.sh #每隔一分钟运行一次
30 2 * * * /usr/local/coreseek/etc/test1.sh #每天半夜2:30运行


保存并对delta.sh/test1.sh设权限 chmod 755;

#重启crond服务
Java代码
$service crond stop $service crond start

接下来可以查看log日志,或者搜索下delta索引;


增量索引
source goods
{
type = mysql

sql_host = localhost
sql_user = root
sql_pass = root
sql_db = sphinx
sql_port = 3306

sql_query =SELECT goods_id,goods_name,goods_color,goods_id as goods_new_id ,goods_name AS goods_name_search,goods_color AS goods_color_search From goods_test WHERE goods_id>=$start and goods_id <=$end and goods_id<=( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 ) ;
sql_attr_uint = goods_new_id //查询的信息
sql_attr_str2ordinal = goods_name //查询的信息
sql_attr_str2ordinal = goods_color //查询的信息
//查询语句
sql_query_info = SELECT * FROM goods_test Where goods_id = $id;
sql_query_pre = set names utf8
sql_query_pre = replace into sph_counter select 1,max(goods_id) from goods_test //把sph_counter中counter_id=1的数据中的max_doc_id 替换成最大值
sql_query_range = select 1,max(goods_id) from goods_test
}



index goods
{
source = goods
path = /usr/local/coreseek/var/data/goods
docinfo = extern
charset_dictpath = /usr/local/mmseg3/etc/
charset_type = zh_cn.utf-8
mlock = 0
morphology = none
min_word_len = 1
ngram_len = 1
min_infix_len = 1
}

source delta : goods
{
sql_query_pre = SET NAMES utf8
sql_query = SELECT goods_id, goods_name, goods_color, goods_id as goods_new_id ,goods_name AS goods_name_search,goods_color AS goods_color_search FROM goods_test WHERE goods_id>=$start and goods_id <=$end and goods_id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )
sql_query_post_index = replace into sph_counter select 1,max(goods_id) from goods_test //此查询在索引完全成功结束后执行
}

index delta:goods
{
source = delta
path = /usr/local/coreseek/var/data/goodsdelta

docinfo = extern
charset_type = zh_cn.utf-8
charset_dictpath = /usr/local/mmseg3/etc/
ngram_len = 0
mlock = 0
min_word_len = 1


}
indexer //全局index 定义
{
mem_limit = 128M
}


searchd
{
port = 9312
log = /usr/local/coreseek/var/log/searchd_new.log
query_log = /usr/local/coreseek/var/log/query_new.log
pid_file = /usr/local/coreseek/var/log/searchd.pid
max_matches = 1000
seamless_rotate = 1
preopen_indexes = 0
unlink_old = 1
read_timeout = 5
max_children = 30


}


分布式索引
index dist1 {
type = distributed
local = test1
agent = 172.xx.xx.xx:3312:test1//另一台机器上安装的sphinx
agent_connect_timeout = 1000
agent_query_timeout = 3000

}


索引--http://itsoul.iteye.com/blog/1581858

索引--http://blog.csdn.net/ms_x0828/article/details/7679229

指令--http://www.zzbaike.com/wiki/Sphinx/searchd命令参考

attr-http://www.cnblogs.com/iLoveMyD/archive/2012/06/27/2565310.html


elasticsearch
如果不用安装命令,也可以直接下载安装。
https://github.com/lukas-vlcek/bigdesk
 下载安装包。
1.在cmd命令行中进入安装目录,看是否有plugins目录,如果没有,则创建(第一次时,没有,需要创建)。
2.进入plugins目录,创建bigdesk目录
3.进入bigdesk目录,创建_site目录
4.解压下载的bigdesk-master.zip,将其bigdesk-master目录下的所有文件放入_site目录中。
5.再次重新启动elasticsearch。在浏览器中输入:http://localhost:9200/_plugin/bigdesk/查看结果。
本文固定链接:  http://www.chepoo.com/step-to-step-install-elasticsearch-on-windows.html | IT技术精华网


//example

    http://my.oschina.net/u/730537/blog/288703


    require_once('vendor/autoload.php');  

    function get_conn(){  

        $host = 'ip';  

        $dbname = 'dbname';  

        $user = 'user';  

        $passwd = 'passwd';  

      

        $conn = new PDO("pgsql:dbname=$dbname;host=$host",$user,$passwd);  

        return $conn;  

    }  

      

    function create_index(){  

        //Elastic search php client  

        $client = new Elasticsearch\Client();  

        $sql = "SELECT * FROM log";  

        $conn = get_conn();  

        $stmt = $conn->query($sql);  

        $rtn = $stmt->fetchAll();  

      

        //delete index which already created  

        $params = array();  

        $params['index'] = 'log_index';  

        $client->indices()->delete($params);  

          

        //create index on log_date,src_ip,dest_ip  

        $rtnCount = count($rtn);  

        for($i=0;$i<$rtnCount;$i++){  

            $params = array();  

            $params['body'] = array(  

                'log_date' => $rtn[$i]['log_date'],  

                'src_ip' => $rtn[$i]['src_ip'],  

                'dest_ip' => $rtn[$i]['dest_ip']  

            );  

            $params['index'] = 'log_index';  

            $params['type'] = 'log_type';  

              

            //Document will be indexed to log_index/log_type/autogenerate_id          

            $client->index($params);  

        }  

        echo 'create index done!';  

    }  

      

    function search(){  

        //Elastic search php client  

        $client = new Elasticsearch\Client();  

        $params = array();  

        $params['index'] = 'log_index';  

        $params['type'] = 'log_type';  

        $params['body']['query']['match']['src_ip'] = '1.122.33.141';  

      

        $rtn = $client->search($params);  

        var_dump($rtn);  

    }  

      

    set_time_limit(0);  

    //create_index();  

    search();  

    ?>  


//curd

//select
global $sysES;
        $clsEs             = new Es($sysES['default']);
        $arrSelect         = $clsEs->search(array( 'where' => $arrWhere, 'limit' => array( $this->_offset, $this->_pagesize ), 'order' => array( "houseCreate:desc", "_id:desc" ) ));
    
    
//insert
    if(is_array($data['newsSign']) && count($data['newsSign']) > 0)
        {
            $data['newsSign'] = self::arrayToString($data['newsSign']);
        }
        global $sysES;
        $indexName = $config['index'] ? $config['index'] : self::$index;
        $typeName  = $config['type'] ? $config['type'] : self::$type;
        $configs   = array( 'hosts' => $sysES['default']['hosts'], 'index' => $indexName, 'type' => $typeName );

        $res = $cache ? Es::instance($configs)->insert($data) : Es::instance($configs, false)->insert($data);


//bulk
$info = $client->bulk($bulkData);

//delete
global $sysES;
    $configs   = array( 'hosts' => $sysES['default']['hosts'], 'index' => 'cms', 'type' => 'news' );
    
    foreach($ids as $id) {
        $res = Es::instance($configs)->delete(array('id'=> CmsDynamic::LIST_TYPE.'_'.$id));
    }


//update
global $sysES;
            $params = $sysES['default'];
            $params['index'] = 'esf';
            $params['type'] = 'house';
            $client = new Es($params);
            $auditingInfo['failure'] = isset($arrUpdate['weigui_reason'])    ?    $arrUpdate['weigui_reason']    :    0;
            $intFlag = $client->update(array('id' => $houseId, 'data' => $client->houseFormat($auditingInfo)));


ab测试
同时处理 200个用户请求,总共访问5000次index.php
[root@my bin]# ./ab -n 5000 -c 200 http://localhost/index.php
Concurrency Level: 200
Time taken for tests: 16.108 seconds
Complete requests: 5000
Failed requests: 0
Write errors: 0
Total transferred: 270875000 bytes
HTML transferred: 270015000 bytes
Requests per second: 310.41 [#/sec] (mean) 每秒多少请求,服务器的吞吐量
Time per request: 644.301 [ms] (mean) 1/吞吐量=服务器平均处理时间
Time per request: 3.222 [ms] (mean, across all concurrent requests) 服务器平均处理时间
Transfer rate: 16422.53 [Kbytes/sec] received
######################################################
Requests per second 每秒多少请求,服务器的吞吐量
Time per request 服务器平均处理时间
1/吞吐量=服务器平均处理时间
######################################################




nfs:

centos:
yum install nfs nfs-utils portmap


mkdir /nfs_server

mkdir /nfs_server/upload


vim /etc/exports

/nfs_server/upload 192.168.1.*(rw,async,anonuid=500,anongid=500)


chkconfig nfs on

service nfs start


mount


mac:

sudo nfsd enable #确认NFSD服务开启

sudo nfsd update #刷新NFSD共享资源

showmount -e #显示当前共享的资源


mount -t nfs 192.168.0.2:/nfs_server


rsync -avz --progress --rsh=ssh root@ip:/rsync/dir  /nfs_server/upload/






细小知识点:


机制:绘图 时间戳 错误和异常 文件操作 mysql服务 会话清理  pdo事务 数组 魔术方法 字符编码
类:分页 pdo事务 session_handler  ajax原理  smarty_cache


绘图流程:
创建画布及其背景
创建字符串,并声明位置
输出字符串和文件格式
释放图像资源


绘制验证码:


private $width;                               //验证码图片的宽度
private $height;                               //验证码图片的高度
private $codeNum;                            //验证码字符的个数
private $checkCode;                           //验证码字符
private $image;                               //验证码画布


function showImage(){                       //通过访问该方法向浏览器中输出图像
$this->getCreateImage();                 //调用内部方法创建画布并对其进行初使化
$this->outputText();                     //向图像中输出随机的字符串
$this->setDisturbColor();                 //向图像中设置一些干扰像素
$this->outputImage();                    //生成相应格式的图像并输出


异常:
$e实际是异常的对象 
toSring 实际是预定义的错误信息删除
异常需要先抛出后 才能获取,这是php的机制,没有过多的内置异常,异常会被认为是错误


$e实际是异常的对象 
toSring 实际是预定义的错误信息删除
异常需要先抛出后 才能获取,这是php的机制,没有过多的内置异常,异常会被认为是错误
没有异常向下执行
有异常判断是自定义还是系统内置掉,自定义掉就要进行处理




时间戳:
mcrotime(true) 返回时间戳 
usleep 毫秒
$birthday = mktime (0, 0, 0, $month, $day, $year);   //将出生日期转变为UNIX时间戳
日期可超出 date("M-d-Y", mktime(0, 0, 0, 12, 36, 2007))."\n";  //日期超过31天,计算后输出Jan-05-2008 




错误提示:
ini_set('display_errors',1);  
error_reporting(E_ALL);




错误日志:
error_log("出现大麻烦了!", 1, "webmaster@www.mydomain.com");   //发送到管理员邮箱中
error_log("搞砸了!",   2,   "localhost:5000");       //发送到本机对应5000端口的服务器中
error_log("搞砸了!",   3,   "/usr/local/errors.log");   //发送到指定的文件中




文件处理流程:
from==>to    
is_file($filename)
file_exists($filename) 可用来判断目录是不是存在
opendir($path)=> readdir()=>except '. ..'=>is_dir->copydir | is_file copy
filefunction listDir($dir)
{
if(is_dir($dir))
    {
      if ($dh = opendir($dir)) 
{
        while (($file = readdir($dh)) !== false)
{
      if((is_dir($dir."/".$file)) && $file!="." && $file!="..")
{
      echo "<b><font color='red'>文件名:</font></b>",$file,"<br><hr>";
      listDir($dir."/".$file."/");
      }
else
{
          if($file!="." && $file!="..")
{
          echo $file."<br>";
      }
      }
        }
        closedir($dh);
      }
    }
}
//开始运行
listDir("./nowamagic");


文件属性:
目录或文件是不是存在
是文件还是目录
文件类型和大小(普通 目录 块 字符 命名 符号 未知 没有检测)
文件权限 读写执行
文件建立时间 更新时间和打开时间




文件操作:复制 删除 重命名 截取




fread 读取字节
ftell 文件指针
fopen 读取文件
flock($fp, LOCK_EX) 排他锁
flock($fp, LOCK_SH) 共享锁
flock($fp, LOCK_UN);释放锁
fclose


路径:pathnfo  dir base ext


文件上传:
$_FILES['myfile']['error'] : 
0 没有问题 
1 上传文件大小超出了PHP配置文件中的约定值:upload_max_filesiz
2 上传文件大小超出了表单中的约定值:MAX_FILE_SIZE
3 文件只被部分上载 
4 没有上传任何文件
$_FILES['myfile']['type']
$_FILES['myfile']['name']
is_uploaded_file($_FILES['myfile']['tmp_name'])
!move_uploaded_file($_FILES['myfile']['tmp_name'], $upfile)
$_FILES['myfile']['size']




mysql服务:
echo "与MySQL服务器建立的连接成功:<br>";          //连接成功则会输出这条提示信息
echo mysql_get_client_info().'<br>';                          //客户端API函数库的版本信息
echo mysql_get_host_info().'<br>';                           //与MySQL服务器的连接类型
echo mysql_get_proto_info().'<br>';                          //通信协议的版本信息
echo mysql_get_server_info().'<br>';                         //MySQL服务器的版本信息
echo mysql_client_encoding().'<br>';                         //客户端使用的默认字符集
echo mysql_stat().'<br>';                                   //MySQL服务器的当前工作状态
mysql_close($link);                                  //关闭与MySQL服务器建立的连接




会话处理:
session_start();                     //使用Cookie中现有的SessionID返回已经存在的Session
$username=$_SESSION["username"];               //从Session中获取登录用户名
$_SESSION = array();                             //删除所有Session的变量 
if (isset($_COOKIE[session_name()])) {             //判断是否是使用基于Cookie的Session
    setcookie(session_name(), '', time()-42000, '/');   //删除包含Session Id的Cookie
}
session_destroy();                              //最后彻底销毁Session




pdo处理:预处理 占位符 绑定参数 执行sql 返回结果 获取结果


事务处理:
start transaction
autocommit(0)
commit
rollback
autocommit(1)






在第一个表达式中初使化3个变量,它们之间使用逗号隔开。
在第三个表达式中,分别将三个变量设置成不同的增量值
在第二个表达式中,不管怎样编写,最后一定要是一个布尔值


自定义函数table()时,声明了三个参数,参数之间用逗号分隔
第一个参数需要一个字符串类型的表名
第二个参数是表格的行数需要一个整型数值
第三个参数是输出表格的列数也需要一个整数


数组处理:
while( list($key, $value) = each($contact)){  //将foreach语句改写成while、list()和each()的组合
echo "<dd> $key : $value </dd>";      //输出每个元素的键/值对
}




__isset __unset | isset unset
___set __get $this->name=value 自动调用 //可访问内部被封装的private属性
_autoload ==> new obj 自动加载 obj
__call($functionName, $args) {     //声明此方法用来处理调用对象中不存在的方法
__clone clone
self::CONSTANT."<br>";
echo MyClass::CONSTANT . "<br>";




继承关系中的重写
overwrite 完全重写   overload 重载,加载
function say() { 
parent::say();                         //调用父类中被本方法覆盖掉的方法
echo "在".$this->school."学校上学<br>";   //再原有的功能基础上多加一点功能
}
 




__sleep __wakeup  serialize unserialize


静态变量:
static $count;
self::$count
MyClass::$count
$myc3->getCount();






字符串操作: 去掉标签 转换为实体  ubb  同步换行




分页类:
<?php  header('Content-Type:text/html;charset=gbk');
class Page {                  //分页类
private $total;            //保存所有的数据表记录的总条数
private $page;            //保存当前第几页
private $num;            //设置每页显示记录的条数
private $pageNum;        //保存一共被分为多少页的数字
private $offset;           //保存从数据库中取记录的开始偏移数
          /* 该类的构造方法,创建对象时用来初使化成员属性 */
/* 参数total:需要提供一个据表的记录总数        */
/* 参数page:需要提供一个当前页面数             */
/* 参数num:需要提供每页显示记录的条数          */
function __construct($total, $page=1, $num=5) {
$this->total=$total;                    //为成员属性$total通过提供的参数初使化
$this->page=$page;                   //为成员属性$page通过提供的参数初使化
$this->num=$num;                   //为成员属性$num通过提供的参数初使化
$this->pageNum=$this->getPageNum();  //为属性$pageNum通过调用内部方法初使化
$this->offset=$this->getOffset();//为属性$offset通过调用内部方法初使化
}
private function getPageNum(){             //调用该方法返回计算后的页面总数
return ceil($this->total/$this->num);   //根据记录总数和每页显示记录的个数计算
}
private function getNextPage() {            //调用该方法返回下一页的页面索引
if($this->page==$this->pageNum)       //判断是否是最后一页
return false;                   //如果是最后一页,则没有下一页,返回false
else                                //如果有下一页
return $this->page+1;           //返回下一页的索引页面数字
}
private function getPrevPage() {            //调用该方法返回上一页的页面索引数字
if($this->page==1)                   //如果现在是第一页
return false;                   //没有上一页,则返回false
else                               //如果不是第一页,还存在上一页
return $this->page-1;           //返回上一页的页面索引数字
}
private function getOffset() {              //调用该方法返回数据库查询所需要的偏移量
return ($this->page-1)*$this->num;      //返回在数据表中开始查询的位置
}
private function getStartNum() {            //调用该方法返回当前页开始的记录偏移数
if($this->total==0)                  //如果数据表中没有记录
return 0;                       //返回0
else                               //如果数据表中有记录
return $this->offset+1;         //返回当前页开始的记录偏移数
}
private function getEndNum() {            //调用时返回当前页结束的记录偏移数
return min($this->offset+$this->num,$this->total);   //计算并返回结束的位置
}
          /* 该方法是唯一可以在对象外部调用的公有方法                */
/* 该方法会将所有和当前页面有关系的值放入一个数组一起返回  */
public function getPageInfo(){             
$pageInfo=array(                            //声明一个数组存放以下信息
"row_total" => $this->total,          //存放数据表中记录的总行数
"row_num" => $this->num,          //存放每页显示的行数
"page_num" => $this->getPageNum(),  //被分为的总页数信息
"current_page"=> $this->page,       //当前页面索引
"row_offset" => $this->getOffset(),     //当前页开始的偏移位置
"next_page" => $this->getNextPage(),  //下一页面的索引页面索引数字
"prev_page" => $this->getPrevPage(),    //上一页面的索引页面索引数字
"page_start" => $this->getStartNum(),   //当前页面开始的记录位置
"page_end" => $this->getEndNum()   //当前页面结束的页面位置
);
return $pageInfo;                   //将存放和当前页有关的所有信息数组返回
}
}
?>




if (!get_magic_quotes_gpc()) $value .= $k." = '".addslashes($v)."',";






/*
 * pdo 处理类
 */
try{
$pdo=new PDO("mysql:host=localhost;dbname=xsphpdb", "root", "123456", array(PDO::ATTR_AUTOCOMMIT=>0));
$pdo->setAttribute(PDO::ATTR_ERRMODE,  PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
echo "数据库连接失败:".$e->getMessage();
exit;
}


//执行SQL语句 exec() query()  prepare()
//一是有结果集的query(), 执行select语句
//exec()用来执行有影响行数的,update, delete insert, other
//exec()返回的是影响的行数
/*
*
* 事务处理
*
*   张三从李四那里买了一台 2000 元的电脑
*
*     从张三帐号中扣出 2000元
*
*     向李四账号中加入 2000元
*
*     从商品表中减少一台电脑
*
*     MyIsAM  InnoDB
*
*/


try{
$pdo->beginTransaction();

$price=500;


$sql="update zhanghao set price=price-{$price} where id=1";


$affected_rows=$pdo->exec($sql);


if(!$affected_rows)
throw new PDOException("张三转出失败");


$sql="update zhanghao set price=price+{$price} where id=3";


$affected_rows=$pdo->exec($sql);

if(!$affected_rows)
throw new PDOException("向李四转入失败");


echo "交易成功!";
$pdo->commit();
}catch(PDOException $e){
echo $e->getMessage();
$pdo->rollback();
}

$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);

//设置错误报告模式 ERRMODE_SILENT    ERRMODE_WARNING




<?php

//在运行session_start(); //启动
function open($save_path, $session_name){
global $sess_save_path;


$sess_save_path=$save_path;


return true;
}
//session_write_close()  session_destroy() 
function close(){
return true;
}
//session_start(), $_SESSION, 读取session数据到$_SESSION中
function read($id){
global $sess_save_path;
$sess_file=$sess_save_path."/glf_".$id;


return (string)@file_get_contents($sess_file);

}
//结束时和session_write_close()强制提交SESSION数据 $_SESSION[]="aaa";
function write($id, $sess_data){
global $sess_save_path;
$sess_file=$sess_save_path."/glf_".$id;


if($fp=@fopen($sess_file, "w")){
$return=fwrite($fp, $sess_data);
fclose($fp);
return $return;
}else{
return false;
}


}
//session_destroy()
function destroy($id){
global $sess_save_path;
$sess_file=$sess_save_path."/glf_".$id;


return @unlink($sess_file);
}


//ession.gc_probability和session.gc_divisor值决定的,open(), read() session_start也会执行gc
function gc($maxlifetime){
global $sess_save_path;

foreach(glob($sess_save_path."/glf_*") as $filename){
if(filemtime($filename)+$maxlifetime < time() ){
@unlink($filename);
echo $filename;
}
}


return true;
}


session_set_save_handler("open", "close", "read", "write", "destroy","gc");


session_start();




<script>
function createAjax(){
var request=false;

//window对象中有XMLHttpRequest存在就是非IE,包括(IE7,IE8)
if(window.XMLHttpRequest){
request=new XMLHttpRequest();


if(request.overrideMimeType){
request.overrideMimeType("text/xml");
}



//window对象中有ActiveXObject属性存在就是IE
}else if(window.ActiveXObject){

var versions=['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 'Msxml2.XMLHTTP.7.0','Msxml2.XMLHTTP.6.0','Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];


for(var i=0; i<versions.length; i++){
try{
request=new ActiveXObject(versions[i]);


if(request){
return request;
}
}catch(e){
request=false;
}
}
}
return request;
}


//注意: 要每次请求都要使用一个新的XMLHttpRequest
/*
如果使用get将数据传给服务器,则服务器就使用$_GET
就直接通过Url将数据传给服务器


使用POST时一定要使用 ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");



  */ 
var ajax=null;


function show(){
var helloobj=document.getElementById("hello");
ajax=createAjax();
ajax.onreadystatechange=function(){
if(ajax.readyState==4){
if(ajax.status==200){
var dom=ajax.responseXML;



var users=dom.getElementsByTagName("user");


alert(users.length);
}else{
alert("页面请求失败");
}
}
}


ajax.open("post", "users.xml", true);
ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ajax.send("username=lisi&email=1111111111");




}




</script>


<input type="button" onclick="show()" value="request">


<div style="width:500px;height:200px;background:yellow" id="hello">


</div>


function Ajax(recvType){
var aj=new Object();
aj.recvType=recvType ? recvType.toUpperCase() : 'HTML' //HTML XML
aj.targetUrl='';
aj.sendString='';
aj.resultHandle=null;


aj.createXMLHttpRequest=function(){
var request=false;

//window对象中有XMLHttpRequest存在就是非IE,包括(IE7,IE8)
if(window.XMLHttpRequest){
request=new XMLHttpRequest();


if(request.overrideMimeType){
request.overrideMimeType("text/xml");
}



//window对象中有ActiveXObject属性存在就是IE
}else if(window.ActiveXObject){

var versions=['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 'Msxml2.XMLHTTP.7.0','Msxml2.XMLHTTP.6.0','Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];


for(var i=0; i<versions.length; i++){
try{
request=new ActiveXObject(versions[i]);


if(request){
return request;
}
}catch(e){
request=false;
}
}
}
return request;
}


aj.XMLHttpRequest=aj.createXMLHttpRequest();


aj.processHandle=function(){
if(aj.XMLHttpRequest.readyState == 4){
if(aj.XMLHttpRequest.status == 200){
if(aj.recvType=="HTML")
aj.resultHandle(aj.XMLHttpRequest.responseText);
else if(aj.recvType=="XML")
aj.resultHandle(aj.XMLHttpRequest.responseXML);
}
}
}


aj.get=function(targetUrl, resultHandle){
aj.targetUrl=targetUrl;

if(resultHandle!=null){
aj.XMLHttpRequest.onreadystatechange=aj.processHandle;
aj.resultHandle=resultHandle;
}
if(window.XMLHttpRequest){
aj.XMLHttpRequest.open("get", aj.targetUrl);
aj.XMLHttpRequest.send(null);
}else{
aj.XMLHttpRequest.open("get", aj.targetUrl, true);
aj.XMLHttpRequest.send();
}

}


aj.post=function(targetUrl, sendString, resultHandle){
aj.targetUrl=targetUrl;


if(typeof(sendString)=="object"){
var str="";
for(var pro in sendString){
str+=pro+"="+sendString[pro]+"&";
}
aj.sendString=str.substr(0, str.length-1);
}else{
aj.sendString=sendString;
}


if(resultHandle!=null){
aj.XMLHttpRequest.onreadystatechange=aj.processHandle;
aj.resultHandle=resultHandle;
}


aj.XMLHttpRequest.open("post", targetUrl);
aj.XMLHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
aj.XMLHttpRequest.send(aj.sendString);

}


return aj;
}




1. Smarty是以变量为主的
2. 在Smarty模板中不是调用函数,是以自定义标记(类似于HTML标记)的使用形式
写函数就是自己定义一个类HTML标记
一种是使用注册的方式, 注册函数和块。 另一种是使用Smarty插件的功能加入函数和块
<?php
require "init.inc.php";






$tpl->register_function("hello", "demo");


function demo($args){
$html="";


for($i=0; $i<$args["num"]; $i++){
$html.='<font size="'.$args["size"].'" color="'.$args["color"].'">'.$args["content"]."</font><br>";
}


return $html;
}


$tpl->register_block("world", "test");

function test($args, $content, &$a, &$b){
$html="";


for($i=0; $i<$args["num"]; $i++){
$html.='<font size="'.$args["size"].'" color="'.$args["color"].'">'.$content."</font><br>";
}


return $html;
}


$tpl->assign("var", "@@@@@@@@@@");
$tpl->assign("color", "blue");
$tpl->assign("int", "#########");
$tpl->assign("arr", array("one"=>"9999", "8888"));


$tpl->display("test.tpl");






Smarty缓存和网页表态化一样, 使用Smarty缓存使用非常方便


1. 需要开启缓存
2. 指定一下缓存的时间
3. 指定缓存文件保存位置


开启这些内容只需要为Smarty的属性初使化即可


注意:
1. 一个模板只能有一个缓存文件,如果一个模板的多个文章,则需要每个文章有一个
缓存
$tpl->display("test.tpl", cacheid);


第二个参数,每变化一个值就会有一个不同的缓存(最好使用$_SERVER["REQUEST_URI"])



2. 一定要处理,如果有缓存了就不要执行连接数据库和到数据库中操作数据表了。


使用smarty中的is_cached()方去判断,它的用法和display()相同




局部缓存设置
使用一个块标记完成




清除缓存功能 




生成静态页:
$smarty->assign('content','hello world');替换 {$content}
$contect = $smarty->fetch('index.tpl');获取页面
$fp = fopen('index.html','w');写入
fwrite($fp,$content);
fclose($fp);








0 0