mysql 标准

1、数据库命名规范,统一:vip_xxxx

0、表一旦设计好,字段只允许增加,不允许减少(drop column)

1、统一使用INNODB存储引擎,UTF8编码(整个数据库的编码统一为utf8_general_ci,为此不需要建立表的DDL加上特别CHARACTER SET utf8 COLLATE utf8_general_ci);

2、需在设计阶段考虑如果访问量非常大,且不做scale out表拆分的话,需读写分离,但读写分离注意主从复制有延迟的可能性;

3、禁用Stored procedure (包括存储过程,函数,触发器);

4、UUID(),USER()这样的MYSQL INSIDE函数对于复制来说是很危险的,会导致主备数据不一致,重要的是会严重影响mysql性能,禁止使用

5、表必须有主键,建议统一由Auto-Increment字段生成整型,不建议使用组合主键,自增id只作为虚拟主键,不建议与业务数据处理有关联关系,如果把控不好,会有问题(案例:AUTO_INCREMENT主键字段不要与业务有关联关系

6、库名、表名、字段名、索引名必须使用小写字母;

7、多表join的时候,写SQL的时候一定要给每个字段指定表名做前缀;如: select a.id,a.name from test1 a, test2 b where a.id=b.id

8、如果应用使用的是长连接,应用必须具有自动重连的机制。但请避免每执行一个SQL去检查一次DB可用性;

9、如果应用使用的是长连接,应用应该具有连接的TIMEOUT检查机制,及时回收长时间没有使用的连接,TIMEOUT时间一般建议为20min。

10、存储精确浮点数必须使用DECIMAL替代FLOAT和DOUBLE,如金额等。

11、尽量用单表查询,避免多表JOIN。

12、表名列名必须有注释(必须加上COMMENT '<字段扼要解说>'),表结构变更须由库表OWNER所在团队发起,

13、SQL语句必须采用preparedStatement技术, 如果编程语言不支持preparedStatement技术,需要做好特殊字符过滤,如不要前后有空串等

14、尽可能不要使用TEXT、BLOB、char,请使用VARCHAR(N),N表示的是字符数不是字节数,比如VARCHAR(255),可以最大可存储255个汉字,需要根据实际的宽度来选择N,请注意同一表中,所有varchar字段的长度加起来,不能大于65535。

15、每张表数据量建议控制在千万级别行以下,为此设计阶段需考虑数据的归档。

16、如果字段只有true or false,请使用tinyint(数值范围-128~127),如模块分类:1订单 2商品;删除标志 0正常,1删除;状态 1为可选,2为不可选等等

17、存储时间(精确到秒)建议使用TIMESTAMP类型,因为TIMESTAMP使用4字节,DATETIME使用8个字节,同时TIMESTAMP具有自动赋值以及自动更新的特性。

18、每个字段的默认值不能用NULL,禁止default NULL,数字类型default 0,字符类型default '';

19、关键业务数据表,建议有create_time和last_update_time,方便后期数据分析,如订单表,库存表;

20、MySQL上,禁止使用select col、col from table where id in (select col from table)这样的子查询;

21、需要多表join的字段(禁止多于两表join),数据类型保持绝对一致。

22、关键业务数据表,如订单表,用户信息表,钱包支付信息等,禁止硬删除,必须软删除,加上is_deleted字段,标注这条记录的状态。

23、加字段禁止使用after,因为你不确定全局代码里面(如其他团队使用你的表)是否都insert into table(col,col,col。。。) value,如果你在中间插一个字段,就导致数据偏移的问题了,影响可大可小,同样select * 的也可能会影响数值的偏移,所以才要求,禁止after,必须带default(第18点要求)。

24、线上MySQL是忽略大小写的(配置了lower_case_table_names=1),如下面的例子:

 

 

 

事务的处理标准

0、一个事务,处理的行数不能超过1000 rows/s (曾经发生过的案例,超出了会导致主从复制延迟的问题

1、禁止一些框架或定制化的底层类等使用set autocommit=0;set autocommit=1;这样控制事务,应该由程序把控,需要时begin;操作完后及时commit2、要合理使用事务,例子:购物车如下的 事务处理,可以更好的优化。

 

下面的事务可以更好的优化,start transection后,select 1次,insert 2次,seletc 1次,update 1次,总:2 QPS,3 TPS,然后没有库存 rollback,这种在正常情况下没有问题的,按如小米这种极端抢购的情况下,会大大浪费了购物车数据库的CPU资源
########################################################
#如用户ID:72965761,一次事务的操作
########################################################
Query SET NAMES utf8
Query start transaction
Query SELECT `cart`.`id`, `cart`.`user_id`, `cart`.`warehouse`, `cart`.`add_time`, `cart`.`expire_time`, `cart`.`add_type` FROM `cart` WHERE (user_id =72965761 OR user_id=-72965761) AND (warehouse = 'VIP_NH') AND (expire_time >= 1408084591) ORDER BY `id` DESC LIMIT 1
Query INSERT IGNORE INTO `cart` (`user_id`, `warehouse`, `add_time`, `expire_time`, `add_type`) VALUES (72965761, 'VIP_NH', 1408084591, 1408085791, 0)
Query INSERT IGNORE INTO `user_cart` (`cart_id`, `user_id`, `product_id`, `size`, `num`, `add_time`, `warehouse`, `product_info`, `brand_id`, `suite_id`, `active_id`, `active_limit_id`, `active_no`, `add_type`) VALUES (442034, 72965761, '30014072', '78845863', '1', 1408084591, 'VIP_NH', '', '210123', 0, 0, 0, '', 0)
Query SELECT `user_cart`.`id` FROM `user_cart` WHERE (cart_id = 442034 AND flag = '0')
Query UPDATE `user_cart` SET `add_time` = 1408084591 WHERE id in ('711744') AND flag = '0'
Query rollback
Quit

 

索引使用标准

 

1、非唯一索引建议使用“idx_表缩写名称_字段缩写名称”进行命名。

2、唯一索引建议使用“uniq_表缩写名称_字段缩写名称”进行命名。

3、索引名称必须使用小写。

4、唯一键不和主键重复。

5、索引字段的顺序需要考虑字段值去重之后的个数,个数多的放在前面,就是数据分布。

6、使用EXPLAIN判断SQL语句是否合理使用索引,尽量避免extra列出现:Using File Sort,Using Temporary。

7、UPDATE、DELETE语句需要根据WHERE条件添加索引。

8、合理创建联合索引(避免冗余),(a,b,c) 相当于 (a) 、(a,b) 、(a,b,c)。

9、合理利用覆盖索引。比如SELECT email,uid FROM user_email WHERE uid=xx,如果uid不是主键,适当时候可以将索引添加为index(uid,email),以获得性能提升。

 

 

 

约束设计

a) 主键的内容不能被修改。

b) 外键约束一般不在数据库上创建,只表达一个逻辑的概念,由程序控制。

