我在一个网站上有一个表格,里面有很多不同的领域。有些字段是可选的,有些是必选的。在我的DB中,我有一个表,其中包含所有这些值,是更好的实践插入一个NULL值或一个空字符串到用户没有放任何数据的DB列?
当前回答
我不知道这里的最佳实践是什么,但我通常倾向于使用null,除非您希望null表示与空字符串不同的东西,并且用户的输入与您的空字符串定义相匹配。
请注意,我是说您需要定义您希望它们如何不同。有时让它们不同有意义,有时没有意义。如果没有,那就选一个,然后坚持下去。就像我说的,大多数时候我倾向于使用NULL。
哦,请记住,如果列为空,那么实际上任何基于该列进行选择(在SQL术语中有where子句)的查询中都不太可能出现该记录,当然,除非选择为空列。
其他回答
如果你打算切换数据库,有一件事需要考虑,那就是Oracle不支持空字符串。它们会自动转换为NULL,你不能使用WHERE somefield = "这样的子句来查询它们。
我不知道这里的最佳实践是什么,但我通常倾向于使用null,除非您希望null表示与空字符串不同的东西,并且用户的输入与您的空字符串定义相匹配。
请注意,我是说您需要定义您希望它们如何不同。有时让它们不同有意义,有时没有意义。如果没有,那就选一个,然后坚持下去。就像我说的,大多数时候我倾向于使用NULL。
哦,请记住,如果列为空,那么实际上任何基于该列进行选择(在SQL术语中有where子句)的查询中都不太可能出现该记录,当然,除非选择为空列。
通过使用NULL,你可以区分“不放数据”和“放空数据”。
还有一些不同之处:
NULL的LENGTH为NULL,空字符串的LENGTH为0。 null在空字符串之前排序。 COUNT(message)将计算空字符串,但不计算null 您可以使用绑定变量搜索空字符串,但不能搜索NULL。这个查询: SELECT * 从mytable WHERE mytext = ? 将永远不会匹配mytext中的NULL,无论你从客户端传递什么值。要匹配null,你必须使用其他查询: SELECT * 从mytable 哪里mytext是空的
要记住的一件事是,NULL可能会使您的代码路径更加困难。例如,在Python中,大多数数据库适配器/ orm将NULL映射为None。
比如:
print "Hello, %(title)s %(firstname) %(lastname)!" % databaserow
可能会出现“你好,没有无名氏!”为了避免这种情况,你需要这样的代码:
if databaserow.title:
print "Hello, %(title)s %(firstname) %(lastname)!" % databaserow
else:
print "Hello, %(firstname) %(lastname)!" % databaserow
这会让事情变得更加复杂。
如果你在一个唯一的索引中使用多个列,并且这些列中至少有一个是强制的(即一个必需的表单字段),如果你将索引中的其他列设置为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', '', '');
所以,这里没有对错之分。这取决于您决定什么最适合您的业务规则。
推荐文章
- 比较两个SQL Server数据库(模式和数据)的最佳工具是什么?
- 在SQL中,如何在范围中“分组”?
- 选项(RECOMPILE)总是更快;为什么?
- 设置数据库从单用户模式到多用户
- oracle中的RANK()和DENSE_RANK()函数有什么区别?
- 警告用户/local/mysql/data目录不属于mysql用户
- 的类型不能用作索引中的键列
- SQL逻辑运算符优先级:And和Or
- 如何检查一个表是否存在于给定的模式中
- 添加一个复合主键
- 如何在SQL Server Management Studio中查看查询历史
- 无法添加或更新子行:外键约束失败
- 如何从本地机器mysqldump远程数据库
- 可以为公共表表达式创建嵌套WITH子句吗?
- 什么时候我需要在Oracle SQL中使用分号vs斜杠?