使用应用程序代码强制NOT NULL是错误的吗


Is it wrong to enforce NOT NULL using application code?

我的MySQL数据库中大约有6个表,比如

mysql> describe Quiz;
+--------------+-------------+------+-----+---------+----------------+
| Field        | Type        | Null | Key | Default | Extra          |
+--------------+-------------+------+-----+---------+----------------+
| quiz_id      | int(11)     | NO   | PRI | NULL    | auto_increment |
| name         | varchar(25) | YES  |     | NULL    |                |
| category     | varchar(20) | YES  |     | NULL    |                |
| is_published | tinyint(1)  | YES  |     | 0       |                |
| open_count   | int(11)     | YES  |     | 0       |                |
| finish_count | int(11)     | YES  |     | 0       |                |
+--------------+-------------+------+-----+---------+----------------+

在所有6个表中,在编写CREATE TABLE ...时,我没有对每个属性强制执行NOT NULL(如上所示),但它们应该不是NULL。

行将使用我的PHP代码插入这些表中。因此,在插入之前,我可以确保它们都不是NULL。

我想知道,使用应用程序代码而不是MySQL强制执行NOT NULL是否存在缺陷

在我的脑海中,除了在代码中执行外,我还可以给您两个在数据库中强制执行它的理由。

  • 如果PHP代码中出现错误,则数据不会损坏。如果您只是从数据库中检查返回代码,就会立即注意到这个错误。

  • 如果有人决定手动更新数据库中的数据,他们将不会错误地将应用程序代码无法处理的字段保留为NULL。

最好的做法是在数据库和应用程序中强制执行约束。在数据库中具有约束是至关重要的,因为数据库可以由其他应用程序访问,甚至可以手动更新(如果我们谈论MySQL,可以从workbench中进行更新)。

另一方面,适当的前端应用程序应该始终检查要进入数据库的表单的值。

在您的情况下,通过在表中使用ALTER语句,将约束添加到数据库字段应该很容易。

我希望这能帮助你做出决定。

这不一定是一个"缺陷",因为它可以工作,但如果某些存储引擎将列定义为NOT NULL,MySQL查询优化器会对列进行不同的处理。

编写自己的代码来执行它也更麻烦。

为什么不在你的桌子上运行一个ALTER,使它们成为NOT NULL呢?

您应该在两者中强制执行它。

应用程序有错误,您永远不希望它们危及数据库的完整性。设置适当的列规范是防止这种情况发生的地方。

作为一般原则,最好在数据库级别使用诸如not null之类的约束。这意味着,未来可能使用该数据库的任何其他应用程序(或您的应用程序的版本2)都不必包含此数据完整性逻辑(如果不需要)。

将数据完整性留给数据库,将应用程序逻辑留给应用程序

在数据库级别强制执行约束听起来是正确的。但就我个人而言,我不遵循这种做法,也不在代码级别强制执行这种完整性:

  • 约束条件经常发生变化,特别是在开发的早期阶段
  • 如果需要修改约束条件,我会尽量限制需要更改的位置数量
  • 在数据库中有一些约束是不能做的——比如在电子邮件地址字段中强制执行电子邮件地址,只使用alhpa数字的用户名等等——我将它们视为另一种形式的约束,并在代码中实现它们。同样适用于null/not null