对于新手容易在数据库上犯的五个错误

Posted by 启示录 Blog on June 11, 2016

1.存储图片到数据库中

千万不要把图片存储到数据库中,有些初学者喜欢把图片转换成base64的编码,然后使用数据库的text/blob对象存储,这里非常不建议这样做,因为它会消耗你数据库的大量I/O资源。而且转换后的对象也非常占存储空间。最终导致整个数据库的存储空间极速增长。 在国内推荐使用云存储服务(譬如:七牛,又拍云等),然后存储url即可。在你的web应用中可以使用 <img>标签显示图片。而且也可以优化你的应用。因为这些云存储服务都提供有CDN的功能。

2.Limit/Offset

分页对于一个web应用是非常常见的。在以往的CMS,电商平台等信息流展示平台都会有分页。因为一次性加载所有资源是很耗费资源的,并且用户体验很不好。常见的方法就是先使用ORDER BY对结果排序后再使用LIMIT返回一定的条数的结果,也会使用OFFSET设置偏移值。这个逻辑似乎没有什么问题,但是当数据量达到一定的数量的时候,问题就出现了:

  • 数据库的压力会增加,因为要进行大规模数据排序与分页
  • 数据在不断修改(增,删)所以会导致分页的内容不确定,在变化

分页也是一件比较复杂的事情,尤其是对于大规模的数据来说,每次一次的排序与分页都要扫描整个表。这里可以看看pg中的利用ctid的实现方案Five ways to paginate in Postgres, from the basic to the exotic

3.使用整数型作为主键

以前我经常使用数据库内建的自增序列作为主键来使用,很多ORM也是这样的做的,例如操作某个用户的时候就是/user/1,/user/2。这种方法对于小型系统还可以,但是对于大型的系统来说,如果当值超过数据库内建的数据类型长度如何处理?这也不例如系统扩展,这需要额外的发号系统。此外这样做还有很多安全问题,例如,其他人可以通过枚举很轻松的获得有多少条纪录。多少用户。这里可以使用UUID来做为唯一标识符。我所知道pg的uuid-ossp模块是支持的。

4.在新字段中设置默认值

在项目中可能会遇到对于正在运行中的环境,需要新增一个字段,很多情况下在新增字段的时候会设置一个默认值,但是对于数据量较大的表来说,整个过程会造成写锁表。如果是单独的添加一个字段,那么速度还是挺快的,如果是添加字段并设置默认值就另当别论了。所以对于大表最好不要这么做,这里可以使用新字段的方式,先添加字段再更新,具体可以看看别人的在线数据迁移案例

5.太注重规范

例如我们有一个文章表(posts),然后文章可能属于不同的分类,这时你可能需要建立一个categories表,为了把两者关联起来,又需要创建一个post_categories关联表。这样看起来并没有什么问题,但是对于上面的情况,我们是否可以直接使用一个数组字段来存储所属的分类?规范或许有些时候可以帮助你解决很多问题,但是你的问题真的只有标准化的理论才能解决么?最适合你的才是最好的标准规范,条理分明可能不适合你。在国外,有一个《金发姑娘和三只熊》的童话故事,里面有一个重要的原则:“金发姑娘原则”或许可能帮助你理解你所需要的具体是什么。

总结

这些只是实践过程中容易遇到的几个问题,但是事实上遇到的问题并不止如此。在做的时候需要去思考这样做是否真的合理。是否真的适合我的应用场景。多思考,多总结才能进步。

本文来自Five Mistakes Beginners Make When Working With Databases,但并不全是来自于此。