我在一个有很多不同领域的网站上有一个表格 . 某些字段是可选字段,而某些字段是必填字段 . 在我的数据库中,我有一个包含所有这些值的表,是否更好的做法是将NULL值或空字符串插入到用户未放置任何数据的DB列中?
通过使用 NULL ,您可以区分"put no data"和"put empty data" .
NULL
更多的差异:
LENGTH 的 NULL 是 NULL ,空字符串的 LENGTH 是 0 .
LENGTH
0
NULL 在空字符串之前排序 .
COUNT(message) 将计算空字符串,但不计算 NULL s
COUNT(message)
您可以使用绑定变量搜索空字符串,但不能搜索 NULL . 这个查询:
SELECT * FROM mytable WHERE mytext = ?
永远不会匹配 mytext 中的 NULL ,无论您从客户端传递什么值 . 要匹配 NULL ,您必须使用其他查询:
mytext
SELECT * FROM mytable WHERE mytext IS NULL
如果您计划切换数据库,那么需要考虑的一件事是Oracle does not support empty strings . 它们会自动转换为NULL,您无法使用 WHERE somefield = '' 等子句查询它们 .
WHERE somefield = ''
要记住的一件事是NULL可能会使您的代码路径变得更加困难 . 例如,在Python中,大多数数据库适配器/ ORM将 NULL 映射到 None .
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
这可能会使事情变得更加复杂 .
最好在MySQL中插入 NULL 以保证数据库的一致性 . 外键可以存储为 NULL 但不能作为空字符串存储 .
在约束中,您将遇到空字符串的问题 . 您可能必须插入具有唯一空字符串的伪记录以满足外键约束 . 我猜是不好的做法 .
另见:Can a foreign key be NULL and/or duplicate?
我不知道这里有什么最佳实践,但我通常会支持null,除非你想要null表示与空字符串不同的东西,并且用户的输入与空字符串定义匹配 .
请注意,我说你需要定义你希望它们与众不同的方式 . 有时候让它们与众不同是有意义的,有时则不然 . 如果没有,只需选择一个并坚持下去 . 就像我说的那样,我倾向于大多数时候都喜欢NULL .
哦,请记住,如果列为null,则记录几乎不会出现在基于该列选择(在SQL术语中具有where子句)的任何查询中,除非选择用于空列当然 .
如果在唯一索引中使用多个列,并且这些列中至少有一列是必需的(即必需的表单字段),如果将索引中的其他列设置为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', '', '');
所以,这里没有对错 . 由您决定什么最适合您的业务规则 .
6 回答
通过使用
NULL
,您可以区分"put no data"和"put empty data" .更多的差异:
LENGTH
的NULL
是NULL
,空字符串的LENGTH
是0
.NULL
在空字符串之前排序 .COUNT(message)
将计算空字符串,但不计算NULL
s您可以使用绑定变量搜索空字符串,但不能搜索
NULL
. 这个查询:永远不会匹配
mytext
中的NULL
,无论您从客户端传递什么值 . 要匹配NULL
,您必须使用其他查询:如果您计划切换数据库,那么需要考虑的一件事是Oracle does not support empty strings . 它们会自动转换为NULL,您无法使用
WHERE somefield = ''
等子句查询它们 .要记住的一件事是NULL可能会使您的代码路径变得更加困难 . 例如,在Python中,大多数数据库适配器/ ORM将
NULL
映射到None
.所以像:
可能导致“你好,没有Joe Doe!”要避免它,你需要像这样的代码:
这可能会使事情变得更加复杂 .
最好在MySQL中插入
NULL
以保证数据库的一致性 . 外键可以存储为NULL
但不能作为空字符串存储 .在约束中,您将遇到空字符串的问题 . 您可能必须插入具有唯一空字符串的伪记录以满足外键约束 . 我猜是不好的做法 .
另见:Can a foreign key be NULL and/or duplicate?
我不知道这里有什么最佳实践,但我通常会支持null,除非你想要null表示与空字符串不同的东西,并且用户的输入与空字符串定义匹配 .
请注意,我说你需要定义你希望它们与众不同的方式 . 有时候让它们与众不同是有意义的,有时则不然 . 如果没有,只需选择一个并坚持下去 . 就像我说的那样,我倾向于大多数时候都喜欢NULL .
哦,请记住,如果列为null,则记录几乎不会出现在基于该列选择(在SQL术语中具有where子句)的任何查询中,除非选择用于空列当然 .
如果在唯一索引中使用多个列,并且这些列中至少有一列是必需的(即必需的表单字段),如果将索引中的其他列设置为NULL,则最终可能会出现重复的行 . 那是因为在唯一列中忽略NULL值 . 在这种情况下,请在唯一索引的其他列中使用空字符串以避免重复行 .
以下是一些代码:
现在插入它以查看它将允许重复的行:
现在插入此内容并检查是否允许:
所以,这里没有对错 . 由您决定什么最适合您的业务规则 .