应用程序开发人员常见的数据库开发错误有哪些?


当前回答

这之前已经说过了,但是:索引,索引,还是索引。我见过许多性能不佳的企业web应用程序,它们通过简单地进行一些分析(查看哪些表被频繁访问),然后在这些表上添加索引来解决问题。这甚至不需要太多的SQL编写知识,而且回报是巨大的。

Avoid data duplication like the plague. Some people advocate that a little duplication won't hurt, and will improve performance. Hey, I'm not saying that you have to torture your schema into Third Normal Form, until it's so abstract that not even the DBA's know what's going on. Just understand that whenever you duplicate a set of names, or zipcodes, or shipping codes, the copies WILL fall out of synch with each other eventually. It WILL happen. And then you'll be kicking yourself as you run the weekly maintenance script.

最后:使用清晰、一致、直观的命名约定。与一段编写良好的代码应该是可读的一样,一个好的SQL模式或查询应该是可读的,并且实际上告诉您它在做什么,甚至没有注释。六个月后,当你不得不对桌子进行维护时,你会感谢自己的。“选择account_number, billing_date FROM national_accounts”比“选择ACCNTNBR, BILLDAT FROM NTNLACCTS”更容易使用。

其他回答

使用Access而不是“真正的”数据库。有很多很棒的小型甚至免费的数据库,比如SQL Express、MySQL和SQLite,它们可以更好地工作和扩展。应用程序通常需要以意想不到的方式进行扩展。

不使用参数化查询。它们在停止SQL注入时非常方便。

这是一个不消毒输入数据的具体例子,在另一个回答中提到过。

在修复生产数据库内部的一些问题之前没有进行备份。 在存储过程中的存储对象(如表、视图)上使用DDL命令。 害怕使用存储的proc或害怕在更有效/更合适的地方使用ORM查询。 忽略数据库分析器的使用,它可以准确地告诉您ORM查询最终转换为什么,从而验证逻辑,甚至在不使用ORM时进行调试。

我不得不说,应用程序开发人员犯的最大错误是没有正确地规范化数据库。

作为一名应用程序开发人员,我意识到正确的数据库结构、规范化和维护的重要性;我花了无数的时间自学数据库结构和管理。根据我的经验,每当我开始与不同的开发人员合作时,我通常必须重组整个数据库并更新应用程序以适应,因为它通常是畸形的和有缺陷的。

For example, I started working with a new project where the developer asked me to implement Facebook Connect on the site. I cracked open the database to see what I had to work with and saw that every little bit of information about any given user was crammed into one table. It took me six hours to write a script that would organize the table into four or five separate tables and another two to get the app to use those tables. Please, normalize your databases! It will make everything else less of a headache.

我讨厌开发人员使用嵌套的选择语句,甚至在查询的“select”部分中返回选择语句的结果的函数。

我很惊讶我在其他地方没有看到这个,也许我忽略了它,尽管@adam也有类似的问题。

例子:

SELECT
    (SELECT TOP 1 SomeValue FROM SomeTable WHERE SomeDate = c.Date ORDER BY SomeValue desc) As FirstVal
    ,(SELECT OtherValue FROM SomeOtherTable WHERE SomeOtherCriteria = c.Criteria) As SecondVal
FROM
    MyTable c

在这个场景中,如果MyTable返回10000行,结果就好像查询只运行了20001个查询,因为它必须运行初始查询,并对每一行结果查询一次其他表。

开发人员可以在只返回几行数据且子表通常只有少量数据的开发环境中使用这种查询,但在生产环境中,随着向表中添加更多数据,这种查询的成本可能会呈指数级增长。

一个更好的(不一定完美的)例子是这样的:

SELECT
     s.SomeValue As FirstVal
    ,o.OtherValue As SecondVal
FROM
    MyTable c
    LEFT JOIN (
        SELECT SomeDate, MAX(SomeValue) as SomeValue
        FROM SomeTable 
        GROUP BY SomeDate
     ) s ON c.Date = s.SomeDate
    LEFT JOIN SomeOtherTable o ON c.Criteria = o.SomeOtherCriteria

这允许数据库优化器将数据混合在一起,而不是从主表中重新查询每条记录,我通常发现,当我必须修复产生这个问题的代码时,我通常会将查询速度提高100%或更多,同时减少CPU和内存使用。