1. 规范目的
为提高团队协作效率,便于后台人员添加功能及前端后期优化维护,输出高质量的文档。
2. 基本规则
2.1. 基本说明
符合API化标准,结构简洁清晰。
API与用户的通信协议,总是使用HTTPS协议。
API部署在专用域名之下。例如:https://api.example.com
API的版本号放入URL中。例如:https://api.example.com/v1/
API的接口频次请求限制。例如:一个接口请求次数多少次。
API资源的具体操作类型分为:get获取资源,add添加资源,update更新资源,delete删除资源,list资源列表,search搜索资源,validate验证资源,apply申请资源,send发送资源。后边连接名词。
如:method GET
getAccount获取广告主 。https://api.example.com/v1/account/getAccount
如:method POST
addAccount添加广告主 。https://api.example.com/v1/account/addAccount
如:method PUT
updateAccount更新广告主 。https://api.example.com/v1/account/updateAccount
如:method POST
listAccount广告主列表 。https://api.example.com/v1/account/listAccount
如:method DELETE
delAccount广告主列表 。https://api.example.com/v1/account/delAccount
程序性能方面,代码要求简洁明了有序,尽可能的减少服务器负载,保证最快的解析速度。
2.2. 项目开发框架
代码目录结构api请以dsp的架构为准,node请以dsp的架构为准。
API接口框架采用thinkphp3.2.3版本
前端框架采用node v6.9.1
nginx/1.8.0
PHP 5.6.0
redis2.8.13
mysql5.6.20
php redis的扩展2.2.8-rc1
php zip的扩展 1.12.4
3. 开发规则
3.1. php书写规范
1、类文件都是以.class.php为后缀(这里是指的ThinkPHP内部使用的类库文件,不代表外部加载的类库文件),使用驼峰法命名,并且首字母大写,例如DbMysql.class.php;
2、类的命名空间地址和所在的路径地址一致,例如HomeControllerUserController类所在的路径应该是Application/Home/Controller/UserController.class.php;
3、确保文件的命名和调用大小写一致,是由于在类Unix系统上面,对大小写是敏感的(而ThinkPHP在调试模式下面,即使在Windows平台也会严格检查大小写);
4、类名和文件名一致(包括上面说的大小写一致),例如UserController类的文件命名是UserController.class.php, InfoModel类的文件名是InfoModel.class.php, 并且不同的类库的类命名有一定的规范;
5、函数、配置文件等其他类库文件之外的一般是以.php为后缀(第三方引入的不做要求);
6、函数的命名使用小写字母和下划线的方式,例如get_client_ip;
7、方法的命名使用驼峰法,并且首字母小写或者使用下划线“_”,例如getUserName,_parseType,通常下划线开头的方法属于私有方法;
8、属性的命名使用驼峰法,并且首字母小写或者使用下划线“_”,例如tableName、_instance,通常下划线开头的属性属于私有属性;
9、以双下划线“__”打头的函数或方法作为魔法方法,例如__call和__autoload;
10、常量以大写字母和下划线命名,例如HAS_ONE和MANY_TO_MANY;
11、配置参数以大写字母和下划线命名,例如HTML_CACHE_ON;
12、语言变量以大写字母和下划线命名,例如MY_LANG,以下划线打头的语言变量通常用于系统语言变量,例如_CLASS_NOT_EXIST_;
13、不建议使用短标签:?>,建议结尾不写?>,如果使用完整格式定界,需要保证在关闭标签后不要有任何空格,避免尾部的空白字符意外输出。
14、行最大长度:以屏幕换行为准,尽量不要横拉滚动条看代码。
15、字符串如果是纯字符(不带变量),那么就用单引号。($a = ‘a b c’)
16、类声明:类后面的{}每半个大扩号,需要单独占一行。每个类需要有符合PHPDocumentor标准的注释。一个PHP文件内只能有一个类。尽量一个PHP文件不要写其他的代码,如果有的话,请空一行。
require_once ‘abc.php’;
/**
* Documentation注释
*/
class UserModel
{
//content of class
}
18、类的成员变量:在类中定义,成员变量要先于函数,必须使用private,protected,public。
19、函数
声明:类中的函数必须使用private,protected,public。和类的格式相同,也需要大扩号单独占一行,函数后面的()紧贴函数名。
使用:函数参数中如果有多个,就要用逗号隔开,并且逗号后面要有空格。
20、控制语句:
If/Else/Elseif :If,Else,Elseif 每个都要占一行。条件中,操作符前后要有空格,提高可读性。开始的大括号和if同行,结束的大括号另起一行。尽量多的使用elseif而不是再写一个if。如果遇到很长的逻辑判断,则要用内嵌括号来分割各个逻辑。
Switch:和if相似,开始的大括号和switch同行,结束的大括号另起一行。每一个case都要有2个空格缩进。每个case需要有个break,如果想要出于某种特殊目的不写break的,需要注释。必须以"default" 控制结束。
21、注释:所有的注释都要符合phpdocumentor规范。
文件注释:每个文件在开始都要有注释,不要求很复杂
/**
*文件功能说明
*@version
*@author [email protected]
*/
类注释:
/**
*类功能说明
*@version
*@author [email protected]
*/
函数注释:
函数注释需要注明:描述,全部的参数,返回值。
如有异常抛出,则需要:@throws exceptionclass [description]
单行注释:
必须现在所注释的前一行或简短写在行末。
如:
//注释
$num = 5;//注释
多行注释:
/*
* 多行注释
*/
尽量不用 #、///等方式进行注释
22、=或者==等二元操作符需要左右空一格,尽力按要求来。
23、如果需要把一些经常使用的方法定义为全局函数,建议以静态 (static) 的形式定义在类中。
24、代码缩进2个空格缩进。
3.2. node书写规范
1、使用严格模式;文件头部定义:use strict;
2、缩进采用两个空格缩进,在编辑器中设置tab为两个空格;
3、变量声明;
3.1、用var声明变量,
例:
var assert = require(‘assert’);
var net = require(‘net’);
避免使用:var assert = require(‘assert’),net = require(‘net’);
3.2、用字面量声明方式,
例:var isAdmin = true;var arr = [];
避免使用:var arr = new Array();var obj =new Object();
4、不要在for循环等循环里声明var变量首先var是函数作用域,在循环声明以后只有等函数声明周期结束这些资源才会释放;
5、空格在操作符前后需要加上空格,= 、% 、* 、- 、+ 前后都应该加一个空格。
如:var foo = ‘bar’ + baz;错误实例:var foo=’bar’+baz;
6、单双引号的使用在node中尽量使用单引号;var html = 'CNode';
7、变量命名变量名采用驼峰命名,单词之间没有任何符号
如:var adminUser = {}; var callNum = 2134323;
8、方法命名也是采用驼峰命名,与变量不同的是采用动词或判断型词汇;
如:var getUser = function(){}; var isAdmin = function(){}; var findUser = function(){};
9、类命名类名采用驼峰,所有单词首字母大写
如:function User{}
10、常量命名作为常量,单词所有字母大写,用下划线分割
如:var PINK_COLOR = "PINK";
11、文件命名命名文件时,尽量使用下划线分割单词;
如:child_process.js和string_decode.js
12、包名在包名中尽量不要包含js和node的字样,应当适当短并且有意义
13、作用域慎用with和eval(),容易引起作用域混乱
14、比较操作尽量使用===代替==,否则会遇到下面的情况,
如:'0'==0;//true; ''==0;//true; '0'===''//false;
15、对象和数组遍历数组遍历使用普通for循环,避免使用for in对数组遍历,对象的遍历使用for in
3.3. mysql书写规范
3.3.1、表设计
1、库名、表名必须使用小写字母,“_”分割,字段名使用驼峰命名。
2、库名、表名、字段名必须不超过20个字符。
3、库名、表名、字段名见名知意,建议使用名词而不是动词。
4、建议插入操作多的使用InnoDB存储引擎、查询操作多的使用MYISAM存储引擎。
5、存储精确浮点数必须使用DECIMAL替代FLOAT和DOUBLE。
6、建议使用UNSIGNED存储非负数值。
7、建议使用INT UNSIGNED存储IPV4。
8、整形定义中不添加长度,比如使用INT,而不是INT(4)。
9、使用短数据类型,比如取值范围为0-80时,使用TINYINT UNSIGNED。
10、不建议使用ENUM类型,使用TINYINT来代替。
11、尽可能不使用TEXT、BLOB类型。
12、VARCHAR(N),N表示的是字符数不是字节数,比如VARCHAR(255),可以最大可存储255个汉字,需要根据实际的宽度来选择N。
13、VARCHAR(N),N尽可能小,因为MySQL一个表中所有的VARCHAR字段最大长度是65535个字节,进行排序和创建临时表一类的内存操作时,会使用N的长度申请内存。
14、表字符集选择UTF8。
15、使用VARBINARY存储变长字符串。
16、存储年使用YEAR类型。
17、存储日期使用DATE类型。
18、存储时间(精确到秒)建议使用TIMESTAMP类型,因为TIMESTAMP使用4字节,DATETIME使用8个字节。
19、建议字段定义为NOT NULL。
20、将过大字段拆分到其他表中。
21、禁止在数据库中使用VARBINARY、BLOB存储图片、文件等。
3.3.2、索引
1、非唯一索引必须按照“idx_字段名称_字段名称[_字段名]”进行命名。
2、唯一索引必须按照“uniq_字段名称_字段名称[_字段名]”进行命名。
3、索引名称必须使用小写。
4、索引中的字段数建议不超过5个。
5、单张表的索引数量控制在5个以内。
6、唯一键由3个以下字段组成,并且字段都是整形时,使用唯一键作为主键。
7、没有唯一键或者唯一键不符合5中的条件时,使用自增id作为主键。
8、唯一键不和主键重复。
9、索引字段的顺序需要考虑字段值去重之后的个数,个数多的放在前面。
10、ORDER BY,GROUP BY,DISTINCT的字段需要添加在索引的后面。
11、使用EXPLAIN判断SQL语句是否合理使用索引,尽量避免extra列出现:Using File Sort,Using Temporary
12、UPDATE、DELETE语句需要根据WHERE条件添加索引。
13、不建议使用%前缀模糊查询,例如LIKE “%weibo”。
14、对长度过长的VARCHAR字段建立索引时,添加crc32或者MD5 Hash字段,对Hash字段建立索引。
15、合理创建联合索引(避免冗余),(a,b,c) 相当于 (a) 、(a,b) 、(a,b,c)。
16、合理利用覆盖索引。
3.3.3、SQL语句
1、使用prepared statement,可以提供性能并且避免SQL注入。
2、SQL语句中IN包含的值不应过多。
3、UPDATE、DELETE语句不使用LIMIT。
4、WHERE条件中必须使用合适的类型,避免MySQL进行隐式类型转化。
5、SELECT语句只获取需要的字段。
6、SELECT、INSERT语句必须显式的指明字段名称,不使用SELECT *,不使用INSERT INTO table()。
7、使用SELECT column_name1, column_name2 FROM table WHERE [condition]而不是SELECT column_name1 FROM table WHERE [condition]和SELECT column_name2 FROM table WHERE [condition]。
8、WHERE条件中的非等值条件(IN、BETWEEN、<、<=、>、>=)会导致后面的条件使用不了索引。
9、避免在SQL语句进行数学运算或者函数运算,容易将业务逻辑和DB耦合在一起。
10、INSERT语句使用batch提交(INSERT INTO table VALUES(),(),()……),values的个数不应过多。
11、避免使用存储过程、触发器、函数等,容易将业务逻辑和DB耦合在一起,并且MySQL的存储过程、触发器、函数中存在一定的bug。
12、避免使用JOIN。
13、使用合理的SQL语句减少与数据库的交互次数。
14、不使用ORDER BY RAND(),使用其他方法替换。
15、建议使用合理的分页方式以提高分页的效率。
16、统计表中记录数时使用COUNT(*),而不是COUNT(primary_key)和COUNT(1)。
17、禁止在从库上执行后台管理和统计类型功能的QUERY。
3.3.4、散表
1、每张表数据量建议控制在5000w以下。
2、可以结合使用hash、range、lookup table进行散表。
3、散表如果使用md5(或者类似的hash算法)进行散表,表名后缀使用16进制,比如user_ff。
4、推荐使用CRC32求余(或者类似的算术算法)进行散表,表名后缀使用数字,数字必须从0开始并等宽,比如散100张表,后缀从00-99。
5、使用时间散表,表名后缀必须使用特定格式,比如按日散表user_20110209、按月散表user_201102。
3.3.5、其他
1、批量导入、导出数据需要在执行过程中观察服务,重复审查是否有问题。
2、批量更新数据,如update,delete 操作,需在执行过程中观察服务。
3、产品出现非数据库平台运维导致的问题和故障时,如前端被抓站,请及时稳定程序,并处理。
4、业务部门程序出现bug等影响数据库服务的问题,请及时稳定程序,并处理。
5、业务部门推广活动,请提前进行服务和访问评估。
6、服务器权限、线上的DB权限、svn权限由技术经理控制。不得随意下分。
7、开发人员只可以访问测试DB权限。