yulu

普通PHP面试遇到的问题7

问题:
mysql的索引

mysql常见索引:

  • B-Tree 索引:最常见的索引类型,大部分引擎都支持B树索引。
  • HASH 索引:只有Memory引擎支持,使用场景简单。
  • R-Tree 索引(空间索引):空间索引是MyISAM的一种特殊索引类型,主要用于地理空间数据类型。
  • Full-text (全文索引):全文索引也是MyISAM的一种特殊索引类型,主要用于全文索引,InnoDB从MYSQL5.6版本提供对全文索引的支持。

B-TREE索引类型:
普通索引
这是最基本的索引类型,而且它没有唯一性之类的限制。普通索引可以通过以下几种方式创建:
(1)创建索引: CREATE INDEX 索引名 ON 表名(列名1,列名2,…);
(2)修改表: ALTER TABLE 表名ADD INDEX 索引名 (列名1,列名2,…);
(3)创建表时指定索引:CREATE TABLE 表名 ( […], INDEX 索引名 (列名1,列名 2,…) );
UNIQUE索引
表示唯一的,不允许重复的索引,如果该字段信息保证不会重复例如身份证号用作索引时,可设置为unique:
(1)创建索引:CREATE UNIQUE INDEX 索引名 ON 表名(列的列表);
(2)修改表:ALTER TABLE 表名ADD UNIQUE 索引名 (列的列表);
(3)创建表时指定索引:CREATE TABLE 表名( […], UNIQUE 索引名 (列的列表) );
主键:PRIMARY KEY索引
主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。
(1)主键一般在创建表的时候指定:“CREATE TABLE 表名( […], PRIMARY KEY (列的列表) ); ”。
(2)但是,我们也可以通过修改表的方式加入主键:“ALTER TABLE 表名ADD PRIMARY KEY (列的列表); ”。
每个表只能有一个主键。 (主键相当于聚合索引,是查找最快的索引)
注:不能用CREATE INDEX语句创建PRIMARY KEY索引

写一个函数,算出两个文件的相对路径如 $a = ‘/a/b/c/d/e.php’; $b = ‘/a/b/12/34/c.php’; 计算出 $b 相对于 $a 的相对路径应该是 ../../c/d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function getRelativePath($a, $b) {
$relativePath = "";
$pathA = explode('/', dirname($a));
$pathB = explode('/', dirname($b));
$n = 0;
$len = count($pathB) > count($pathA) ? count($pathA) : count($pathB);
do {
if ( $n >= $len || $pathA[$n] != $pathB[$n] ) {
break;
}
} while (++$n);
//str_repeat — 重复一个字符串
$relativePath .= str_repeat('../', count($pathB) - $n);
//array_splice — 去掉数组中的某一部分并用其它值取代
$relativePath .= implode('/', array_splice($pathA, $n));
return $relativePath;
}
$res = getRelativePath($a, $b);
var_dump($res);
根据网盘设计一个数据库

主要考虑后续用户删除目录的时候,如何操作。

PHP的多进程

pcntl_fork()

mysql的时间字段设置成什么类型

可以有三种类型存储,包括:timestamp,datetime以及直接存int类型的unix时间戳。

  • int: int首先存成int字段的话如果考虑微秒的情况是不好存储的,其次不便于查看。
  • timestamp: timestamp 更适合来记录时间,比如我在东八区时间现在是 2016-08-02 10:35:52, 你在日本(东九区此时时间为 2016-08-02 11:35:52),我和你在聊天,数据库记录了时间,取出来之后,对于我来说时间是 2016-08-02 10:35:52,对于日本的你来说就是 2016-08-02 11:35:52。所以就不用考虑时区的计算了。但是timestamp所能标示的时间范围是硬伤,只能表示1970-2038。
  • datetime: datetime占8个字节,timestamp占4个字节。所以datetime的时间范围是1000-01-01 00:00:00 ~ 9999-12-31 23:59:59,比timestamp时间范围大很多。其次datetime是不受时区影响的。
mysql的查询语句的优化
  • 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
  • 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
  • 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
    select id from t where num is null
    可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
    select id from t where num=0
  • 尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描
  • 应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。
mysql的慢查询

MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10S以上的语句。

  • 查看慢查询日志是否开启
    show variables like ‘%slow’;
  • 开启慢查询日志,默认关闭,mysql需要重启。
    show variables like ‘%slow_query_log%’;
数据库的分区
  • 垂直分区:将一张表中值比较大的字段拆分出来,形成新的表
  • 水平分区:复制一张相同结构的表