Onebound技术规范文档


MySQL

<p>[TOC]</p> <h3>命名规范</h3> <ul> <li>库名、表名、字段名必须使用小写字母,&quot;_&quot;分割。</li> <li>库名、表名、字段名不超过12个字符。</li> <li>库名、表名、字段名禁止使用MySQL保留字,见附件。</li> <li>库名、表名、字段名见名知意,建议使用名词而不是动词。</li> <li>数据对象、变量的命名都采用英文字符,禁止使用中文命名。</li> <li>临时库、表名必须以tmp为前缀,并以日期为后缀。</li> <li>备份库、表必须以bak为前缀,并以日期为后缀。</li> </ul> <h3>基础规范</h3> <ul> <li>所有表统一使用InnoDB或MyISAM存储引擎。</li> <li>表字符集选择UTF8mb4。</li> <li>所有表和列都需要添加注释。</li> <li>禁止在数据库中存储图片、文件。</li> <li>禁止在线上做数据库压力测试,如有特殊需要,需提前报备。</li> <li>禁止客户端直接操作测试,生产数据库。</li> <li>研发保证应用与数据库表结构版本的统一</li> </ul> <h3>字段设计规范</h3> <ul> <li>每张表必须有整型主键。如:id bigint(20) UNSIGNED , NOT NULL。</li> <li>禁止DEFAULT NULL,建议NOT NULL 设置默认值。</li> <li>存储精确浮点数必须使用DECIMAL替代FLOAT和DOUBLE,或者使用bigint(需要做转换)。</li> <li>建议使用UNSIGNED存储非负数值。</li> <li>不建议使用ENUM类型,使用TINYINT来代替。</li> <li>建议使用INT UNSIGNED存储IPV4。</li> <li>禁止在数据库中存储明文密码。</li> <li>整形定义中建议采用INT(10),而不是INT(1),INT(11)或其他。</li> <li>存储状态,性别等,用TINYINT。</li> <li>将过大字段拆分到其他表中。尽可能不使用TEXT、BLOB类型。如果必须使用,业务表中的TEXT,BLOB中字段,必须要拆分到单独的表中存储。</li> <li>需要根据实际的宽度来选择VARCHAR(N)类型的宽度。</li> <li>N表示的是字符数不是字节数. VARCHAR(N),N尽可能小,进行排序和创建临时表一类的内存操作时,会使用N的长度申请内存。</li> <li>存储年使用YEAR类型,存储日期使用DATE类型。</li> <li>13 存储时间(精确到秒)建议使用TIMESTAMP类型,因为TIMESTAMP使用4字节,DATETIME使用8个字节。TIMESTAMP类型保存的值不能比1970早或比2037晚。</li> </ul> <h3>索引规范</h3> <ul> <li>单张表的索引数量控制在5个以内。</li> <li>复合索引中的字段数建议不超过5个。</li> <li>非唯一索引必须按照&quot;idx_字段名称_字段名称[_字段名]&quot;进行命名。</li> <li>唯一索引必须按照&quot;uniq_字段名称_字段名称[_字段名]&quot;进行命名。</li> <li>合理利用覆盖索引。不使用更新频繁的列做为索引。</li> <li>对长字符串考虑使用前缀索引,前缀索引长度不超过8个字符。</li> <li>索引字段的顺序需要考虑字段值去重之后的个数,个数多的放在前面。</li> <li>使用EXPLAIN判断SQL语句是否合理使用索引,尽量避免extra列出现:Using File Sort,UsingTemporary。</li> <li>UPDATE、DELETE语句需要根据WHERE条件添加索引。</li> <li>合理创建联合索引(避免冗余),(a,b,c) 相当于 (a) 、(a,b) 、(a,b,c),但(a,c)只能用到部分索引。</li> </ul> <h3>索引禁忌</h3> <ul> <li>不在选择性低的列上建立索引,例如&quot;性别&quot;, &quot;状态&quot;, &quot;类型&quot;。</li> <li>不在索引列进行数学运算和函数运算。</li> <li>尽量不使用外键。</li> <li>高并发场景不建议使用唯一索引。</li> <li>不使用前导查询,如like &quot;%ab&quot;,like &quot;%ab%&quot;。</li> </ul> <h3>SQL语句规范</h3> <ul> <li>SQL语句中IN包含的值不应过多(不超过1000个)</li> <li>UPDATE、DELETE语句不使用LIMIT。</li> <li>WHERE条件中必须使用合适的类型,避免MySQL进行隐式类型转化。</li> <li>SELECT语句只获取需要的字段。</li> <li>SELECT、INSERT语句必须显式的指明字段名称,不使用SELECT *,不使用INSERT INTO table()。</li> <li>WHERE条件中的非等值条件(IN、BETWEEN、&lt;、&lt;=、&gt;、&gt;=)会导致后面的条件使用不了索引。</li> <li>避免在SQL语句进行数学运算或者函数运算,容易将业务逻辑和DB耦合在一起。</li> <li>INSERT语句使用batch提交(INSERT INTO table VALUES(),(),()……),values的个数不应过多。</li> <li>避免使用存储过程、触发器、函数等,容易将业务逻辑和DB耦合在一起,并且MySQL的存储过程、触发器、函数中存在一定的bug。</li> <li>避免使用JOIN。</li> <li>使用合理的SQL语句减少与数据库的交互次数。</li> <li>不使用ORDER BY RAND(),使用其他方法替换。</li> <li>建议使用合理的分页方式以提高分页的效率。</li> <li>统计表中记录数时使用COUNT(*),而不是COUNT(primary_key)和COUNT(1)。</li> </ul> <h3>总结:</h3> <ol> <li>char、varchar取值要吝啬,根据实际需求给,比如人名一般不超过5个,varchar(5),不要varchar(200)。int、tinyint这类,int(1)和int(13)都是一样的(在ZERO FILL时不一样)</li> </ol> <pre><code class="language-sql">-- 错误示例、指定varchar时,给定的都是255,实际上关键字、语言code不会达到255长度 CREATE TABLE `ob_keyword_lang` ( `keyword_id` int(10) NOT NULL COMMENT '关键词ID', `langcode` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '语言Code', `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '关键词名称', PRIMARY KEY (`keyword_id`, `langcode`) USING BTREE, INDEX `name`(`name`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '关键词语言表' ROW_FORMAT = Compact; </code></pre> <ol> <li>能NOT NULL 就NOT NULL,char、varchar用NOT NULL DEFAULT '',tinyint、smallint、int用NOT NULL DEFAULT 0</li> </ol>

页面列表

ITEM_HTML