13

MySQL中的哥哥表、妹妹字段,是什么鬼?

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzA4MTc4NTUxNQ%3D%3D&%3Bmid=2650523039&%3Bidx=1&%3Bsn=61be3e8a49223049623780a3cc03b870
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

e6JBVrU.gif!mobile

原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。

晚上,我被叫进宽大的办公室,总监正在煮茶。高压锅煮着长嘴茶壶,水蒸气缭绕。领导举手之间,淡黄茶水奔涌而出,倒立而下浇上茶叶,漏出两杯茶水。

“喝茶?”领导推给我一杯,然后自己抿了一口。沉默良久,把显示器转到我这边:“最近数据库表出现了些有意思的东西,你来看看”。

我探着脑袋一瞧,心凉了半截。

时隔五年,又在项目里见到 哥哥 表和 妹妹 字段,着实让我坐立不安。所谓哥哥表,就是名称叫做 gg 的数据库表,意为 公共 ;所谓妹妹字段,就是名称叫做 mm 的表子段,意为 密码 。比起shit mountain来,这些命名更让人浮想联翩,实为不规范之典范。

vmQNRvZ.png!mobile

这么魔幻的事情,不止一次出现,任何领导都会坐不住。可惜的是,一次次的会议,专项讨论某一个SQL禁止条例,到最后还是大开方便之门,过往的规范承诺皆抛之脑外。

数据库命名规范是最基础的规范,连这个都没做好,证明监管工作确实出现了纰漏。我赶紧掏出自己的手机,翻到xjjdog的文章,打算把数据库要注意的点,给领导汇报一下。

也顺便向大家汇报。

我把规范分成了统一的规范、索引规范、SQL规范、命名规范、安全规范、性能小Case等6个部分。

请听我慢慢道来。

1. 统一的规范

首先,我们来一些通用的规范。这里有很多是经验值,如果你的数据库所在的宿主机硬件,并不是十分的牛X,可以考虑再降低一下标准。

存储引擎:请统一使用innodb存储引擎,特殊的数据库引擎必须通过DBA的评审。

字符集:统一使用utf8字符集。这个要从应用程序、服务器、数据库的表、字段等全部统一起来。注意:MySQL中的 utf8mb4 字符集,才是真正的utf8,请用这个。

作用范围:不要在MySQL存储大对象,比如图片、音乐等;不要用MySQL做Gis运算、全文检索;不使用存储过程、触发器、函数、外键,避免破坏数据库的性能和扩展性。

使用上限:

  • 每个MySQL实例,数据库不要超过50个;

  • 单数据库容量,不要超过500GB,否则分库;

  • 单表记录数量,不要超过5000W,否则分表;

  • 单表子段数量,不要超过30个,否则拆表;

  • 单张表中索引数量不超过5个,单个索引中的字段数不超过5个;

  • varchar字段最大值不超过1024;注意:VARCHAR(N)中的N表示字符数而非字节数

2. 索引规范

索引是数据库中非常重要的结构,可以加速数据的检索。但索引是要占用大量空间的,如果你的数据表里面没几条记录,就不必创建索引。比如2000条以下。

ZBf6ZzJ.png!mobile

选择性很小的字段(低基数列),不要加索引。比如一些state,type,布尔判断等。因为加了也没用。

尽量让索引的内容尽量的短!比较长的子段,要使用前缀索引。比如: title varchar (64) ,可以创建前缀索引  idx_title (title(16))

合理利用索引的最左原则,合并相似的索引。比如 (a) (ab) (abc)三种索引需求,我们只需要创建abc这一个索引就ok了。

避免在索引列做计算(这将造成索引失效),比如 data_format(created_date)substring(short_name,0,6) = 'xjjdog'

不能使用 % 前缀模糊查询,因为无法使用索引,例如: WHERE name LIKE '%味道'

不能使用数据库端做全文检索操作。虽然它支持,也不要这么做。

索引的命名要有章可循: idx_ 前缀表明是普通索引,而  uk_ 前缀表明的是唯一索引。

3. SQL规范

建议在每个表中,添加下面三个字段。其实,SpringBoot JPA,也建议你添加上这三个字段。根据时间字段,除了审计,还能够做一些非常nice的迁移操作;version字段是高并发下的乐观锁实现,UPDATE语句可以结合version字段,避免并发操作造成的不一致情况。

  • created:记录创建时间,时间类型

  • modified:记录修改时间,时间类型

  • version:“乐观锁”的版本标记,long型,默认为0

大多数字段应该定义成 not null 的,并分配默认值,但是不要 default null ,因为数据库无法索引null值。

