数据库新手常犯的5个错误

刚做开发人员的时候,需要掌握的东西非常多。首先是编程语言本身,还有所有你用到的框架的的特定用法,之后(也可能是之前),前端开发的东西也会混进来,在开发过程中你还要考虑数据存在哪的问题。

起初,由于你有太多东西需要迅速掌握,在应用设计的过程中,会倾向于把数据库放在后面考虑(大概因为它对用户的使用体验没什么影响)。结果就是在处理数据库的时候,会发现很多不好的实践。这里举几个例子。

1. Storing images 储存图片

数据库里不应该放图片。你可以做的事情并不代表你就应该去做。图片会占用数据库里相当大的空间,吃掉不必要的 IO 资源从而拖慢应用。这个错误最常出现的情况,就是新人将图片用 base64 编码,然后将其储存在很大的 text/blob 字段当中。

更好的办法是直接将图片上传至像 Amazon S3 这样的云服务上,然后用数据库里用 text 字段储存图片的 URL。每次要加载一张图片的时候,只要把图片的 URL 输出到有效的 <img> 标签里就可以了。这会极大地提升网页的响应速度,对大规模 Web 应用非常有帮助。

2. Limit/Offset

分页在很多应用中都非常常见。从你开始学习 SQL,(你就该知道)最直接的分页方法就是先用 ORDER BY 对数据库的一些列进行排序,然后 LIMIT 返回的结果数,对除第一页外的每一页使用 OFFSET。这看起来很符合逻辑,直到你处理中等规模应用时才意识到:

  1. 它对数据库施加的负载是非常痛苦的。
  2. 它具有不确定性,记录应该随着用户翻页而改变。

不幸的是:分页非常复杂,目前还没有一个万全之策。

3. 用整数做 primary key

在创建 primary key 的时候,几乎所有的 ORM(Object Relational Mapping 对象关系映射)的默认做法都是创建一个串行字段,它是按顺序自动生成的,然后你就可以用它(这些自动生成的数字)作为你的 primary key。在管理员看来,这是非常直观的,因为可以由用户 1 到 用户 2 这样依次查看。对大多数的应用来说,这种做法通常是不错的。但是随着这些整数 primary key 不断变大,你很快就会意识到处理他们会让人筋疲力尽。对于大规模系统,这是很不理想的处理方法。此外,你还会依赖生成这些 key 的那个系统,在你必须要扩大规模的时候,会非常痛苦。更好的解决办法是从一开始就利用好 UUID (Universally Unique Identifier 通用唯一识别码)的优势。

(UUID)还有其它的好处,那就是它不会无形中暴露给用户(数据库中)有多少用户、列表、或是这些 key 所指代的任何东西。

4. 新列中的默认值

无论你做这个工作有多久,都不会一次就创建出一个完美的 schema。最好是将数据库 schema 视为一个持续演化的文档。不幸的是:向数据库中添加一列是件很容易的事,这也就意味着在添加列的时候把工作搞砸同样很容易。默认情况下,如果你新添加了一列,通常是允许有 NULL 值的。这个操作速度很快,但大多数应用实际上不太想让他们的数据里有 null 值,他们会想要设置默认值。

如果你在表里添加设置了默认值的新列,会对这张表触发一次完全的重写。注意:这对应用中的任何(数据量)很大的表都非常不利。(正确的方法)恰恰相反,最好是先允许 null 值存在,这样操作就是即时的,接下来再设置默认值,再用后台进程去回溯更新数据。

实际操作比我所说的要更复杂,幸好已经有一些便利的指南可以为我们提供帮助。

5. 过度标准化

开始学习数据库的标准化的时候,(标准化)感觉就像是很正确的事。你创建了一个 posts 的表,里面包含 authors,每篇文章(post)都属于一个条目(category),所以你又创建了一个 categories 的表,然后再创建一个把它们俩 join 在一起的表,post_categories。从根本上来说,这样做标准化也没什么原则上的错误,但是某种程度上,标准化的收益正在递减。

在上述实例中,categories 可以简单地作为 post 里的一个 varchar 字段。标准化是件很有意义的工作,但是每次处理包含多对多关系的表时都要深思熟虑,想想你是不是真的需要在关系的两边都各用一个单独的表。

修正:值得一提的是,欠标准化也是个问题。这里并不存在“一刀切”的解决方案。有时完全不做标准化和完全标准化也行得通。像 @fuzzychef 说的那样:“适度标准化,即金发姑娘原则(The goldilocks principle,意为适度的是最好的)”。

总结

在 Twitter 上问到这个问题的时候,我得到了很多非常棒的回应,但是这些回应五花八门。从“从不查看 ORM 生成的查询”这样的基本问题,到像事务隔离这样的进阶话题。有一点我并没提到,但是对于所有构建 app 的人来说都非常值得注意的一点就是索引。了解索引的工作原理,知道你需要创建什么样的索引,是获得良好的数据库性能的关键。除了用 Postgres 分析性能的实践步骤以外,还有很多关于索引的基础知识的文章。

通常我会鼓励大家把数据库当做你工具箱中的另一个工具,而不是什么非学不可的恶魔。但我希望,以上的提示可以帮助初学者避免一些基本错误。

原文地址:https://www.cnblogs.com/syncnavigator/p/10198345.html

时间: 2024-10-09 03:01:22

数据库新手常犯的5个错误的相关文章

