如果不接受在数字列中插入非数字值,SQLite会有用吗?


10

在SQLite中,以下语句将成功执行,并将字符串插入/更新到SALARY类型为的列中INTEGER

update employee set salary='TOO MUCH' where emp_id=1;

请注意,不会插入/更新零,而是实际的“ TOO MUCH”字符串,因此这与认证类型转换无关。

常见问题解答指出:

这是一个功能,而不是错误。SQLite使用动态类型。它不强制执行数据类型约束。任何类型的数据(通常)都可以插入任何列中。您可以将任意长度的字符串放入整数列,布尔列中的浮点数或字符列中的日期。您在CREATE TABLE命令中分配给列的数据类型不限制可以在该列中放入哪些数据。每列都可以容纳任意长度的字符串。(有一个例外:INTEGER PRIMARY KEY类型的列只能包含一个64位有符号整数。如果尝试将一个整数以外的任何内容放入INTEGER PRIMARY KEY列,则会导致错误。)

因此,这种行为显然是故意的,但是我想知道为什么 SQLite会有这种行为,因为我所知道的大多数其他SQL数据库的行为都大不相同,因此,当尝试将非数字字符串插入到数据库中时,它们将引发错误或将字符串转换为0一个数字列。

  • 如果没有这种行为,SQLite库会不会有用呢?

  • 这是设计使图书馆小而又快吗?

  • 尝试在数字列中插入字符串时,SQLite库会明显变慢还是变大,以引起错误?


9
曾经有人说“功能是市场部门描述的错误”。
Dan Pichelman 2015年

3
我怀疑它对性能和数据密度是否有利,尽管它可能对代码大小有利。总而言之,我将其称为故意的(或至少被采纳的)错误功能。
Deduplicator

3
“在我看来,为了保留通常用于需要实时性能的嵌入式系统的小型,低资源库,施加了一定的限制。”我无法想象类型检查无非是一个下降。做任何数量的磁盘IO的操作的时间/空间性能存储区。此外,他们还必须在代码中进行其他检查,因为他们不能简单地假设数据将具有固定大小,因此可以说动态类型会降低性能。
2015年

1
@DocBrown不是因为我这么说,而是因为它很特殊
图兰斯·科尔多瓦

2
@ user61852我建议您完全重写问题,并专注于SQLite的动态类型是否会给它带来性能上的好处,并忽略X或Y上下文中动态类型的功能/错误区别或一般用途/无用之处。
2015年

Answers:


8

不,动态类型化需要更多的存储空间和更多的处理时间,特别是因为它们还增加了类型相似性,这意味着它具有程序员可以自由忽略的首选类型。这是真正具有故意权衡成本的故意功能。对于使用SQLite目标的用例,这些成本实际上可以忽略不计,但仍然存在。

很难看到这些功能的用处,因为您不习惯将其提供给您。缺少它的解决方法现在对您来说更加自然。由于您以前的经验,您将其视为一个INTEGER字段,该字段永远不会成为其他字段,但是SQLite会将其更多地视为任何类型的字段,但可能大多数将包含整数。也许这是一家主要在美国开展业务但有少数加拿大客户的公司的邮政编码。允许用户指定整数亲和力将为每行设置一个字符串节省很多空间,但仍然为您提供该选项。


3
我编写了有关将字符串“ TOO MUCH”成功存储到数字列中的问题的更新。自动转换将插入零。这也是我所知道的第一个关系数据库实现。我曾经使用过MSSQLServer,Oracle,PostgreSQL,MySQL,MS Acces,DBase,Foxbase,COBOL和Sybase SQL Anywhere。
图兰斯·科尔多瓦

2
我不明白你的评论。我的答案与自动转换无关。
Karl Bielefeldt 2015年

1
SQLite认为它们是存储类,而不是数据类型。sqlite.org/datatype3.html
JeffO 2015年

1
Upvoted对于被写得清清楚楚,但你忽视的问题,在这个原因证明数据的准确性。 您不能从数据库中提取一些整数并假设它们将是整数。(“动态类型”是疯狂地在与赔率的实际关系模型本身。)
通配符

1
完全忽略打字的成本远远高于很少的存储空间和处理器时间。
DeadMG '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.