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、定点数
浮点型在数据库中存放的是近似值,而定点类型在数据库中存放的是精确值。 4、字符串(char,varchar,_text) char和varchar: 5.二进制数据(_Blob) 1._BLOB和_text存储方式不同,_TEXT以文本方式存储,英文存储区分大小写,而_Blob是以二进制方式存储,不分大小写。 6.日期时间类型 若定义一个字段为timestamp,这个字段里的时间数据会随其他字段修改的时候自动刷新,所以这个数据类型的字段可以存放这条记录最后被修改的时间。 数据类型的属性 表列出了各种数值类型以及它们的允许范围和占用的内存空间。 类型 大小 范围(有符号) 范围(无符号) 用途 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的值 小数值 在 MySQL 中支持的 5 个主要整数类型是 TINYINT,SMALLINT,MEDIUMINT,INT 和 BIGINT。这些类型在很大程度上是相同的,只有它们存储的值的大小是不相同的。 MySQL 以一个可选的显示宽度指示器的形式对 SQL 标准进行扩展,这样当从数据库检索一个值时,可以把这个值加长到指定的长度。例如,指定一个字段的类型为 INT(6),就可以保证所包含数字少于 6 个的值从数据库中检索出来时能够自动地用空格填充。需要注意的是,使用一个宽度指示器不会影响字段的大小和它可以存储的值的范围。 万一我们需要对一个字段存储一个超出许可范围的数字,MySQL 会根据允许范围最接近它的一端截短后再进行存储。还有一个比较特别的地方是,MySQL 会在不合规定的值插入表前自动修改为 0。 UNSIGNED 修饰符规定字段只保存正值。因为不需要保存数字的正、负符号,可以在储时节约一个“位”的空间。从而增大这个字段可以存储的值的范围。 ZEROFILL 修饰符规定 0(不是空格)可以用来真补输出的值。使用这个修饰符可以阻止 MySQL 数据库存储负值。 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 类型用于定长字符串,并且必须在圆括号内用一个大小修饰符来定义。这个大小修饰符的范围从 0-255。比指定长度大的值将被截短,而比指定长度小的值将会用空格作填补。 CHAR 类型可以使用 BINARY 修饰符。当用于比较运算时,这个修饰符使 CHAR 以二进制方式参于运算,而不是以传统的区分大小写的方式。 CHAR 类型的一个变体是 VARCHAR 类型。它是一种可变长度的字符串类型,并且也必须带有一个范围在 0-255 之间的指示器。CHAR 和 VARCHGAR 不同之处在于 MuSQL 数据库处理这个指示器的方式:CHAR 把这个大小视为值的大小,不长度不足的情况下就用空格补足。而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度(增加一个额外字节来存储字符串本身的长度)来存储值。所以短于指示器长度的 VARCHAR 类型不会被空格填补,但长于指示器的值仍然会被截短。 因为 VARCHAR 类型可以根据实际内容动态改变存储值的长度,所以在不能确定字段需要多少字符时使用 VARCHAR 类型可以大大地节约磁盘空间、提高存储效率。 VARCHAR 类型在使用 BINARY 修饰符时与 CHAR 类型完全相同。 对于字段长度要求超过 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 混合日期和时间值,时间戳 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 个数字表示的年份。 除了日期和时间数据类型,MySQL 还支持 DATEYIME 和 TIMESTAMP 这两种混合类型。它们可以把日期和时间作为单个的值进行存储。这两种类型通常用于自动存储包含当前日期和时间的时间戳,并可在需要执行大量数据库事务和需要建立一个调试和审查用途的审计跟踪的应用程序中发挥良好作用。 如果我们对 TIMESTAMP 类型的字段没有明确赋值,或是被赋与了 null 值。MySQL 会自动使用系统当前的日期和时间来填充它。 MySQL 还支持两种复合数据类型 ENUM 和 SET,它们扩展了 SQL 规范。虽然这些类型在技术上是字符串类型,但是可以被视为不同的数据类型。一个 ENUM 类型只允许从一个集合中取得一个值;而 SET 类型允许从一个集合中取得任意多个值。 ENUM 类型因为只允许在集合中取得一个值,有点类似于单选项。在处理相互排拆的数据时容易让人理解,比如人类的性别。ENUM 类型字段可以从集合中取得一个值或使用 null 值,除此之外的输入将会使 MySQL 在这个字段中插入一个空字符串。另外如果插入值的大小写与集合中值的大小写不匹配,MySQL 会自动使用插入值的大小写转换成与集合中大小写一致的值。 ENUM 类型在系统内部可以存储为数字,并且从 1 开始用数字做索引。一个 ENUM 类型最多可以包含 65536 个元素,其中一个元素被 MySQL 保留,用来存储错误信息,这个错误值用索引 0 或者一个空字符串表示。 MySQL 认为 ENUM 类型集合中出现的值是合法输入,除此之外其它任何输入都将失败。这说明通过搜索包含空字符串或对应数字索引为 0 的行就可以很容易地找到错误记录的位置。 SET 类型与 ENUM 类型相似但不相同。SET 类型可以从预定义的集合中取得任意数量的值。并且与 ENUM 类型相同的是任何试图在 SET 类型字段中插入非预定义的值都会使 MySQL 插入一个空字符串。如果插入一个即有合法的元素又有非法的元素的记录,MySQL 将会保留合法的元素,除去非法的元素。 一个 SET 类型最多可以包含 64 项元素。在 SET 元素中值被存储为一个分离的“位”序列,这些“位”表示与它相对应的元素。“位”是创建有序元素集合的一种简单而有效的方式。并且它还去除了重复的元素,所以 SET 类型中不可能包含两个相同的元素。 希望从 SET 类型字段中找出非法的记录只需查找包含空字符串或二进制值为 0 的行。 mysql -h 主机地址 -u 用户名 -p 用户密码 ================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 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 放在数据更新之前 在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 #题意不明,写法了解下,就是找出对应的字段,也是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 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============================= 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 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、查询男生、女生人数 30、查询同名同性学生名单,并统计同名人数 缓存 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
decimal(m,d) 参数m<65 是总个数,d<30且 d
MySQL数据类型
含义
char(n)
固定长度,最多255个字符
varchar(n)
固定长度,最多65535个字符
tinytext
可变长度,最多255个字符
text
可变长度,最多65535个字符
mediumtext
可变长度,最多2的24次方-1个字符
longtext
可变长度,最多2的32次方-1个字符
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的索引似乎不起作用。
2._BLOB存储的数据只能整体读出。
3._TEXT可以指定字符集,_BLO不用指定字符集。
MySQL数据类型
含义
date
日期 '2008-12-2'
time
时间 '12:25:36'
datetime
日期时间 '2008-12-2 22:06:44'
timestamp
自动存储记录修改时间
MySQL关键字
含义
NULL
数据列可包含NULL值
NOT NULL
数据列不允许包含NULL值
DEFAULT
默认值
PRIMARY KEY
主键
AUTO_INCREMENT
自动递增,适用于整数类型
UNSIGNED
无符号
CHARACTER SET name
指定一个字符集
浮点数值
浮点数值
INT 类型
FLOAT、DOUBLE 和 DECIMAL 类型
字符串类型
CHAR 和 VARCHAR 类型
TEXT 和 BLOB 类型
日期和时间类型
(字节)
DATE、TIME 和 TEAR 类型
DATEYIME 和 TIMESTAMP 类型
复合类型
ENUM 类型
SET 类型
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 老师
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)
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、号课的平均成绩;
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;
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
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;
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;
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
$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 '';
// 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 '';
$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 '';
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 '';
$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 '';
// $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 '';
// 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
ServerAdmin [email protected]
ProxyRequests Off #开启反向代理
ProxyMaxForwards 100
ProxyPreserveHost On
ProxyPass / 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
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, 所以这里是子进程执行的逻辑。
}
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的原因。
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://[email protected]/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 [email protected]::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, "[email protected]"); //发送到管理员邮箱中
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 "文件名:",$file,"