python新手常犯的17个错误

1)忘记在 if , elif , else , for , while , class ,def 声明末尾添加 :(导致 "SyntaxError :invalid syntax") 该错误将发生在类似如下代码中: 1 2 if spam== 42 print('Hello!') 2) 使用 = 而不是 ==(导致"SyntaxError: invalid syntax") = 是赋值操作符而 == 是等于比较操作.该错误发生在如下代码中: 1 2 if spam

C#新手常犯的错误汇总

本文所述为C#新手常犯的错误,但是实际上很多有经验的程序员也经常犯这些错误,对此特别整理了一下,供大家参考.具体如下: 1.遍历List的错误 ,比如如下代码: List<String> strList =newList<String> for(int i =0; i<strList.Count; i++) { strList.RemoveAt(i); } 这段代码看上去是删除了所有元素,实际上每次调用RemoveAt方法会导致List元素索引重排,最后导致元素没有完全删除.

Python 新手常犯错误

Python 新手常犯错误(第二部分) 转发自:http://blog.jobbole.com/43826/ 作用域 在这篇文章里,我们来关注作用域在Python被误用的地方.通常,当我们定义了一个全局变量(好吧,我这样说是因为讲解的需要——全局变量是不好的),我们用一个函数访问它们是能被Python理解的: 1 2 3 bar = 42 def foo():     print bar 在这里,我们在foo函数里使用了全局变量bar,然后它也如预想的能够正常运行: 1 2 >>> fo

C# 程序员最常犯的 10 个错误

关于C# C#是达成微软公共语言运行库(CLR)的少数语言中的一种.达成CLR的语言可以受益于其带来的特性,如跨语言集成.异常处理.安全性增强.部件组合的简易模型以及调试和分析服务.作为现代的CLR语言,C#是应用最为广泛的,其应用场景针对Windows桌面.移动手机以及服务器环境等复杂.专业的开发项目. C#是种面向对象的强类型语言.C#在编译和运行时都有的强类型检查,使在大多数典型的编程错误能够被尽早地发现,而且位置定位相当精准.相比于那些不拘泥类型,在违规操作很久后才报出可追踪到莫名其妙错

Web开发人员常犯的10个错误

说到开发一个运行在现代网络中的网站:Web开发人员需要选择虚拟主机平台和底层数据存储,准备编写HTML.CSS和JavaScript用的工具,要有设计执行方式,以及一些可用的JavaScript库/框架.在将任务分解为这几步之后,接下来要做的就简单多了,可以去网上找文章,浏览论坛,看看那些能提供更好的Web体验提示的示例. 然而不管是走哪条路,犯错却是每一个开发人员都不可避免的.虽然有些错误与某一个具体的行为相关,但有些错误却是所有Web开发人员都需要面对的挑战.因此,通过研究,体验和观察,我总

销售人员常犯的九项错误

1.忘了自己的微笑 2.争辩 3.离客户太近,过于热情 4.轻易地作出了让步 5.忽略了客户正真的需求 6.轻易地给客户下结论 7.忽略了老客户 8.过于专业 9.轻易地承诺 1.忘了自己的微笑 销售人员走南闯北,有时是刮风下雨.有时天寒地冻.有时烈日炎炎,还有一些人为的因素,不可避免地会带有一些情绪,与客户见面的时候,忘了自己的微笑.心里学上讲,人与人之间的交往,前10秒钟最关键,10秒中决定对方以何种态度跟你接触,微笑是上天赐给我们重要的肢体语言,如果一开始你的肢体语言给对方的印象是:"其实

Spring常犯的十大错误,你踩过吗?

1.错误一:太过关注底层 我们正在解决这个常见错误,是因为 "非我所创" 综合症在软件开发领域很是常见.症状包括经常重写一些常见的代码,很多开发人员都有这种症状. 虽然理解特定库的内部结构及其实现,在很大程度上是好的并且很有必要的(也可以是一个很好的学习过程),但作为软件工程师,不断地处理相同的底层实现细节对个人的开发生涯是有害的. 像 Spring 这种抽象框架的存在是有原因的,它将你从重复地手工劳作中解放出来,并允许你专注于更高层次的细节 -- 领域对象和业务逻辑. 因此,接受抽象

《职业经理人常犯的11个错误》——余世维

相比<赢在执行力>,余博士<职业经理人常犯的11个错误>所谈到的问题更为尖锐,每个问题都一针见血地挑出作为一个处于工作中的人(不仅仅是职业经理)习惯性所容易犯的错误. 第一个错误:拒绝承担责任.“圣人千虑,必有一失”,每个人在日常工作中难免会有犯错误的时候,有效的管理者.有效的员工应该果断为事情的结果承担责任.余博士指出:与其不停地辩解,还不如努力地表现.一句“对不起,这是我的错”.“对不起,我失察了”.“对不起,我刚才犯了个错误”能让事情马上有了结果,直接进入解决错误的局面.因此

Java程序员常犯的10个错误

本文总结了Java程序员常犯的10个错误. #1. 把Array转化成ArrayList 把Array转化成ArrayList,程序员经常用以下方法: List<String> list = Arrays.asList(arr); Arrays.asList() 实际上返回一个ArrayList,但是这个ArrayList是Arrays的一个内部私有类,而不是java.util.ArrayList类.这个私有类java.util.Arrays.ArrayList有set(), get(), c