d) 禁用数据库外键

命名

a) 主键约束:默认PRIMARY;

b) unique约束:UK_<column_name>

c) check约束: CK_<column_name>

d) 外键约束: 业务禁用

 

 

SQL语句标准

 

0、禁止多于3表的join。

1、使用prepared statement,可以***能并且避免SQL注入。

2、SELECT语句只获取需要的字段,禁止使用SELECT * FROM语句,这是有效防止新增字段对应用逻辑的影响,还能减少对性能的影响;

3、INSERT语句必须显式的指明字段名称,不使用INSERT INTO table value()。

4、禁止在where子句中对字段施加函数,如to_date(add_time)>xxxxx,应改为:add_time >= unix_timestamp(date_add(str_to_date('20130227','%Y%m%d'),interval - 29 day))

5、UPDATE、DELETE语句不使用LIMIT。

6、写到应用程序里的SQL语句,禁止一切DDL操作,如对这些权限有要求,必需与DBA协商同意方可使用

7、WHERE条件中必须使用合适的类型,避免MySQL进行隐式类型转化,如ISENDED=1,字段类型是tinyint,那么不能是ISENDED=‘1’。

8、避免在SQL语句进行数学运算或者函数运算,容易将业务逻辑和DB耦合在一起。

9、INSERT语句使用batch提交。

10、避免使用存储过程、触发器、函数等,容易将业务逻辑和DB耦合在一起,并且MySQL的存储过程、触发器、函数中存在一定的bug。

11、使用合理的SQL语句减少与数据库的交互次数。

12、不使用ORDER BY RAND(),使用其他方法替换。

13、建议使用合理的分页方式以提高分页的效率。

14、InnoDB表避免使用COUNT(*)操作,计数统计实时要求较强可以使用memcache或者redis,非实时统计可以使用单独统计表,定时更新。

15、不建议使用%前缀模糊查询,例如LIKE “%weibo”。

16、避免多余的排序。使用GROUP BY 时,默认会进行排序,当你不需要排序时,可以使用order by null,例如Select a.OwnerUserID,count(*) cnt from DP_MessageList a group by a.OwnerUserID order by null;

 

  

 

每个整数类型的存储和范围。

 

类型

字节

最小值

最大值

(带符号的/无符号的)

(带符号的/无符号的)

TINYINT

1

-128

127

0

255

SMALLINT

2

-32768

32767

0

65535

MEDIUMINT

3

-8388608

8388607

0

16777215

INT

4

-2147483648

2147483647

0

4294967295

BIGINT

8

-9223372036854775808

9223372036854775807

0

18446744073709551615

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章