PHP小接
一种是innodb,一种是myisam,两者的主要区别是
①myisam不支持事务处理,而innoDB支持事务处理
②myisam 不支持外键,innoDB支持外键
③myisam支持全文检索,而innoDB在MySQL5.6版本之后才支持全文检索
④数据的存储形式不一样,mysiam表存放在三个文件:结构、索引、数据,innoDB存储把结构存储为一个文件,索引和数据存储为一个文件
⑤myisam在查询和增加数据性能更优于innoDB,innoDB在批量删除方面性能较高。
⑥myisam支持表锁,而innoDB支持行锁
mysql优化怎么做的?
??
①设计角度:存储引擎的选择,字段类型选择,范式
??
②功能角度:可以利用mysql自身的特性,如索引,查询缓存,碎片整理,分区、分表等
??
③sql语句的优化方面:尽量简化查询语句,能查询字段少就尽量少查询字段,优化分页语句、分组语句等。
??
④部署大负载架构体系:数据库服务器单独出来,负载大时可以采用主从复制,读写分离机制进行设计
??
⑤从硬件上升级数据库服务器
单例模式
private static $_instance;
private function __construct(){}
private function __clone(){}
public static function get_instance(){}
接口安全方面是怎么处理的
我们当时是这么做的,使用HTTP的POST方式,对固定参数+附加参数进行数字签名,使用的是md5加密,比如:我想通过标题获取一个信息,在客户端使用 信息标题+日期+双方约定好的一个key通过md5加密生成一个签名(sign),然后作为参数传递到服务器端,服务器端使用同样的方法进行校验,如何接受过来的sign和我们通过算法算的值相同,证明是一个正常的接口请求,我们才会返回相应的接口数据。
用户不登录,怎么直接加入购物车的
用户在不登录的情况下,可以把要购买商品的信息(如商品的ID,商品的价格、商品的sku_id,购买数量等关键数据)存到COOKIE里面,当登陆的情况下。把COOKIE里面的内容存到数据库,并清除cookie中的数据。
如何处理负载、高并发
1、HTML静态化
其实大家都知道,效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的 网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。
2、图片服务器分离
把图片单独存储,尽量减少图片等大流量的开销,可以放在一些相关的平台上,如骑牛等
3、数据库集群和库表散列及缓存数据库的并发连接为100,一台数据库远远不够,可以从读写分离、主从复制,数据库集群方面来着手。另外尽量减少数据库的访问,可以使用缓存数据库如memcache、redis。
4、镜像:尽量减少下载,可以把不同的请求分发到多个镜像端。
5、负载均衡:
Apache的最大并发连接为1500,只能增加服务器,可以从硬件上着手,如F5服务器。当然硬件的成本比较高,我们往往从软件方面着手。
echo(),print(),print_r()的区别
echo可以一次输出多个值,多个值之间用逗号分隔。echo是语言结构(language construct),而并不是真正的函数,因此不能作为表达式的一部分使用。
echo是php的内部指令,不是函数,无返回值。
print():函数print()打印一个值(它的参数),如果字符串成功显示则返回true,否则返回false。只能打印出简单类型变量的值(如int,string),有返回值
printf():源于C语言中的printf()。该函数输出格式化的字符串。
print_r()和var_dump()
print_r()可以把字符串和数字简单地打印出来,而数组则以括起来的键和值得列表形式显示,并以Array开头。但print_r()输出布尔值和NULL的结果没有意义,因为都是打印"\n"。因此用var_dump()函数更适合调试。print_r是函数,可以打印出比较复杂的变量(如数组,对象),有返回值
var_dump()判断一个变量的类型与长度,并输出变量的数值,如果变量有值输的是变量的值并回返数据类型。此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。
Linux基本命令,目录结构
文件搜索?
find / -name file1?从?'/'开始进入根文件系统搜索文件和目录?
locate \*.ps?寻找以?'.ps'结尾的文件?-先运行'updatedb'命令?
whereis halt?显示一个二进制文件、源码或man的位置?
which halt?显示一个二进制文件或可执行文件的完整路径?
磁盘空间?
df -h?显示已经挂载的分区列表?
ls -lSr |more?以尺寸大小排列文件和目录?
du -sh dir1?估算目录?'dir1'已经使用的磁盘空间'?
下载、解压
1)对于.tar结尾的文件?
tar -xf all.tar?
2)对于.gz结尾的文件?
gzip -d all.gz?
gunzip all.gz?
# zip all.zip *.jpg?
这条命令是将所有.jpg的文件压缩成一个zip包?
# unzip all.zip?
这条命令是将all.zip中的所有文件解压出来
下载命令
wget +?空格?+要下载文件的url路径
魔术方法、魔术常量
1。__construct()
实例化对象时被调用,当__construct和以类名为函数名的函数同时存在时,__construct将被调用,另一个不被调用。
2。__destruct()
当删除一个对象或对象操作终止时被调用。
3。__call()
对象调用某个方法,若方法存在,则直接调用;若不存在,则会去调用__call函数。
4。__get()
读取一个对象的属性时,若属性存在,则直接返回属性值;若不存在,则会调用__get函数。
5。__set()
设置一个对象的属性时,若属性存在,则直接赋值;若不存在,则会调用__set函数。
6。__toString()
打印一个对象的时被调用。如echo $obj;或print $obj;
7。__clone()
克隆对象时被调用。如:$t=new Test();$t1=clone $t;
8。__sleep()
serialize之前被调用。若对象比较大,想删减一点东东再序列化,可考虑一下此函数。
9。__wakeup()
unserialize时被调用,做些对象的初始化工作。
10。__isset()
检测一个对象的属性是否存在时被调用。如:isset($c->name)。
11。__unset()
unset一个对象的属性时被调用。如:unset($c->name)。
12。__set_state()
调用var_export时,被调用。用__set_state的返回值做为var_export的返回值。
13。__autoload()
实例化一个对象时,如果对应的类不存在,则该方法被调用。
魔术常量:
1。__LINE__
返回文件中的当前行号。
2。__FILE__
返回文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自?PHP 4.0.2?起,__FILE__?总是包含一个绝对路径,而在此之前的版本有时会包含一个相对路径。
3。__FUNCTION__
返回函数名称(PHP 4.3.0?新加)。自?PHP 5?起本常量返回该函数被定义时的名字(区分大小写)。在PHP 4?中该值总是小写字母的。
4。__CLasS__
返回类的名称(PHP 4.3.0?新加)。自?PHP 5?起本常量返回该类被定义时的名字(区分大小写)。在PHP 4?中该值总是小写字母的。
5。__METHOD__
返回类的方法名(PHP 5.0.0?新加)。返回该方法被定义时的名字(区分大小写)。
__set()当程序试图写入一个不存在或者不可见的成员变量时,__set()方法包含两个参数,分别表示变量名称和变量值,两个参数都不可省略
__get()当程序试图调用一个未定义或不可见的成员变量时,__get()方法有一个参数,表示要调用的变量名
__sleep()?常用于提交未提交的数据,或类似的清理操作如果有一些很大的对象,但不需要全部保存,这个功能就很好用。
__construct() ?在类实例化对象的同时执行该函数
__distruct()?在类实例化的对象销毁时执行
__call()对象调用某个方法,若方法存在,则直接调用;若不存在,则会去调用__call函数。
__clone()克隆对象时被调用。如:$t=new Test();$t1=clone $t;
__toString()打印一个对象的时被调用。如echo $obj;或print $obj;
__isset()检测一个对象的属性是否存在时被调用。如:isset($c->name)。
__unset()unset一个对象的属性时被调用。如:unset($c->name)。
__autoload()实例化一个对象时,如果对应的类不存在,则该方法被调用。
字符串反转
给定字符串abcdef,写出反转函数,将字符串反转为fedcba.?
function?myStrReve($str){??
????
$len?=?strlen($str);??
????
$result?=?'';???
????
for($i?=?$len?-?1;?$i?>=0?;?$i--?){??
???????
?$result?.=?$str[$i];??
????
}?????
????
return?$result;??
}??
mysql共享锁与排他锁
mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流。
共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
排他锁又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
对于共享锁大家可能很好理解,就是多个事务只能读数据不能改数据,对于排他锁大家的理解可能就有些差别,我当初就犯了一个错误,以为排他锁锁住一行数据后,其他事务就不能读取和修改该行数据,其实不是这样的。排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁。mysql InnoDB引擎默认的修改数据语句,update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型,如果加排他锁可以使用select ...for update语句,加共享锁可以使用select ... lock in share mode语句。所以加过排他锁的数据行在其他事务种是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select ...from...查询数据,因为普通查询没有任何锁机制
MySQL的四种事务隔离级别
https://www.cnblogs.com/huanongying/p/7021555.html
一、事务的基本要素(ACID)
1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。
二、事务的并发问题
1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
三、MySQL事务隔离级别
事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted) 是 是 是
不可重复读(read-committed) 否 是 是
可重复读(repeatable-read) 否 否 是
串行化(serializable) 否 否 否
mysql默认的事务隔离级别为repeatable-read
Mysql事务与redis事务的区别
默认状态
MySQL:
MySQL会默认开启一个事务,且缺省设置是自动提交,即,每成功执行一个SQL,一个事务就会马上 COMMIT。所以不能Rollback。
Redis:
Redis默认不会开启事务,即command会立即执行,而不会排队。并不支持Rollback(详情可见:Redis之坑:理解Redis事务 )
事务命令
mysql:
begin #显式地开启一个事务
commit #提交事务,对数据库进行的所有写操作变为永久性的
rollback #结束用户的事务,并撤销正在进行的所有未提交的写操作
redis支持简单的事务:
multi #标记事务的开始
exec #执行事务的
commands队列
discard #结束事务,并清除commands队列
https://blog.csdn.net/github_26672553/article/details/82892233
主键索引和唯一索引的区别
主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键。
唯一性索引列允许空值,而主键列不允许为空值。
主键列在创建时,已经默认为空值 + 唯一索引了。
主键可以被其他表引用为外键,而唯一索引不能。
一个表最多只能创建一个主键,但可以创建多个唯一索引。
主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等。
在 RBO 模式下,主键的执行计划优先级要高于唯一索引。 两者可以提高查询的速度。
Mysql各种索引区别:
普通索引:最基本的索引,没有任何限制
唯一索引:与"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。
主键索引:它 是一种特殊的唯一索引,不允许有空值。
全文索引:仅可用于 MyISAM 表,针对较大的数据,生成全文索引很耗时好空间。
组合索引:为了更多的提高mysql效率可建立组合索引,遵循”最左前缀“原则。
mysql创建索引的原则
1.选择唯一性索引
唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。例如,学生表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的信息。如果使用姓名的话,可能存在同名现象,从而降低查询速度。
2.为经常需要排序、分组和联合操作的字段建立索引
经常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作会浪费很多时间。如果为其建立索引,可以有效地避免排序操作。
3.为常作为查询条件的字段建立索引
如果某个字段经常用来做查询条件,那么该字段的查询速度会影响整个表的查询速度。因此,为这样的字段建立索引,可以提高整个表的查询速度。
4.限制索引的数目
索引的数目不是越多越好。每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大。修改表时,对索引的重构和更新很麻烦。越多的索引,会使更新表变得很浪费时间。
5.尽量使用数据量少的索引
如果索引的值很长,那么查询的速度会受到影响。例如,对一个CHAR(100)类型的字段进行全文检索需要的时间肯定要比对CHAR(10)类型的字段需要的时间要多。
6.尽量使用前缀来索引
如果索引字段的值很长,最好使用值的前缀来索引。例如,TEXT和BLOG类型的字段,进行全文检索会很浪费时间。如果只检索字段的前面的若干个字符,这样可以提高检索速度。
7.删除不再使用或者很少使用的索引
表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再需要。数据库管理员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响。
8 . 最左前缀匹配原则,非常重要的原则。
mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a 1=”” and=”” b=”2” c=”“> 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
9 .=和in可以乱序。
比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式
10 . 尽量选择区分度高的列作为索引。
区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就 是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条 记录
11 .索引列不能参与计算,保持列“干净”。
比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本 太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’);
12 .尽量的扩展索引,不要新建索引。
比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可
注意:选择索引的最终目的是为了使查询的速度变快。上面给出的原则是最基本的准则,但不能拘泥于上面的准则。读者要在以后的学习和工作中进行不断的实践。根据应用的实际情况进行分析和判断,选择最合适的索引方式。
Mysql explain的每项说明
1、id
每个被独立执行的操作的标识,表示对象被操作的顺序;id值大,先被执行;如果相同,执行顺序从上到下。
若没有子查询和联合查询,id则都是1。Mysql会按照id从大到小的顺序执行query,在id相同的情况下,则从上到下执行。
2、select_type
查询中每个select子句的类型
(1)SIMPLE
(2)PRIMARY/UNION
(3)DEPENDENT UNION/UNIOIN RESULT
(4)SUBQUERY/DEPENDENT SUBQUERY
(5)DERIVED/MATERIALIZED
(6)UNCACHEABLE SUBQUERY/UNCACHEABLE UNION
3、table
名字,被操作的对象名称,通常是表名,或者表的别名,或者一个为查询产生临时表的标示符(如派生表、子查询、集合)。
4、type
代表查询执行计划中表使用的连接方式。
连接操作类型及级别:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般来说,得保证查询至少达到range级别,最好能达到ref。
5、partitions
匹配的分区信息(对于非分区表值为NULL)。
6、possible_keys
备选的索引(列出可能被使用到的索引)
7、key
经优化器选定的索引;常用ANALYZE TABLE命令,可以使优化器正确地选择索引。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
8、key_len
被优化器选定的索引键的长度,单位是字节。
9、ref
表示本行被操作的对象的参照对象(被参照的对象可能是一个常量用const表示,也可能是其他表的key指向的对象)。
10、rows
查询执行所扫描的元组个数(对于InnoDB,此值是估计值)。
11、filtered
按照条件表上数据被过滤的元组个数的百分比,rows×filtered/100可以求出过滤后的元组数即实际的元组数。
12、Extra
(1)using where
(2)using temporary
(3)using filesort
(4)using index
(5)using join buffer
(6)impossible where
(7)select tables optimized away
(8)distinct
mysql索引的原理
一 索引原理
索引的目的在于提高查询效率,与我们查阅图书所用的目录是一个道理:先定位到章,然后定位到该章下的一个小节,然后找到页数。相似的例子还有:查字典,查火车车次,飞机航班等
本质都是:通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。
数据库也是一样,但显然要复杂的多,因为不仅面临着等值查询,还有范围查询(>、<、between、in)、模糊查询(like)、并集查询(or)等等。数据库应该选择怎么样的方式来应对所有的问题呢?我们回想字典的例子,能不能把数据分成段,然后分段查询呢?最简单的如果1000条数据,1到100分成第一段,101到200分成第二段,201到300分成第三段......这样查第250条数据,只要找第三段就可以了,一下子去除了90%的无效数据。但如果是1千万的记录呢,分成几段比较好?稍有算法基础的同学会想到搜索树,其平均复杂度是lgN,具有不错的查询性能。但这里我们忽略了一个关键的问题,复杂度模型是基于每次相同的操作成本来考虑的。而数据库实现比较复杂,一方面数据是保存在磁盘上的,另外一方面为了提高性能,每次又可以把部分数据读入内存来计算,因为我们知道访问磁盘的成本大概是访问内存的十万倍左右,所以简单的搜索树难以满足复杂的应用场景。
Mysql优化的思路?
Mysql的优化,大体可以分为三部分:索引的优化,sql语句的优化,表的优化
1.索引的优化
只要列中含有NULL值,就最好不要在此例设置索引,复合索引如果有NULL值,此列在使用时也不会使用索引
尽量使用短索引,如果可以,应该制定一个前缀长度
对于经常在where子句使用的列,最好设置索引,这样会加快查找速度
对于有多个列where或者order by子句的,应该建立复合索引
对于like语句,以%或者‘-’开头的不会使用索引,以%结尾会使用索引
尽量不要在列上进行运算(函数操作和表达式操作)
尽量不要使用not in和<>操作
2.sql语句的优化
查询时,能不要*就不用*,尽量写全字段名
大部分情况连接效率远大于子查询
多使用explain和profile分析查询语句
查看慢查询日志,找出执行时间长的sql语句优化
多表连接时,尽量小表驱动大表,即小表 join 大表
在千万级分页时使用limit
对于经常使用的查询,可以开启缓存
3.表的优化
表的字段尽可能用NOT NULL
字段长度固定的表查询会更快
把数据库的大表按时间或一些标志分成小表
将表分区
操作系统优化
sysbench 工具
1.测试CPU性能
2.测试IO读写性能
3.测试事务性能
数据库系统参数优化
1.使用 show processlist命令长时间查看服务器负载情况
2.开启服务器慢查询开关
3.减少临时表使用,可以EXPLAIN 语法查看 extra 是否为 using temporary
@如果group by 的列没有索引,会产生内部临时表
@如果order by 与 group by为不同列时,或多表联查时 order by,group by 包含的列不是第一张表的列,会产生外部临时表
@如果distinct 与 order by 一起使用可能会产生临时表
@如果用union合并查询会用到临时表
@如果表中数据过大,可能会把临时表转存在磁盘上处理
数据表设计
1.表结构拆分,核心字段与非核心字段或长文本字段最好拆出单一张表
2.字段选取规则:整形->data,time->enum,char->varchar->text->blob
3.字段长度设定,够用就行杜绝浪费
4.尽量避免用NULL(),不利于索引查询,要用特殊的字节来标注,占有磁盘空间较大。
索引设计,myisam与innodb默认使用B-tree索引
1.建议建立单个索引,避免建立组合索引
2.索引值,或主键值应尽量是连续增长的整型值,不是随机值
3.要建立适当的索引对象,过多的索引会影响插入和更新速度,同时占用内存
4.对于左前缀不易区分的列,要分析数据内容找出最容易区别的部分放在前面,(比如,要url倒过来存储,后缀都不一样)
5.索引碎片维护,长期的数据更改过程中, 索引文件和数据文件,都将产生空洞,形成碎片
4.注意索引的左前缀原则,范围截断原则(or 条件,只要其中一个没有都不会用索引)
建立组合索引index(a,b,c) 为例:
语句
索引是否发挥作用
Where a=3
是,只使用了a列
Where a=3 and b=5
是,使用了a,b列
Where a=3 and b=5 and c=4
是,使用了abc
Where b=3 ?or ?where c=4
否
Where a=3 and c=4
a列能发挥索引,c不能
Where a=3 and b>10 and c=7
a能利用,b能利用, c不能利用 ? ? ? ? ? ? ? ? ? ? ??
同上,where a=3 and b like ‘xxxx%’ and c=7 ? ?
a能用,b能用,c不能用
建立多个单列索引index(a),index(b),index(c)
Where a=3
是,只使用了a列
Where a=3 and b=5
是,使用了a,b列
Where a=3 and b=5 and c=4
是,使用了abc
Where b=3 ?or ?where c=4
bc使用
Where a=3 and c=4
ac都使用
Where a=3 and b>10 and c=7
a能利用,b能利用, c不能利用 ? ? ? ? ? ? ? ? ? ? ? ?
同上,where a=3 and b like ‘xxxx%’ and c=7 ? ?
a能用,b用,c不能用
Mysql索引不生效场景总结
1. 跳过列,where a = 1 and c = 3,最多用到索引列a;where b = 2 and c = 3,一个也用不到,必须从最左列开始
2. 前面是范围查询,where a = 1 and b > 2 and c = 3,最多用到 a, b两个索引列;
3. 顺序颠倒,where c = 3 and b = 2 and a = 1,一个也用不到;
4. 索引列上使用了表达式,如where substr(a, 1, 3) = 'hhh',where a = a + 1,表达式是一大忌讳,再简单mysql也不认。有时数据量不是大到严重影响速度时,一般可以先查出来,比如先查所有有订单记录的数据,再在程序中去筛选以'cp1001'开头的订单,而不是写sql过滤它;
5. 模糊匹配时,like '%a'
6. 如果 MySQL 估计使用索引比全表扫描更慢,则不使用索引。例如如果列key_part1 均匀分布在 1 和 100 之间,下列查询中使用索引就不是很好:SELECT * FROM table_name where key_part1 > 1 and key_part1 < 90;
7. 用 or 分割开的条件,如果 or 前的条件中的列有索引,而后面的列中没有索引,那么涉及到的索引都不会被用到,必须两个字段都得是索引才能使用到索引
8. 如果列类型是字符串,那么一定记得在 where 条件中把字符常量值用引号引起来,否则的话即便这个列上有索引,MySQL 也不会用到的,因为,MySQL 默认把输入的常量值进行转换以后才进行检索。如下面的例子中 company2 表中的 name字段是字符型的,但是 SQL 语句中的条件值 294 是一个数值型值,因此即便在 name 上有索引,MySQL 也不能正确地用上索引,而是继续进行全表扫描;explain select * from company2 where name = 294\G; explain select * from company2 where name = '294'
9. 查看索引使用情况 show status like 'Handler_read%';
10. show status like 'Com_%'; Com_select:执行 select 操作的次数,一次查询只累加 1。Com_insert:执行 INSERT 操作的次数,对于批量插入的 INSERT 操作,只累加一次。Com_update:执行 UPDATE 操作的次数。Com_delete:执行 DELETE 操作的次数。
11. Innodb_rows_read:select 查询返回的行数。Innodb_rows_inserted:执行 INSERT 操作插入的行数。Innodb_rows_updated:执行 UPDATE 操作更新的行数。Innodb_rows_deleted:执行 DELETE 操作删除的行数。
12. Connections:试图连接 MySQL 服务器的次数。Uptime:服务器工作时间。Slow_queries:慢查询的次数
13. show processlist 命令查看当前 MySQL 在进行的线程,包括线程的状态、是否锁表等,可以实时地查看 SQL 的执行情况,同时对一些锁表操作进行优化。
14. 查看索引使用情况:show status like 'Handler_read%';
15. 定期分析和检查表,如果感觉分析表:本语句用于分析和存储表的关键字分布,分析的结果将可以使得系统得到准确的统计信息,使得 SQL 能够生成正确的执行计划。如果用户感觉实际执行计划并不是预期的执行计划,执行一次分析表可能会解决问题。 检查表:可以检查表或视图是否由错误(表删除之后,视图可能仍然存在);优化表:如果已经删除了表的一大部分,或者如果已经对含有可变长度行的表(含有 VARCHAR、BLOB 或 TEXT 列的表)进行了很多更改,则应使用 OPTIMIZE TABLE 命令来进行表优化。 ANALYZE、CHECK、OPTIMIZE 执行期间将对表进行锁定,因此一定注意要在数据库不繁忙的时候执行相关的操作。
16. show status like 'Handler_read%'; 查看'Handler_read_key ' 和 'Handler_read_rnd_next' 两个值的大小来评判索引效果是否明显;
sql语句优化
1.尽量使用索引覆盖,加快查询速度(查询只需要在索引文件上进行,不需要回行到磁盘再找数据)
2.在大数据范围查找时,尽量在索引覆盖上面查找到需要的索引id,然后在通过id去查到对应的数据
3.尽量减少查询次数,能用业务逻辑处理的功能,都用算法处理。
4.利用explain来利用分析
hash索引为什么不能作为数据存储原因:
1.hash函数计算后的结果,是随机的,如果是在磁盘上放置数据,比主键为id为例, 那么随着id的增长, id对应的行,在磁盘上随机放置
2.无法对范围查询进行优化
3.无法利用前缀索引
4.排序无法优化
5.必须回行.就是说 通过索引拿到数据位置,必须回到表中取数据
工厂模式
工厂模式,工厂方法或者类生成对象,而不是在代码中直接new。
使用工厂模式,可以避免当改变某个类的名字或者方法之后,在调用这个类的所有的代码中都修改它的名字或者参数。
1 Test1.php
2 <?php
3 class Test1{
4 static function test(){
5 echo __FILE__;
6 }
7 }
8
9 Factory.php
10 <?php
11 class Factory{
12 /*
13 * 如果某个类在很多的文件中都new ClassName(),那么万一这个类的名字
14 * 发生变更或者参数发生变化,如果不使用工厂模式,就需要修改每一个PHP
15 * 代码,使用了工厂模式之后,只需要修改工厂类或者方法就可以了。
16 */
17 static function createDatabase(){
18 $test = new Test1();
19 return $test;
20 }
21 }
22
23 Test.php
24 <?php
25 spl_autoload_register('autoload1');
26
27 $test = Factory::createDatabase();
28 $test->test();
29 function autoload1($class){
30 $dir = __DIR__;
31 $requireFile = $dir."\\".$class.".php";
32 require $requireFile;
33 }
HTTP与HTTPS有什么差异
1、HTTPS是加密传输协议,HTTP是名文传输协议;
2、HTTPS需求用到SSL证书,而HTTP不用;
3、HTTPS比HTTP更加安全,对查找引擎更友好,利于SEO
4、HTTPS规范端口443,HTTP规范端口80;
5、HTTPS基于传输层,HTTP基于使用层;
6、HTTPS在浏览器显现绿色安全锁,HTTP没有显现;
由于HTTP协议传输的数据都是未加密的,很有可能被人盗取或篡改,因而使用HTTP协议传输隐私信息十分不安全。
短信防刷
图片验证
单IP请求次数限制
手机号限制
1、时间限制:60秒后才能再次发送
从发送验证码开始,前端(客户端)会进行一个60秒的倒数,在这一分钟之内,用户是无法提交多次发送信息的请求的。这种方法虽然使用得比较普遍,但是却不是非常有用,技术稍微好点的人完全可以绕过这个限制,直接发送短信验证码。
2、手机号限制:同一个手机号,24小时之内不能够超过5条
对使用同一个手机号码进行注册或者其他发送短信验证码的操作的时候,系统可以对这个手机号码进行限制,例如,24小时只能发送5条短信验证码,超出限制则进行报错(如:系统繁忙,请稍后再试)。然而,这也只能够避免人工手动刷短信而已,对于批量使用不同手机号码来刷短信的机器,这种方法也是无可奈何的。
3、短信验证码限制:30分钟之内发送同一个验证码
网上还有一种方法说:30分钟之内,所有的请求,所发送的短信验证码都是同一个验证码。第一次请求短信接口,然后缓存短信验证码结果,30分钟之内再次请求,则直接返回缓存的内容。对于这种方式,不是很清楚短信接口商会不会对发送缓存信息收取费用,如果有兴趣可以了解了解。
4、前后端校验:提交Token参数校验
这种方式比较少人说到,个人觉得可以这种方法值得一试。前端(客户端)在请求发送短信的时候,同时向服务端提交一个Token参数,服务端对这个Token参数进行校验,校验通过之后,再向请求发送短信的接口向用户手机发送短信。
5、唯一性限制:微信产品,限制同一个微信ID用户的请求数量
如果是微信的产品的话,可以通过微信ID来进行识别,然后对同一个微信ID的用户限制,24小时之内最多只能够发送一定量的短信。
6、产品流程限制:分步骤进行
例如注册的短信验证码使用场景,我们将注册的步骤分成2步,用户在输入手机号码并设置了密码之后,下一步才进入验证码的验证步骤。
7、图形验证码限制:图形验证通过后再请求接口
用户输入图形验证码并通过之后,再请求短信接口获取验证码。为了有更好的用户体验,也可以设计成:一开始不需要输入图形验证码,在操作达到一定量之后,才需要输入图形验证码。具体情况请根据具体场景来进行设计。
8、IP及Cookie限制:限制相同的IP/Cookie信息最大数量
使用Cookie或者IP,能够简单识别同一个用户,然后对相同的用户进行限制(如:24小时内最多只能够发送20条短信)。然而,Cookie能够清理、IP能够模拟,而且IP还会出现局域网相同IP的情况,因此,在使用此方法的时候,应该根据具体情况来思考。
9、短信预警机制,做好出问题之后的防护
以上的方法并不一定能够完全杜绝短信被刷,因此,我们也应该做好短信的预警机制,即当短信的使用量达到一定量之后,向管理员发送预警信息,管理员可以立刻对短信的接口情况进行监控和防护。
以上所说到的方式,或许不是很完美,但是可以通过多个方式结合着来作使用,通过多个规则来降低短信被刷的风险。
(问群里的人)
php做APP接口时,如何保证接口的安全性?
1、当用户登录APP时,使用https协议调用后台相关接口,服务器端根据用户名和密码时生成一个access_key,并将access_key保存在session中,将生成的access_key和session_id返回给APP端。
2、APP端将接收到的access_key和session_id保存起来
3、当APP端调用接口传输数据时,将所传数据和access_key使用加密算法生成签名signature,并将signature和session_id一起发送给服务器端。
4、服务器端接收到数据时,使用session_id从session中获取对应的access_key,将access_key和接收到的数据使用同一加密算法生成对应signature,如果生成的签名和接收到的signature相同时,则表明数据合法
oauth2.0
https://www.cnblogs.com/flashsun/p/7424071.html
mysql获取版本号
select versio();
mysql获取用户名和主机名组合函数
select user(),current_user(), system_user();
查询mysq数据库性能参数
show status like ‘value’;
其中value是参数值常用如下:
connections :连接mysql服务器次数;
uptime: mysql 服务器上线时间;
slow queries: 慢查询次数
com_select: 查询操作的次数
com_insert: 查询插入的次数
com_delete:updata....
举例子:show status like 'slow_queries';
//字符串“open_door” 转换成 “OpenDoor”、”make_by_id” 转换成 ”MakeById”。
function str_change($str) {
$strr = str_replace('_','',$str);
$strr = ucwords($strr);//将单词首字母变大写
$strr = str_replace(' ','',$strr);
return $strr;
}
$aa = str_change('open_door');
var_dump($aa);
php数组函数
array
array_combine
array_merge
array_chunk
array_filp
array_keys
array_push 插入末尾
array_pop 删除最后一个
array_shift 删除第一个
array_unshift 开头插入
array_column 返回输入数组中某个单一列的值。
array_key_exists 判断某个数组中是否存在指定的key
array_unique 去重
常见的HTTP相应状态码
返回的状态
1xx:指示信息--表示请求已接收,继续处理
2xx:成功--表示请求已被成功接收、理解、接受
3xx:重定向--要完成请求必须进行更进一步的操作
4xx:客户端错误--请求有语法错误或请求无法实现
5xx:服务器端错误--服务器未能实现合法的请求
200:请求被正常处理
204:请求被受理但没有资源可以返回
206:客户端只是请求资源的一部分,服务器只对请求的部分资源执行GET方法,相应报文中通过Content-Range指定范围的资源。
301:永久性重定向
302:临时重定向
303:与302状态码有相似功能,只是它希望客户端在请求一个URI的时候,能通过GET方法重定向到另一个URI上
304:发送附带条件的请求时,条件不满足时返回,与重定向无关
307:临时重定向,与302类似,只是强制要求使用POST方法
400:请求报文语法有误,服务器无法识别
401:请求需要认证
403:请求的对应资源禁止被访问
404:服务器无法找到对应资源
500:服务器内部错误
503:服务器正忙
echo "今天:".date("Y-m-d")."<br>";
echo "昨天:".date("Y-m-d",strtotime("-1 day")), "<br>";
echo "明天:".date("Y-m-d",strtotime("+1 day")). "<br>";
echo "一周后:".date("Y-m-d",strtotime("+1 week")). "<br>";
echo "一周零两天四小时两秒后:".date("Y-m-d G:H:s",strtotime("+1 week 2 days 4 hours 2 seconds")). "<br>";
echo "下个星期四:".date("Y-m-d",strtotime("next Thursday")). "<br>";
echo "上个周一:".date("Y-m-d",strtotime("last Monday"))."<br>";
echo "一个月前:".date("Y-m-d",strtotime("last month"))."<br>";
echo "一个月后:".date("Y-m-d",strtotime("+1 month"))."<br>";
echo "十年后:".date("Y-m-d",strtotime("+10 year"))."<br>";