239

我在一个有很多不同领域的网站上有一个表格。有些字段是可选的,而有些是强制性的。在我的数据库中,我有一个包含所有这些值的表,在用户没有放置任何数据的数据库列中插入 NULL 值或空字符串是更好的做法吗?

4

6 回答 6

226

通过使用NULL可以区分“不放数据”和“放空数据”。

还有一些区别:

  • 一个LENGTH是,一个空字符串NULL是。NULLLENGTH0

  • NULLs 在空字符串之前排序。

  • COUNT(message)将计算空字符串但不计算NULLs

  • 您可以使用绑定变量搜索空字符串,但不能搜索NULL. 这个查询:

    SELECT  *
    FROM    mytable 
    WHERE   mytext = ?
    

    永远不会匹配 a NULLin mytext,无论您从客户端传递什么值。要匹配NULLs,您必须使用其他查询:

    SELECT  *
    FROM    mytable 
    WHERE   mytext IS NULL
    
于 2009-08-12T18:50:30.363 回答
46

如果您计划切换数据库,需要考虑的一件事是Oracle不支持空字符串。它们会自动转换为 NULL,您不能使用诸如WHERE somefield = ''.

于 2009-08-12T18:59:37.210 回答
10

要记住的一件事是,NULL 可能会使您的代码路径更加困难。例如,在 Python 中,大多数数据库适配器/ORM 映射NULLNone.

所以像:

print "Hello, %(title)s %(firstname) %(lastname)!" % databaserow

可能会导致“你好,没有 Joe Doe!” 为避免这种情况,您需要类似以下代码:

if databaserow.title:
    print "Hello, %(title)s %(firstname) %(lastname)!" % databaserow
else:
    print "Hello, %(firstname) %(lastname)!" % databaserow

这会使事情变得更加复杂。

于 2009-08-12T19:08:39.903 回答
9

更好地插入NULL以在 MySQL 中的数据库中保持一致性。外键可以存储为NULL但不能存储为空字符串。

您将遇到约束中的空字符串的问题。您可能必须插入具有唯一空字符串的假记录以满足外键约束。我猜是不好的做法。

另请参阅:外键可以为 NULL 和/或重复吗?

于 2016-10-20T07:43:59.670 回答
6

我不知道这里的最佳实践是什么,但我通常会错误地支持 null,除非您希望 null 表示与空字符串不同的东西,并且用户的输入与您的空字符串定义相匹配。

请注意,我是说您需要定义您希望它们如何不同。有时让它们不同是有意义的,有时则不然。如果没有,只需选择一个并坚持下去。就像我说的,大多数时候我倾向于使用 NULL。

哦,请记住,如果该列为空,则记录几乎不会出现在基于该列选择(在 SQL 术语中具有 where 子句)的任何查询中,除非选择是针对空列当然。

于 2009-08-12T18:53:26.393 回答
2

如果您在唯一索引中使用多个列,并且这些列中至少有一个是必需的(即必需的表单字段),如果您将索引中的其他列设置为 NULL,您最终可能会出现重复的行。这是因为 NULL 值在唯一列中被忽略。在这种情况下,在唯一索引的其他列中使用空字符串以避免重复行。

唯一索引中的列:
(event_type_id、event_title、日期、位置、网址)

示例 1:
(1, '烧烤', '2018-07-27', null, null)
(1, 'BBQ', '2018-07-27', null, null) // 允许和重复。

示例 2:
(1, '烧烤', '2018-07-27', '', '')
(1, 'BBQ', '2018-07-27', '', '') // 不允许,因为它是重复的。

以下是一些代码:

CREATE TABLE `test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `event_id` int(11) DEFAULT NULL,
  `event_title` varchar(50) DEFAULT NULL,
  `date` date DEFAULT NULL,
  `location` varchar(50) DEFAULT NULL,
  `url` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `event_id` (`event_id`,`event_title`,`date`,`location`,`url`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

现在插入它以查看它是否允许重复的行:

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-27', NULL, NULL);

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-27', NULL, NULL);

现在插入它并检查它是否不允许:

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-28', '', '');

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-28', '', '');

所以,这里没有对错。由您决定什么最适合您的业务规则。

于 2018-07-27T15:19:38.603 回答