我在一个有很多不同领域的网站上有一个表格。某些字段是可选字段,而某些字段是必填字段。在我的数据库中,我有一个包含所有这些值的表,是否更好的做法是将NULL值或空字符串插入到用户未放置任何数据的DB列中?
答案 0 :(得分:213)
使用NULL
,您可以区分“无数据”和“放空数据”。
更多差异:
LENGTH
NULL
为NULL
,LENGTH
为空字符串为0
。
NULL
在空字符串之前排序。
COUNT(message)
将计算空字符串但不计算NULL
s
您可以使用绑定变量搜索空字符串,但不能搜索NULL
。这个查询:
SELECT *
FROM mytable
WHERE mytext = ?
永远不会匹配NULL
中的mytext
,无论您从客户端传递什么值。要匹配NULL
,您必须使用其他查询:
SELECT *
FROM mytable
WHERE mytext IS NULL
答案 1 :(得分:41)
如果您曾计划切换数据库,那么需要考虑的是Oracle does not support empty strings。它们会自动转换为NULL,您无法使用WHERE somefield = ''
等条款查询它们。
答案 2 :(得分:8)
要记住的一件事是NULL可能会使您的代码路径变得更加困难。例如,在Python中,大多数数据库适配器/ ORM将NULL
映射到None
。
所以像:
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
这可能会使事情变得更加复杂。
答案 3 :(得分:8)
最好在MySQL中插入NULL
以保证数据库的一致性。外键可以存储为NULL
,但不能存储为空字符串。
约束中的空字符串会出现问题。 您可能必须插入带有唯一空字符串的虚假记录以满足外键约束。我猜错了。
答案 4 :(得分:4)
我不知道这里有什么最佳实践,但我通常会支持null,除非你想要null表示与empty-string不同的东西,并且用户的输入与你的空字符串定义匹配。 / p>
请注意,我说你需要定义你希望它们与众不同的方式。有时候让它们与众不同是有意义的,有时则不然。如果没有,只需选择一个并坚持下去。就像我说的那样,我倾向于大多数时候都喜欢NULL。
哦,请记住,如果列为null,则记录不太可能出现在几乎任何基于该列选择(在SQL术语中具有where子句)的查询中,除非选择是当然是一个空列。
答案 5 :(得分:0)
如果您在唯一索引中使用多个列,并且这些列中至少有一个是强制性的(即必填字段),则如果将索引中的其他列设置为NULL,则可能会导致重复的行。这是因为NULL值在唯一列中被忽略。在这种情况下,请在唯一索引的其他列中使用空字符串,以避免重复的行。
COLUMNS IN A UNIQUE INDEX: (event_type_id, event_title, date, location, url) EXAMPLE 1: (1, 'BBQ', '2018-07-27', null, null) (1, 'BBQ', '2018-07-27', null, null) // allowed and duplicated. EXAMPLE 2: (1, 'BBQ', '2018-07-27', '', '') (1, 'BBQ', '2018-07-27', '', '') // NOT allowed as it's duplicated.
以下是一些代码:
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', '', '');
因此,这里没有对与错。由您决定哪种方法最适合您的业务规则。