1.、SESSION 保存在服务器哪里?
答:SESSION 的数据保存在哪里呢?
当然是在服务器端,但不是保存在内存中,而是保存在文件或数据库中。
默认情况下,PHP.ini 中设置的 SESSION 保存方式是 files(session.save_handler = files
),即使用读写文件的方式保存 SESSION 数据,而 SESSION 文件保存的目录由 session.save_path
指定,文件名以 sess_ 为前缀,后跟 SESSION ID,如:sess_c72665af28a8b14c0fe11afe3b59b51b
。文件中的数据即是序列化之后的 SESSION 数据了。
如果访问量大,可能产生的 SESSION 文件会比较多,这时可以设置分级目录进行 SESSION 文件的保存,效率会提高很多,设置方法为:session.save_path="N;/save_path"
,N 为分级的级数,save_path 为开始目录。
当写入 SESSION 数据的时候,php 会获取到客户端的 SESSION_ID,然后根据这个 SESSION ID 到指定的 SESSION 文件保存目录中找到相应的 SESSION 文件,不存在则创建之,最后将数据序列化之后写入文件【3】。读取 SESSION 数据是也是类似的操作流程,对读出来的数据需要进行解序列化,生成相应的 SESSION 变量。
2、说出你所知道的数据库设计模式?常用的建模工具是什么?(mysql建模工具)
《1.主扩展模式
主扩展模式通常用来将几个相似的对象的共有属性抽取出来,形成一个”公共属性表“,且“公共属性表”与“专有属性表”是“一对一”的关系。
“专有属性表”可以看做是“公共属性表”的 扩展,两者合在一起就是对一个特定对象的完整描述,故此得名“主扩展模式”。
对象的个数不多;各个对象之间的属性有一定差别;各个对象的属性在数据库设计阶段能够完全确定;各个扩展对象有独立的、相对比较复杂的业务处理需求,此时用“主扩展模式”。将各个对象的共有属性抽取出来设计为“主表”,将各个对象的剩余属性分别设计为相应的“扩展表”,“主表”与各个“扩展表”分别建立一对一的关系。
《2.主从模式
主从模式,是数据库设计模式中最常见,也是大家日常设计工作中用的最多的一种模式,他描述了两个表之间的主从关系,是典型的一对多关系。
对象的个数较多且不固定;各个对象之间的属性几乎没有差异;对象的属性在数据库设计阶段能够完全确定;各个对象没有独立的业务处理需求,此时用“主从模式”。将各个对象设计为“从表”的记录,与“主表”对象建立一对多的关系。
《3.名值模式
名值模式,通常用来描述在系统设计阶段不能完全确定属性的对象,这些对象的属性在系统运行时会有很大的变更,或者是对个对象之间的属性存在很大的差异。
对象的个数极多;各个对象之间的属性有较大差异;对象属性在数据库设计阶段不能确定,或者在系统运行时有较大变更;各个对象没有相互独立的业务处理需求,此时用“名值模式”。
《4.多对多模式
多对多模式,也是比较常见的一种数据库设计模式,他所描述的两个对象部分主次,地位对等,互为一对多关系。
多对多模式需要在两个表之间建立一个关联表,这个关联表是多对多关系的核心。
两个对象之间互为一对多关系,则使用“多对多模式”。
====================================================
MySQL Workbench是一款专为MySQL设计的ER/数据库建模工具。它是著名的数据库设计工具DBDesigner4的继任者。你可以用MySQL Workbench设计和创建新的数据库图示,建立数据库文档,以及进行复杂的MySQL 迁移.
MySQL Workbench是下一代的可视化数据库设计、管理的工具,它同时有开源和商业化的两个版本。该软件支持Windows和Linux系统.
MySQL-Workbench:http://dev.mysql.com/downloads/windows/installer/ (windows版本)
MySQL-Workbench官网:http://www.mysql.com/products/workbench/
3、有些数据库设计为何出现字段冗余违规设计模式,请说出为何这么做?
冗余字段的存在到底是好还是坏呢?这是一个不好说的问题。可能在有人看来,这是一个很蹩脚的数据库设计。因为在数据库设计领域,有一个被大家必须遵守的数据库设计范式,这个范式理论上要求数据库设计逻辑清晰、关系明确,比如,”用户昵称”字段”username”本来属于表”user”,那么,表示”用户昵称”的字段就唯一的只应该属于”user”表的”username”字段,这样,当用户要修改昵称的时候,程序就只需要修改 user.username这个字段就行了,瞧,很方便。不过问题也随之而来,我在其他数据表(如订单orders表)里只存储了用户的ID,我要通过这个ID值得到用户昵称该怎么办呢?一个普遍的解决方法是通过联接(join),在查询时,通过id这个唯一条件联接两个表,从而取到用户的昵称。还有就是通过用户昵称筛选订单,也是需要join查询
这样确实是没问题,我也一直觉得这样是最好的方案,扩展方便,当要更新用户信息时,程序中要修改的地方很少,但是随着数据库里数据不断增加,百万,千万,同时,用户表的数据肯定也在不断的增加的,它可能是十万,百万。这个时候,你会发现两个表通过联接来取数据就显得相当费力了,可能你只需要取一个username这个用户昵称属性,你就不得不去联一下那个已经几十万的用户表进行检索,其速度可想而知了。
这个时候,你可以尝试把username这个字段加到orders这个订单表中,这样做的好事是,当你要通过订单表呈现一个订单列表时,涉及用户的部分可能就不需要再进行联接查询了。当然,有利就有弊,这样做的弊端就是,当你尝试更新用户信息时,你必须记得用户信息表里当前被更新的字段中,有哪些是冗余字段,分别属于哪些表,找到他们,然后加入到你的更新程序段中来。这个是程序中的开销,开销在开发人员的时间上了。至于这样做是否值得,就得看具体情况而定了。
所以,目前要创建一个关系型数据库设计,我们有两种选择:
1.尽量遵循范式理论的规约,尽可能少的冗余字段,让数据库设计看起来精致、优雅、让人心醉。
2.合理的加入冗余字段这个润滑剂,减少join,让数据库执行性能更高更快。
选择哪一种呢? 根据自己的实际业务需求
4、常用mysql 优化方式,尽可能多说。
《1、创建索引
对于查询占主要的应用来说,索引显得尤为重要。很多时候性能问题很简单的就是因为我们忘了添加索引而造成的,或者说没有添加更为有效的索引导致。如果不加索引的话,那么查找任何哪怕只是一条特定的数据都会进行一次全表扫描,如果一张表的数据量很大而符合条件的结果又很少,那么不加索引会引起致命的性能下降。但是也不是什么情况都非得建索引不可,比如性别可能就只有两个值,建索引不仅没什么优势,还会影响到更新速度,这被称为过度索引。
《2、复合索引
比如有一条语句是这样的:select * from users where area='beijing' and age=22;
如果我们是在area和age上分别创建单个索引的话,由于mysql查询每次只能使用一个索引,所以虽然这样已经相对不做索引时全表扫描提高了很多效率,但是如果在area、age两列上创建复合索引的话将带来更高的效率。如果我们创建了(area, age, salary)的复合索引,那么其实相当于创建了(area,age,salary)、(area,age)、(area)三个索引,这被称为最佳左前缀特性。因此我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。
《3、索引不会包含有NULL值的列
只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。
《4、使用短索引
对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的 列,如果在前10 个或20 个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。
《5、排序的索引问题
mysql查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
《6、like语句操作
一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。
《7、不要在列上进行运算
select * from users where YEAR(adddate)<2007;
将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成
select * from users where adddate<‘2007-01-01';
《8、不使用NOT IN和<>操作
NOT IN和<>操作都不会使用索引将进行全表扫描。NOT IN可以NOT EXISTS代替,id<>3则可使用id>3 or id<3来代替。
5、怎样判断select 语句是否使用了索引?
我先用一个普通的 select语句,用explain解析,看看有什么显示:
explain select * from zje;
主要关注的是,type 和 key:
type = ALL :表示全表扫描
type = const :表示通过索引一次就找到了
key = NULL:表示没有使用索引
key = primary :表示使用了主键
key一般=使用了主键/索引的名字
6、memcache与mongoDB 、Redis 各自的使用场景是什么?
数据存储
- MongoDB的存储格式是文档类型,是一种类型json的格式,这样有机会对某些字段建立索引,可以简单的模仿一下关系型数据库,而且MongoDB确实也有db,table的概念
- Memcache的存储格式是Key-Value模式,但是很遗憾的是,Value的格式只能是字符串,这也限制了Memcache的应用范围
- Redis的存储格式和Memcache一样,也是Key-Value模式,但是Redis有另外的实现,除了基本的string类型,redis还实现了hash,list,set,zset数据类型
安全验证
- Redis有权限验证,不过是全局的,一号在手,天下我有
- Mongo的权限验证类似RBAC,给不同的库建立了不同的账号,并分配账号权限
- Memcache没有自己的权限验证,只能通过防火墙等手段限制
数据有效期
- Redis可以给key添加过期时间,这里需要注意的是,这个过期时间是针对顶级key的,意味着你不能给list里面某个单独元素或者hash里面的单独字段设置时间
- Memcache也是可以设置过期时间的,这里推荐使用时间戳来设置,避免30天的那个界限。
- MongoDB本身其实可以看作是一个数据仓库了,不存在过去时间这一说
数据持久化
- Redis本身支持两种持久化,快照和AOF追加方式
- Mem很遗憾,并没有持久化功能,断电就GG
- MongoDB,你就当他是数据库吧!
特色功能
- Redis没发现
- Memcache多用于分布式缓存,通过addserver的方式,将不同的键保存到不同的服务器上面,一台GG也不影响其他的服务器,当然这里面也就存在一个问题,各个服务器的数据不同步
- MongoDB有很典型的主从复制,现在官方主推副本集
应用场景
- Memcached:动态系统中减轻数据库负载,提升性能;做缓存,适合多读少写,大数据量的情况(如人人网大量查询用户信息、好友信息、文章信息等)。
- Redis:适用于对读写效率要求都很高,数据处理业务复杂和对安全性要求较高的系统(如新浪微博的计数和微博发布部分系统,对数据安全性、读写要求都很高)。
- MongoDB:主要解决海量数据的访问效率问题。
其他
- Memcached单个key-value大小有限,一个value最大只支持1MB,而Redis最大支持512MB
- Memcached只是个内存缓存,对可靠性无要求;而Redis更倾向于内存数据库,因此对对可靠性方面要求比较高
- 从本质上讲,Memcached只是一个单一key-value内存Cache;而Redis则是一个数据结构内存数据库,支持五种数据类型,因此Redis除单纯缓存作用外,还可以处理一些简单的逻辑运算,Redis不仅可以缓存,而且还可以作为数据库用
- 新版本(3.0)的Redis是指集群分布式,也就是说集群本身均衡客户端请求,各个节点可以交流,可拓展行、可维护性更强大。
- MongoDB不支持事务。
7、什么是队列?
8、请说出mysql常用的存储引擎?memory 存储引擎的特点?
9、你用过多少开源框架?说说它们之间的优劣?
10、你所知道的缓存技术有哪些?分别做下简单介绍
11、 js 闭包是什么?
12、php 中魔术方法你了解哪些?请举例说明各自的用法?
13、写出开发过程中你经常使用的数组或字符串函数
14、回答PHP 读取文件数度快、还是读取mysql 的数据快?为何?
15、怎么判断一个值是否存在于数组?
16、下面的输出结果会是怎样?
$x = 5;
echo $x;
echo "<br/>";
echo $x++ + $x++;
echo "<br/>";
echo $x;
echo "<br/>";
echo $x-- - $x--;
echo "<br>";
echo $x;
答案:5 ,11,7,1,5
17、请问 $a 和 $b 的值各为多少?
$a = "1";
$b = &$a;
$b = "2$b";
echo $a."<br/>";
echo $b;
答案:21,21
18、下面是ture 还是false
var_dump(0123 == 123);
var_dump("0123" == 123);
var_dump("0123" === 123);
答案:bool(false) ,bool(true) ,bool(false)
19、请设计一个数据结构可以实现无限级子菜单的树型菜单功能并提供菜单生成算法,用UML描述设计并写出相关设计逻辑