一些杂项

数据冗余

在product表中我们的main_img_url和img_id是指向相同的url,为什么要数据冗余?这里是出于性能的考虑,当数据量如果比较多,嵌套循环(theme-product-image)也多的情况下,查询起来性能会有所影响,product表如果要去image表中查询图片url,在有足够多的product时,查询性能就会有所影响,而做了数据冗余就可以减少去image表中查询url,从而提高一部分性能,减少数据库压力,主要要合理利用,不能滥用,根据具体的情况来决定,先搞清楚业务,数据库优化是比较重要的

为什么不要滥用数据库冗余呢?

对维护数据库的完整性和一致性是比较困难的,例如在增删改查中多出一系列的操作,加大了编码的压力。

REST的合理利用

Rest是基于资源的,不管当前业务需要与否,都统一返回模型所有的关系数据,常规一般都是客户端需要什么就返回什么,在我们返回所有的关系数据中,我们应该适当地隐藏一些不需要用到的属性。总结来说,要根据具体业务来具体返回特定的关系数据,这是内部API需要考虑的,服务端是清晰知道客户端需要什么数据的,从而控制返回的数据,可以编写多个接口来防止业务的变更。

编程思维

小功能小方法都是工具,具体就是要根据业务来然后查找是否有相应的工具能够支持我们的业务编写,由目的来指导我们的功能实现。上面的形式就体现了面向对象的强大,如果是数组的形式处理起来会比较复杂,因为没有一些内置的处理方法。而数据集对象就提供了很多的方法来处理我们的业务。一组product模型对象可以理解为就是数据集对象,最好就是用对象自带的方法来处理,不用公共的或类外面的方法去处理能够提高类的内聚性

接口粒度与接口分层

我们首页获取使用了getbanner接口和getSimpleList接口以及getRecent接口,客户端和向服务器发起了三次请求,我们能不能把是三个接口放在一个接口上,让客户端只请求一次服务器呢?答案是可以的,这种方式是我们传统网站的一种思维方式,这是站在当前业务考虑的问题,并没有站在数据的角度去考虑问题,这会导致什么问题呢?任意的一个小地方如果发生小小的业务变化,就会导致整个接口的剧烈变化。如果是从数据的角度来考虑这个问题,每个Api保持一定的独立性,API的复用就较为容易,如果是按照功能来考虑的话,则API绑定起来的通用性会很差。
那发三次请求有什么优点缺点?
缺点:过多的http链接对服务器有一定压力,减少http的连接数是可以提升服务器性能的。
优点:API接口的复用性比较高。
接口粒度与接口分层。
面对以上的问题解决方案是如何的呢?
本身的API视作一个基础数据API,如果某个业务所需要的接口调用数量确实很多的情况下,则应该在基础数据API上再建立一个业务层,然后在业务层的内部再去调用基础数据层的API相关的接口,再封装成一个统一的适合当前业务访问的接口一次性返回,这就是分层的具体应用,大型项目里的基础数据层,服务层就类似我们说的接口分层,是要考虑接口粒度的

一对多或多对多新增

我们可以拆分为两小步,先在主模型上新增数据,然后在关联模型上新增,如果是多对多的关系,则可以在中间表上新增数据,可以扩展多个字段

时间戳自动写入

autoWriteTimestamp属性支持设置为时间日期类名,如果设置为false,表示关闭自动写入

//设置时间戳自动写入
protected $autoWriteTimestamp = true;

//自定义设置时间字段
protected $createTime = 'create_at';
protected $updateTime = 'update_at';

//关闭时间戳字段写入
protected $createTime = false;
protected $updateTime = false;
业务中使用事物
// 启动事务
Db::startTrans();
try{
    Db::table('think_user')->find(1);
    Db::table('think_user')->delete(1);
    // 提交事务
    Db::commit();    
} catch (\Exception $e) {
    // 回滚事务
    Db::rollback();
}
数据校验小技巧

举例:在service下的Pay类中调用检测order类中的检测库存量方法,还需要检验订单号的安全性,第一种将最有可能发生的写在前面,一旦被检测出来后续操作会中止,可以节约服务器性能;第二种将最消耗服务器性能的检测尽量放在后面

使用扩展类库

ThinkPHP5建议所有的扩展类库都使用命名空间定义,如果你的类库没有使用命名空间,则不支持自动加载,必须使用Loader::import方法先导入文件后才能使用,强烈建议使用Composer安装和更新扩展类库

Loader::import('first.second.Foo');
$foo = new \Foo();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章