复杂的SQL查询语句,是绝对要避免的。我们所说的,就是慢查询。慢查询会占用大量资源,并阻塞线程,应该见谅将大SQL拆分成多条简单的SQL,减少数据的锁定时间。

另外,不要在不同数据类型的字段上进行比较,避免字段类型转换造成性能损失,这就要求我们在SQL语句中传入的参数类型,和数据库中所定义的类型是相同的。 n2y67fY.png!mobile

禁止使用 select * 进行输出,应该选择具体的字段进行输出。除了避免无用的字段造成传输上的性能损耗,还能在一定程度上避免敏感信息的泄漏。

SQL中避免出现now()、rand()、sysdate()、current_user()等不确定结果的函数。

禁止使用order by rand()。

插入语句,不要直接使用 nsert into table values(),而应该加入具体的字段,否则无法适应数据库变更情况。在做批量插入时,一次性操作100-200条就可以,没必要把batch数量设置成上千上万。

禁止非框架类业务代码,直接调用 set sql_mode 或者 set tx_isolation ,禁止使用 SELECT … FOR UPDAT ,优先采用乐观锁实现。

多表关联不要超过3个,尽量拆分成简单的SQL处理。

大多数开发人员会在需要时写UNION,这往往会导致执行一个排序来消除重复。应该尽量使用UNION ALL来代替UNION。

注意OR语句的一些改善情况。比如 WHERE id=1 OR id=2 可以 改写为 WHERE id IN(1,2) 。在不同的字段,可以将OR改写为 UNION ALL

4. 命名规范

数据库表和字段的命名,不要使用驼峰命名方式。比如,不能叫 saleOrder ,而应该叫做 sale_order 。因为大多数数据库,都不区分大小写,下划线命名会更安全。

这些命名,只能使用英文小写字母、数字和下划线,长度不超过17个字符。

命名应该有确切的含义。和代码规范一样,不允许使用a,b等无意义的字符串。不允许中文拼音缩写、中英文混用等。

严禁出现哥哥表和妹妹字段。

5. 安全安全安全

ENvqEjF.png!mobile

(1) 服务器隔离 如果你的公司有多个环境,比如dev环境,测试环境等,就要做好相应的隔离。比如,不允许在线上环境直接进行开发和测试、禁止在线上做数据库压⼒力测试。这是非常重要的,避免了无谓的数据错乱。如果条件允许,甚至可以做物理隔离,用不同的IP段进行区分。不长脑子的程序员有很多,你永远不知道他们连的是哪个环境的数据库。

(2)账户的权限 永远不要在生产上,让root账号远程可连。对不同的应用,应该分配不同的database,并建立相互隔离的账号。

账号默认开启select/insert/update/delete/execute的权限就可以。create都不能放开,用根本上杜绝程序员们删库跑路的机会。

针对安全级别高的应用,应分配读写账号。读账号去掉各种更新权限,只能做一些sql查询。账号命名方式上,可以加入 _w 或者 _r 后缀,表明它们的意图。

对于SQL的传入参数(数字,字符和混用)必须进行合法性检查,防止SQL注入。业务应该提前准备好风险SQL语句,进行集中审核,负责后果自负。

6. 性能小case

如有自增字段,请使用无符号型(unsigned)int或bigint 。优先使用更小的数据类型,比如:

  • 数字用tinyint、smallint、mediumint、int、bigint类型;

  • 日期用date、datetime类型;

  • 时间用timestamp、int类型;

  • 不使用char、varchar存储日期和时间;

  • 使用更小的数据类型,能用tinyint的就不用smallint,能用timestamp的就不用datetime类型;

不能使用tinyblob、mediumblob、blob和longblob类型字段,对于表存在大字段类型,应当考虑单独拆分。

OLTP数据库绝对要避免大事务和数据库端运算,可以考虑使用NoSQL或者大数据计算平台。

End

可以看到,我们规范里,有些禁止的东西,其实最后还是用了。比如分区表、大字段存储、GIS操作。但这是和规范不冲突的。

规范,只定义了一些常见的可能会引起严重后果的操作禁止,然后将风险的事情,交给专业的人去做,并评估、控制风险点的规模。

规范定了,要执行才行。不论是人工的review,还是工具的检测。如此,系统才能健康成长,程序员才能不加班,领导才能开上保时捷。

这时候,我汇报完毕,抬头向领导望去。他的头倚在真皮座椅后背上,已经沉沉的的睡了过去。我把外套轻轻脱下来,披在他身上,这才捧过自己的茶杯,咕咚一口喝了下去。虽然茶已经凉了,但醇香一直在嘴中缭绕。

作者简介: 小姐姐味道 (xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信xjjdog0,欢迎添加好友,进一步交流。

推荐阅读:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK