PHP中高级面试题 – 第三天一、简述一下MongoDB的应用场景
mongodb 支持副本集、索引、自动分片php数据库为什么要分表,可以保证较高的性能和可用性 。
更高的写入负载
默认情况下 , MongoDB 更侧重高数据写入性能,而非事务安全,MongoDB 很适合业务系统中有大量 “低价值” 数据的场景 。但是应当避免在高事务安全性的系统中使用 MongoDB,除非能从架构设计上保证事务安全 。
高可用性
MongoDB 的复副集 (Master-Slave) 配置非常简洁方便,此外 , MongoDB 可以快速响应的处理单节点故障,自动、安全地完成故障转移 。这些特性使得 MongoDB 能在一个相对不稳定(如云主机)的环境中 , 保持高可用性 。
数据量很大或者未来会变得很大
依赖数据库 (MySQL) 自身的特性,完成数据的扩展是较困难的事,在 MySQL 中,当一个单达表到 5-10GB 时会出现明显的性能降级,此时需要通过数据的水平和垂直拆分、库的拆分完成扩展,使用 MySQL 通常需要借助驱动层或代理层完成这类需求 。而 MongoDB 内建了多种数据分片的特性,可以很好地适应大数据量的需求 。
基于位置的数据查询
MongoDB 支持二维空间索引,因此可以快速及精确地从指定位置获取数据 。
表结构不明确
在一些传统 RDBMS 中,增加一个字段会锁住整个数据库 / 表,或者在执行一个重负载的请求时会明显造成其它请求的性能降级 。通常发生在数据表大于 1G 的时候(当大于 1TB 时更甚) 。因 MongoDB 是文档型数据库,为非结构货的文档增加一个新字段是很快速的操作,并且不会影响到已有数据 。另外一个好处当业务数据发生变化时,是将不再需要由 DBA 修改表结构 。
二、数据库设计经验,为什么进行分表php数据库为什么要分表?分库?一般多少数据量开始分表?分库?分库分表的目的?
1、为什么要分表
当一张表的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,有可能会死在那儿了 。分表的目的就在于此,减小数据库的负担,缩短查询时间 。日常开发中php数据库为什么要分表我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表 。这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下 , 如果涉及联合查询的情况,性能会更加糟糕 。
分表和表分区的目的就是减少数据库的负担 , 提高数据库的效率,通常点来讲就是提高表的增删改查效率 。数据库中的数据量不一定是可控的,在未进行分库分表的情况下,随着时间和业务的发展,库中的表会越来越多 , 表中的数据量也会越来越大 , 相应地 , 数据操作,增删改查的开销也会越来越大;另外 , 由于无法进行分布式式部署 , 而一台服务器的资源(CPU、磁盘、内存、IO 等)是有限的 , 最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈 。
2、分表的方案
做 mysql 集群 , 有人会问 mysql 集群,根分表有什么关系吗?虽然它不是实际意义上的分表,但是它启到了分表的作用,做集群的意义是什么呢?为一个数据库减轻负担 , 说白了就是减少 sql 排队队列中的 sql 的数量 , 举个例子:有 10 个 sql 请求,如果放在一个数据库服务器的排队队列中,他要等很长时间 , 如果把这 10 个 sql 请求 , 分配到 5 个数据库服务器的排队队列中,一个数据库服务器的队列中只有 2 个,这样等待时间是不是大大的缩短了呢?
linux mysql proxy 的安装 , 配置,以及读写分离
mysql replication 互为主从的安装及配置,以及数据同步
优点:扩展性好,没有多个分表后的复杂操作(php 代码)
缺点:单个表的数据量还是没有变,一次操作所花的时间还是那么多,硬件开销大 。
三、简述一下数据库主从复制,读写分离
* 什么是主从复制
主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;
* 主从复制的原理:
1.数据库有个bin-log二进制文件,记录了所有的sql语句 。
2.只需要把主数据库的bin-log文件中的sql语句复制 。
3.让其从数据的relay-log重做日志文件中再执行一次这些sql语句即可 。
* 主从复制的作用
1.做数据的热备份 , 作为后备数据库 , 主数据库服务器故障后,可切换到从数据库继续工作 , 避免数据丢失 。
2.架构的扩展 。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问频率,提高单机的I/O性能
3.主从复制是读写分离的基?。故菘饽苤瞥筛?的并发 。例如子报表中,由于部署报表的sql语句十分慢,导致锁表,影响前台的服务 。如果前台服务使用master,报表使用slave,那么报表sql将不会造成前台所,保证了前台的访问速度 。
* 主从复制的几种方式:
1.同步复制:所谓的同步复制,意思是master的变化,必须等待slave-1,slave-2,…,slave-n完成后才能返回 。
2.异步复制:如同AJAX请求一样 。master只需要完成自己的数据库操作即可 。至于slaves是否收到二进制日志,是否完成操作 , 不用关心 。MYSQL的默认设置 。
3.半同步复制:master只保证slaves中的一个操作成功 , 就返回,其他slave不管 。
这个功能,是由google为MYSQL引入的 。
* 关于读写分离
在完成主从复制时 , 由于slave是需要同步master的 。所以对于insert/delete/update这些更新数据库的操作,应该在master中完成 。而select的查询操作,则落下到slave中 。
php数据库用一个sql取数据还是多个sql分开取数据好php使用的数据库一般是mysql,当数据量大于1000万时,为了效率最好还会进行分表存储 。
这要看你应用在什么场合了,如果只是单纯的数据处理,不需要取出来使用的话,可以直接在数据库里操作 , 比如建十张表,根据特征把1000万条数据插入到不同的表里 。如insert intotable_1 select * from table 。
如果要取出来使用的话,建议写执行脚本,在数据库空闲时(如零点之后)执行该脚本,将处理的结果保存在另外一张表里,再从这张表里获取想要的结果 。
MySQL数据库性能优化之分区分表分库分表是分散数据库压力的好方法 。
分表,最直白的意思,就是将一个表结构分为多个表,然后 , 可以再同一个库里,也可以放到不同的库 。
当然 , 首先要知道什么情况下,才需要分表 。个人觉得单表记录条数达到百万到千万级别时就要使用分表了 。
分表的分类
**1、纵向分表**
将本来可以在同一个表的内容,人为划分为多个表 。(所谓的本来,是指按照关系型数据库的第三范式要求,是应该在同一个表的 。)
分表理由:根据数据的活跃度进行分离 , (因为不同活跃的数据 , 处理方式是不同的)
案例:
对于一个博客系统,文章标题 , 作者,分类,创建时间等,是变化频率慢,查询次数多,而且最好有很好的实时性的数据,我们把它叫做冷数据 。而博客的浏览量,回复数等,类似的统计信息,或者别的变化频率比较高的数据 , 我们把它叫做活跃数据 。所以 , 在进行数据库结构设计的时候,就应该考虑分表,首先是纵向分表的处理 。
这样纵向分表后:
首先存储引擎的使用不同,冷数据使用MyIsam 可以有更好的查询数据 。活跃数据 , 可以使用Innodb ,可以有更好的更新速度 。
其次 , 对冷数据进行更多的从库配置 , 因为更多的操作时查询,这样来加快查询速度 。对热数据,可以相对有更多的主库的横向分表处理 。
其实,对于一些特殊的活跃数据,也可以考虑使用memcache ,redis之类的缓存,等累计到一定量再去更新数据库 。或者mongodb 一类的nosql 数据库,这里只是举例,就先不说这个 。
**2、横向分表**
字面意思,就可以看出来,是把大的表结构,横向切割为同样结构的不同表,如,用户信息表 , user_1,user_2等 。表结构是完全一样,但是 , 根据某些特定的规则来划分的表,如根据用户ID来取模划分 。
分表理由:根据数据量的规模来划分,保证单表的容量不会太大,从而来保证单表的查询等处理能力 。
案例:同上面的例子 , 博客系统 。当博客的量达到很大时候,就应该采取横向分割来降低每个单表的压力,来提升性能 。例如博客的冷数据表 , 假如分为100个表 , 当同时有100万个用户在浏览时,如果是单表的话 , 会进行100万次请求,而现在分表后,就可能是每个表进行1万个数据的请求(因为,不可能绝对的平均,只是假设) , 这样压力就降低了很多很多 。
延伸:为什么要分表和分区?
日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表 。这样的表过于庞大,导致数据库在查询和插入的时候耗时太长 , 性能低下,如果涉及联合查询的情况,性能会更加糟糕 。分表和表分区的目的就是减少数据库的负担,提高数据库的效率,通常点来讲就是提高表的增删改查效率 。
什么是分表?
分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体表,我们可以称为子表,每个表都对应三个文件,MYD数据文件,.MYI索引文件,.frm表结构文件 。这些子表可以分布在同一块磁盘上,也可以在不同的机器上 。app读写的时候根据事先定义好的规则得到对应的子表名,然后去操作它 。
什么是分区?
分区和分表相似 , 都是按照规则分解表 。不同在于分表将大表分解为若干个独立的实体表,而分区是将数据分段划分在多个位置存放 , 可以是同一块磁盘也可以在不同的机器 。分区后,表面上还是一张表,但数据散列到多个位置了 。app读写的时候操作的还是大表名字,db自动去组织分区的数据 。
**MySQL分表和分区有什么联系呢?**
1、都能提高mysql的性高,在高并发状态下都有一个良好的表现 。
2、分表和分区不矛盾,可以相互配合的,对于那些大访问量,并且表数据比较多的表,我们可以采取分表和分区结合的方式(如果merge这种分表方式,不能和分区配合的话,可以用其他的分表试),访问量不大,但是表数据很多的表,我们可以采取分区的方式等 。
3、分表技术是比较麻烦的,需要手动去创建子表 , app服务端读写时候需要计算子表名 。采用merge好一些,但也要创建子表和配置子表间的union关系 。
4、表分区相对于分表,操作方便,不需要创建子表 。
我们知道对于大型的互联网应用,数据库单表的数据量可能达到千万甚至上亿级别,同时面临这高并发的压力 。Master-Slave结构只能对数据库的读能力进行扩展 , 写操作还是集中在Master中,Master并不能无限制的挂接Slave库 , 如果需要对数据库的吞吐能力进行进一步的扩展 , 可以考虑采用分库分表的策略 。
**1、分表**
在分表之前,首先要选中合适的分表策略(以哪个字典为分表字段 , 需要将数据分为多少张表),使数据能够均衡的分布在多张表中,并且不影响正常的查询 。在企业级应用中 , 往往使用org_id(组织主键)做为分表字段,在互联网应用中往往是userid 。在确定分表策略后,当数据进行存储及查询时,需要确定到哪张表里去查找数据,
数据存放的数据表 = 分表字段的内容 % 分表数量
**2、分库**
分表能够解决单表数据量过大带来的查询效率下降的问题,但是不能给数据库的并发访问带来质的提升,面对高并发的写访问,当Master无法承担高并发的写入请求时,不管如何扩展Slave服务器 , 都没有意义了 。我们通过对数据库进行拆分,来提高数据库的写入能力,即所谓的分库 。分库采用对关键字取模的方式 , 对数据库进行路由 。
数据存放的数据库=分库字段的内容%数据库的数量
**3、即分表又分库**
数据库分表可以解决单表海量数据的查询性能问题,分库可以解决单台数据库的并发访问压力问题 。
当数据库同时面临海量数据存储和高并发访问的时候,需要同时采取分表和分库策略 。一般分表分库策略如下:
中间变量 = 关键字%(数据库数量*单库数据表数量)
库 = 取整(中间变量/单库数据表数量)
表 = (中间变量%单库数据表数量)
实例:
1、分库分表
很明显,一个主表(也就是很重要的表,例如用户表)无限制的增长势必严重影响性能,分库与分表是一个很不错的解决途径,也就是性能优化途径,现在的案例是我们有一个1000多万条记录的用户表members,查询起来非常之慢,同事的做法是将其散列到100个表中 , 分别从members0到members99,然后根据mid分发记录到这些表中,牛逼的代码大概是这样子:
复制代码 代码如下:
?php
for($i=0;$i 100; $i){
//echo "CREATE TABLE db2.members{$i} LIKE db1.members
";
echo "INSERT INTO members{$i} SELECT * FROM members WHERE mid0={$i}
";
}
?
2、不停机修改mysql表结构
同样还是members表 , 前期设计的表结构不尽合理,随着数据库不断运行 , 其冗余数据也是增长巨大,同事使用了下面的方法来处理:
先创建一个临时表:
/*创建临时表*/
CREATE TABLE members_tmp LIKE members
然后修改members_tmp的表结构为新结构,接着使用上面那个for循环来导出数据,因为1000万的数据一次性导出是不对的,mid是主键,一个区间一个区间的导,基本是一次导出5万条吧,这里略去了
接着重命名将新表替换上去:
/*这是个颇为经典的语句哈*/
RENAME TABLE members TO members_bak,members_tmp TO members;
就是这样 , 基本可以做到无损失,无需停机更新表结构,但实际上RENAME期间表是被锁死的,所以选择在线少的时候操作是一个技巧 。经过这个操作 , 使得原先8G多的表,一下子变成了2G多 。
PHP文章分类为什么要建一个分类表和一个文章表而且相互关联,把分类表的字段加在文章表里面不行吗?可以啊 。
但是,从数据库设计角度看,有几个问题php数据库为什么要分表你准备怎么处理php数据库为什么要分表?
如果需要列出文章分类怎么办?全表搜索然后去重?
如果文章很多,分类名长短差异大,直接使用字段存放分类名岂不是会浪费很大php数据库为什么要分表的存储空间?
如果分类php数据库为什么要分表的需求变成多层的,你怎么办?再加一个字段?如果分类层数不限的话怎么办?
如果要禁止向一个分类里再添加新文章怎么办?
如果要添加一个分类,但目前没有任何文章属于此分类又怎么办?
从业务抽象的角度来看,分类是文章的一个属性,它可使用的值是有限的,并且具有自己的一套属性,因此它应当是一个业务对象,对应到数据库就应当有相应的一个表或一组表 。
【php数据库为什么要分表 php分表分库】php数据库为什么要分表的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于php分表分库、php数据库为什么要分表的信息别忘了在本站进行查找喔 。
推荐阅读
- erp防外泄系统在哪里买,erp防外泄系统在哪里买的
- 怎么叫excel加标尺,excel添加标尺
- 直播吃红萝卜炒肉的主播,吃红烧肉吃播小视频
- 包含linux禁用某一个命令的词条
- 小白入门go语言,零基础go语言从入门到精通
- 网络游戏机甲情缘,曾经火的机甲网游
- 视频号直播营销玩法技巧,视频号直播电商
- mysql怎么查序列 mysql查询结果生成序列号
- jquery写3d动态视频,jquery动态效果