具有 DEFAULT NULL 的 MySQL 列 - 风格选择,或者是它?
Posted
技术标签:
【中文标题】具有 DEFAULT NULL 的 MySQL 列 - 风格选择,或者是它?【英文标题】:MySQL columns with DEFAULT NULL - stylistic choice, or is it? 【发布时间】:2012-08-28 12:27:04 【问题描述】:在许多 SQL 风格中,您可以通过三种方式在每次插入行时将列隐式设置为 NULL。它们是:
columnname type NULL
columnname type DEFAULT NULL
columnname type NULL DEFAULT NULL
即第一个设置 NULL 标志(与 NOT NULL 相对),第二个将 NULL 标志保留为默认值,第三个设置 NULL 标志并将隐式值设置为 NULL。
我听说在 Microsoft SQL 中,第二个变体并不完全相同,因为您还可以为表或模式自定义 NULL 标志的默认值。
但是对于 mysql,我不相信有这样的功能。此外,在 MySQL 中,与 NOT NULL 列不同,带有 NULL 标志的列在没有显式值的情况下总是在插入时隐式设置为 NULL,即使打开了严格模式也是如此。因此,所有这些列声明都是相同的。
在我的 MySQL 脚本中,对于每个 NOT NULL 列,我为我不希望在我的应用程序的某些插入中设置的列指定一个 DEFAULT 值,以避免在启用严格模式时出现任何问题。因此,我觉得如果我选择第三种变体会更加对称,即使它是最冗长和明确的。像第三种变体这样的声明是常见的,还是第一种或第二种变体更频繁地出现在其他人的脚本中?
我正在考虑倾向于第二种方法,因为这是 MySQL 转储使用的别名,但我不确定这是一个好主意,因为它还在列声明的默认子句中将整数文字转储为字符串(单引号)。
这个问题似乎比有解决方案的问题更具意见,但我也想知道我不知道的任何潜在问题。将来我可能会选择从 MySQL 迁移到 PostgreSQL,我也可以参考那些专家的一些建议,例如如果 PostgreSQL 像 MS-SQL 那样区分这些情况。如果我做了任何不正确的假设,请纠正我。
【问题讨论】:
我不确定您是否知道,但在 MySQL 中,您可以为可为空的列设置默认值(不为空)。如果在插入时未能为该列指定值,则该列具有其默认值。您还可以显式指定要插入 null,在这种情况下,该列为 null。例如,您可以将列指定为SMALLINT DEFAULT 3
。然后,如果您显式插入一个非空整数值,它将存储该值;如果显式插入 null,它会存储 null;如果插入时不指定值,则存储3,即默认值。
是的!不过,我只担心默认值为 null 的列。
或许这个问题更适合Software Engineering?
DataGrip 是一种 SQL IDE,可在您键入时自动完成 SQL 语句。它提供了“所有列”版本和用于自动完成的“最小列”版本。在我使用的版本中,可以包含 null 但没有显式默认 IS 的列包含在“最小列”版本中,即使该列可以省略。出于这个原因,我更喜欢明确; "NULL DEFAULT NULL"。
【参考方案1】:
我遇到的每个数据库都按照您描述它们的方式处理 NULL。当列接受 NULL 值时,如果在 INSERT 上不提供值,则默认值为 NULL。我相信这是 ANSI 标准行为的一部分。
至于指定“NULL”本身。这是一个偏好问题。标准确实说列允许 NULL 除非 NOT NULL 被指定(在数据定义语言的级别)。因此,NULL 本身是不必要的,您还有第四个等效选项:
columnname type
NULL 通过 ANSI 标准完全嵌入在 SQL 语言中。您的第三个选项是最明确的,但它看起来也有点不寻常。
如果您计划在整个系统中保持超级一致,那么我会选择您正在走的路。对于每个表中的每一列都有 NULL 或 NOT NULL。对于所有采用默认值的列,请使用 DEFAULT 语句。
但是,不要指望与您一起工作的其他人(现在或将来)会轻易效仿这个例子。在这种情况下,许多人更喜欢第四个选项,因为它需要更少的输入,并且是所有(或几乎所有)SQL 方言的行为方式。
【讨论】:
是的。几乎没有人写显式的SELECT ALL
,而是使用隐式的(和等效的)SELECT
。
虽然 eggyal 有很好的观点(以及对 MySQL 文档的引用),但您的信息清楚地表明它是一个 SQL 标准,而不仅仅是一个 MySQL 标准。因为我相信如果我要更改数据库系统,我将不必重新访问列定义的这个特定部分,并且大多数人应该知道隐式修饰符,所以我将坚持使用你给出的最简洁的别名。谢谢!【参考方案2】:
如Data Type Default Values 中所述:
如果列可以将
NULL
作为值,则使用显式DEFAULT NULL
子句定义该列。
(我认为他们的意思是隐式,而不是显式)。
此外,如CREATE TABLE
Syntax 中所述:
如果既没有指定
NULL
也没有指定NOT NULL
,则将该列视为已指定NULL
。
因此,在 MySQL 中,以下列定义都是相同的:
columnname type
columnname type NULL
columnname type DEFAULT NULL
columnname type NULL DEFAULT NULL
选择使用哪个是明确和简洁之间的平衡。根据情况,我可能会使用上述任何一种。
【讨论】:
请注意,TIMESTAMP
类型存在边缘情况。如果您的列被声明为stamp TIMESTAMP
,并且您在不指定stamp
的值的情况下执行INSERT,它将默认使用当前UTC 日期时间的值进行INSERTing。如果将列声明为stamp TIMESTAMP NULL
,则 INSERTs 将默认为 NULL。以上是关于具有 DEFAULT NULL 的 MySQL 列 - 风格选择,或者是它?的主要内容,如果未能解决你的问题,请参考以下文章