首页
关于
留言
接口
搜索
首页
登录
登录
搜索
KAKA 梦很美
累计撰写
47
篇文章
累计收到
0
条评论
首页
栏目
首页
登录
页面
首页
关于
留言
接口
规范准则
2021-9-11
Redis 开发准则
命名规范 [强制] 键名可读性和可管理性设计(防止 Key 冲突) <项目名称>:<资源类型>[:<子资源类型>]:资源标识 例如: order:user:info:1 键名建议长度控制在一定范围内, 键名需要尽量做到 “见其名知其意”. [强制] Key 名不要包含特殊字符,如空格、换行、单双引号以及其他转义字符 使用规范 [强制] 正常情况下, 键必须设置过期时间 [强制] (热点数据) 高频访问数据需存入缓存 [强制] 如果缓存的是大文本, 当文本长度过大, 类似的键数量多, 会有较大的内存占用. 并且在访问量高时, 会导致带宽使用过高甚至占满. 因此当文本大小到一定程度时, 例如数十 kb 甚至数百 kb时, 可以考虑使用先压缩, 再缓存 [强制] 根据业务场景合理使用不同的数据类型, 切勿过度使用缓存, 必须遵循合理性 [强制] 禁止使用模糊匹配keys、flushall命令 [强制] 慎用hmgetall, hgetall, zrange, smembers, lrange 命令, 如果操作数据量过大,将会导致阻塞。有遍历需求可以使用 hscan、sscan、zscan 代替 [强制] 注意 缓存穿透, 缓存击穿, 缓存雪崩 问题
2021年-9月-11日
192 阅读
0 评论
规范准则
2021-2-17
PHP 开发准则
命名规范 [强制] 代码文件必须以 <?php 或 <?= 标签开始 [强制] 代码文件必须以不带 BOM 的 UTF-8 编码 [强制] 代码中应该只定义类、函数、常量等声明,或其他会产生副作用的操作(如:生成文件输出以及修改 .ini 配置文件等),二者只能选其一 [强制] 命名空间以及类必须符合 PSR 的自动加载规范:PSR-4 中的一个 [强制] 类的命名必须遵循 StudlyCaps 大写开头的驼峰命名规范 [强制] 类中的常量所有字母都必须大写,单词间用下划线分隔 例如: CHANNEL, PLATFORM [强制] 类方法名称必须符合 camelCase 式的小写开头驼峰命名规范 [强制] 普通帮助函数名称必须全小写或小写、下划线、数组的命名规范 例如: get_client_ip, sort_array 编码规范 [强制] 控制结构的关键字后必须要有一个空格符,而调用方法或函数时则一定不可有 [强制] 每个 namespace 命名空间声明语句和 use 声明语句块后面,必须插入一个空白行 [强制] 类的开始花括号({)必须写在函数声明后自成一行,结束花括号(})也必须写在函数主体后自成一行 [强制] 函数方法的开始花括号({)必须写在函数声明后自成一行,结束花括号(})也必须写在函数主体后自成一行 [强制] 控制结构的开始花括号({)必须写在声明的同一行,而结束花括号(})必须写在主体后自成一行 [强制] 类的属性和方法必须添加访问修饰符(private、protected以及public),abstract以及final必须声明在访问修饰符之前,而static必须声明在访问修饰符之后 [强制] 所有关键字必须全部小写, 常量true、false和null必须全部小写 [强制] 关键词extends和implements必须写在类名称的同一行, <font color=#7255e6>[建议]</font>但当implements的继承列表有多个时, 则可以分成多行,每个继承接口名称都必须分开独立成行,包括第一个 [建议] 尽量避免 & 引用赋值的使用, 必要时可以使用 [建议] 方法内避免过度使用匿名函数, 不强制, 但需保持代码的强可读性 以下例子程序简单地展示了以上大部分编码规范: <?php namespace Vendor\Package; use FooInterface; use BarClass as Bar; use OtherVendor\OtherPackage\BazClass; use TIM; class Foo extends Bar implements FooInterface { use TIM; public function sampleFunction($a, $b = null) { if ($a === $b) { bar(); } elseif ($a > $b) { $foo->bar($arg1); } else { BazClass::bar($arg2, $arg3); } } final public static function bar() { // 方法的内容 } }
2021年-2月-17日
163 阅读
0 评论
规范准则
2020-1-11
MySQL 开发准则
命名规范 [强制] 字段名称必须用小写或者小写、下划线、数字组成 例如: name, user_name [强制] 字段名称禁止使用 MySQL 保留关键字 例如: order, sum 等 [强制] 字段名称要见名知其意,不要超过 32 个字符 例如: nickname, created_at [强制] 临时表要以 tmp 为前缀,日期为后缀 例如: tmp_export_user_20200307 [强制] 备份表要以 bak 为前缀,日期为后缀 例如: bak_user_20200307 [强制] 表名不使用复数名词 例如: users [强制] 表字段名称需要表示是否概念时,用 is_xxx 表示 例如: is_default, is_use [强制] 索引名称,用特定 _ 字段表示 普通索引 idx_xxx 联合索引 un_xxx_xxx 唯一索引 uk_xxx [强制] 时间字段名称用特定 _at 字段表示, 推荐 DATETIME 类型 例如: created_at, updated_at, deleted_at 表设计规范 [强制] 如无特殊需求,存储引擎使用 InnoDB 支持事务 行级锁 并发性能好 [强制] 数据库和表的字符集统一使用 utf8 或 utf8mb4, 无特殊要求优先使用 utf8mb4 不同字符集转化可能会产生乱码 不同字符集比较前会进行字符转换,索引失效 UTF8 每个字符占用3字节,占用空间小,但是不能存储 emoj,emoj 占用4字节 UTF8MB4 每个字符占用4字节,是真正的 UTF8,推荐使用 <font color=#7255e6>[建议]</font> InnoDB 字符集默认排序使用 _general_ci 和 _unicode_ci,推荐使用 _general_ci [强制] 每张表都必须建立自增ID字段,不要问为什么,看看B+树原理你就懂了 [强制] 数据库表和字段都需要添加备注,更好理解建表思路 [强制] 不要使用触发器, 可以用事务替代 [强制] 数据量大的表要使用pt(pt-online-schema-change)工具修改表结构 原理是新建一张表并复制原表结构与数据,最终删除原表,可以有效避免行锁及表锁 字段设计规范 [强制] 表字段名称需要表示是否概念时,即 is_xxx, 1 表示是, 0 表示否, 使用 UNSIGNED TINYINT。 [强制] 小数类型都使用 DECIMAL 型 (DECIMAL 精确, 如果超出 DECIMAL 范围建议分两个字段存储) [强制] 固定长度字段用 CHAR, 根据实际情况 例如: 定长的手机号码 [强制] 选择合适的存储长度 可以减少表存储空间 可以减少索引长度,增加索引效率 <font color=#7255e6>[建议]</font> 避免使用TEXT、BLOB数据类型 内存临时表不支持TEXT和BLOB。会使用磁盘临时表,降低查询速度 TEXT和BLOB需要单独成表,提高查询效率 <font color=#7255e6>[建议]</font> 避免使用 ENUM 数据类型 枚举类型 ORDER BY 效率低 禁止使用数字作为枚举值 (在与PHP使用上1和’1’差别大,PHP是弱引用很容易把’1’写为1,1为key,’1’为内容) <font color=#7255e6>[建议]</font> 尽可能把列定义设置为 NOT NULL 索引NULL列,会额外增加开销,占用更多表空间 要做计算或者比较时,会对 NULL 做特别处理 在 SQL 中对 NULL 进行判断会全表扫描 索引设计规范 [强制] 不要使用外键和级联,应放在应用层去做 [强制] 一张表不要超过5个索引 索引过多会降低性能 合理分配索引会提高性能 [强制] 联合索引的最左前缀原则可以减少每个字段单独建立索引 避免每个字段都建立索引 联合索引区分度高的放在最左边 联合索引如果存在非等号和等号混合时,把等号的索引放在最左边 联合索引最左前缀原则,一定要注意顺序 [强制] InnoDB 必须有主键ID <font color=#7255e6>[建议]</font> 查询想走特定索引时可以用 FORCE INDEX MySQL的 optimizer 会执行它认为最优索引,但是往往不是我们需要或者最优的 使用 FORCE INDEX 可以强制使用索引,结合 EXPALIN 使用,确认为最优 [强制] 有唯一索引需求,该字段就应设置唯一索引 即使该字段是在联合索引内,也要单独设置唯一索引 唯一索引对 INSERT 速度影响可以忽略,但是提高查询速度和唯一性是明显的 应用层也建议做校验控制,但是根据墨菲定律,只要有可能就会出现脏数据 [强制] VARCHAR 型设置索引要设置索引长度 不设置默认是全部长度 建议索引长度为20, 区分度可以达到90% 区分度计算公式:SELECT COUNT(DISTINCT left(列名, 索引长度))/COUNT(*) FROM 表名。可以查出区分度百分比。 [强制] 模糊查询最好用搜索引擎 大表禁止使用 LIKE %str 和 LIKE %str%, 因为不走索引 可以使用 LIKE str%, 走索引 [强制] ORDER BY 需要注意索引的有序性 ORDER BY 后接索引的部分,如果是联合索引,应该是联合索引的最后,避免出现 file_sort,影响查询性能。WHERE a=? AND b=? ORDER BY c 那么索引是(a,b,c) file_sort 出现是没有走索引或者联合索引。出现情况:WHERE a=? ORDER BY b索引是a。改进优化:WHERE a=? ORDER BY b索引是(a,b) [强制] 避免冗余索引 重复索引:PRIMARY KEY(id)、INDEX(id)、UNIQUE INDEX(id) 冗余索引:KEY(a,b,c)、KEY(a,b)、KEY(a) [强制] 查询频率较高的SQL语句,应该使用覆盖索引 覆盖索引不是真正的索引,是一种使用索引方式 (原理是从索引中查询出想要内容,而不用回表查询,提高查询效率, 表现是 EXPLAIN 的 Extra 为 Using index) 例如 SELECT user_no FROM user WHERE user_age = 28索引为user_no时效率低,索引为(user_no,user_age)时为覆盖索引,查询效率高 [强制] 避免隐式类型转换 定义和使用不同数据会造成隐式转换 (隐式转换会不走索引,降低查询效率) 例如 user_no为INT, SELECT user_age FROM user WHERE user_no='111' [强制] 避免在字段位置写表达式,不走索引 反例:SELECT user_no FROM user WHERE user_age*2 = 36 正例:SELECT user_no FROM user WHERE user_age = 36/2 查询优化 [强制] SQL性能优化目标,由高到低 const 基本是只有一行匹配 ref 基本是走普通索引 range 基本是走范围索引 index 走索引最差,和全表查询相似 NULL 不走索引,全表查询 [强制] 不适用索引的几种情况 不等式:!=、<> NULL 判断:IS NULL、IS NOT NULL LIKE 模糊查询:LIKE %a、LIKE %a% NOT IN <font color=#7255e6>[建议]</font> 避免使用IN操作,如果避免不了,需小于1000条 多表查询IN会影响查询效率 可以用 BETWEEN 替代 IN(SELECT * FROM)索引会失效,可以使用JOIN(LEFT、RIGHT、INNER、FULL)来实现 <font color=#7255e6>[建议]</font> JOIN 优化 最好在三张表之内,最多不要超过5张表 ON 关联字段类型要相同 每关联一个表就会多分配一个关联缓存,和 join_buffer_size 设置相关。占用内存过大会形成溢出,影响性能和稳定性 LEFT JOIN 的驱动表是左侧表 INNER JOIN 的驱动表是数据少的表 RIGHT JOIN 的驱动表是右侧表 MySQL没有 FULL JOIN,可以用SQL实现。例如:SELECT FROM A LEFT JOIN B ON B.name = A.name WHERE B.name IS NULL UNION ALL SELECT FROM B 尽量利用小表驱动大表,可以减少循环嵌套次数 STRAIGHT_JOIN 的使用。前提是INNER JOIN内连接。INNER JOIN优先查询小表,但有GROUP BY、ORDER BY等file_sort, Using temporary时会想改变优先查询表顺序,这时可以使用STRAIGHT_JOIN。 STRAIGHT_JOIN强制优先查询表为左侧表 (一定要是内连接才能使用 STRAIGHT_JOIN,否则数据可能不准确) <font color=#7255e6>[建议]</font> *避免 SELECT 出现, 特别是多字段大表** SELECT * 增加额外解析成本 增减字段对前端映射不一致 无用字段增加网络消耗 无法使用覆盖索引 [强制] 禁止使用不带字段的 INSERT 出现 正例:INSERT INTO user(user_no,user_age) VALUES (123,18) 反例:INSERT INTO user VALUES (123,18) <font color=#7255e6>[建议]</font> 尽量避免子查询 子查询一般在IN中 子查询会创建临时表,不会存在索引 结果集大的子查询,性能越差 可以使用JOIN替代 [强制] 查询一条或者是否有数据时,要使用 LIMIT 1 索引效率最高 EXPLAIN 的 type 为 const <font color=#7255e6>[建议]</font> ORDER BY 字段没有索引就不要排序 ORDER BY 字段有索引会按索引排序。没有索引影响效率 可以设置索引,或者覆盖索引 <font color=#7255e6>[建议]</font> 尽量不使用 OR 同一字段用IN、BETWEEN等替代OR,因为很多情况不会走索引 多字段下OR两边都需要是索引且其他条件也是索引,才会走索引 最好使用UNION、UNION ALL来替换 <font color=#7255e6>[建议]</font> 尽量用 UNION ALL 替代 UNION UNION 会集合后进行唯一性去重,涉及到排序,加大资源开销 在没有重复数据情况强制使用 UNION ALL <font color=#7255e6>[建议]</font> 拆分大且复杂的SQL 一条SQL只会使用一个CPU 拆成多个小SQL可以通过并行提高查询效率 [强制] 禁止使用 ORDER BY RAND() 随机排序性能差 (可以用其他SQL替换) 原SQL: SELECT id FROM 'dynamic' ORDER BY RAND() LIMIT 1; 新SQL: SELECT id FROM 'dynamic' t1 JOIN (SELECT RAND() * (SELECT MAX(id) FROM 'dynamic') AS nid) t2 ON t1.id > t2.nid LIMIT 1。 注意, 此查询只能随机一条id,并连续查询该id的顺序条数,具体情况具体分析,适用随机取一条,不应用随机取多条, 随机取多条解决方案:先查询所有id->在后端业务层做随机id->IN该id组, rand()取值范围:(0, 1) [强制] 禁止对 WHERE 条件字段进行函数转换(不走索引) 正例:SELECT user_age FROM user WHERE created_at > '20200307' 反例:SELECT user_age FROM user WHERE DATE(created_at) > '20200307' <font color=#7255e6>[建议]</font> IN、EXISTS、NOT IN、NOT EXISTS IN是子查询,优先查询驱动表为内表,所以适合内表数据小的情况 EXISTS优先查询驱动表为外表,适合外表数据小的情况 不建议使用NOT IN和NOT EXISTS,不走索引且容易混淆(建议用其他SQL替代) 反例:SELECT a.user_age FROM user a WHERE a.user_no NOT IN (SELECT b.user_no FROM user_info b)。 正例:SELECT a.user_age FROM user a LEFT JOIN user_info b ON a.user_no = b.user_no WHERE b.user_no IS NULL。 <font color=#7255e6>[建议]</font> OFFSET 偏移量、分页 分页数据量大的情况会影响查询效率,因为不是跳过OFFSET行,而是查询OFFSET+N行,然后抛弃OFFSET行 优化举例1:SELECT user_age FROM user WHERE user_no > 13333 LIMIT 20。 优化举例2:SELECT a.user_age FROM user a,(SELECT user_no FROM user LIMIT 13333,20)b WHERE a.user_no = b.user_no。 [强制] 范围查询注意 BETWEEN、>、< 查询时,如果是走联合索引,那么范围查询后的索引失效 [强制] COUNT() 相关 统计行数要使用COUNT(*),不要使用COUNT(列名) COUNT(*)会统计NULL数据,COUNT(列名)不会统计NULL数据 当某一列的值全为NULL时,COUNT(列名)返回的结果为0,但SUM(列名)结果为NULL,因此使用SUM(列名)需要使用IFNULL判断 例如:SELECT IF(IFNULL(SUM(user_name)),0,SUM(user_name))user_age FROM user
2020年-1月-11日
167 阅读
0 评论
规范准则