我意识到,如果我的所有值都是固定宽度的,建议使用CHAR。但是,那又怎样?为了安全起见,为什么不为所有文本字段选择VARCHAR呢?
当前回答
早期性能优化和使用最佳实践类型的规则之间存在差异。如果创建的新表中总是有固定长度的字段,那么使用CHAR是有意义的,在这种情况下应该使用它。这不是早期优化,而是实现经验法则(或最佳实践)。
即-如果你有一个2字母的状态字段,使用CHAR(2)。如果您有一个包含实际州名的字段,请使用VARCHAR。
其他回答
我会选择varchar,除非列存储固定的值,如美国州代码-这总是2个字符长,有效的美国州代码列表不经常改变:)。
在其他情况下,甚至像存储哈希密码(固定长度),我会选择varchar。
为什么——char类型的列总是用空格填充,这使得列my_column定义为char(5),值为'ABC'在比较中:
my_column = 'ABC' -- my_column stores 'ABC ' value which is different then 'ABC'
假的。
这个特性可能会在开发过程中导致许多恼人的bug,并使测试更加困难。
如果字段中的所有数据值长度相同,则CHAR占用的存储空间比VARCHAR少。现在,在2009年,800GB的数据库与810GB的数据库(如果您将varchar转换为CHARs)在所有用途和目的上是一样的,但对于短字符串(1或2个字符),CHAR仍然是行业的“最佳实践”。
现在,如果您查看大多数数据库提供的各种各样的数据类型,即使是整数(bit、tiny、int、bigint),也有理由选择其中一种。每次都简单地选择bigint实际上是对字段的目的和用途有点无知。如果一个字段只是以年为单位表示一个人的年龄,那么使用bigint就太夸张了。现在它不一定是“错误的”,但它不是有效的。
但这是一个有趣的争论,随着数据库的改进,可以说CHAR vs VARCHAR的相关性越来越小。
我永远不会使用字符。我和很多人都有过这样的争论,他们总是提出令人厌倦的cliché char更快。我说,快多少?我们在这里讨论的是什么,毫秒,秒,如果是的话,是多少?你是在告诉我,因为有人声称它快了几毫秒,我们就应该在系统中引入大量难以修复的bug ?
这里有一些你会遇到的问题:
每个字段都将被填充,因此您最终得到的代码将永远到处都是RTRIMS。对于较长的字段来说,这也是一种巨大的磁盘空间浪费。
现在假设你有一个典型的例子,一个只有一个字符的char字段,但是这个字段是可选的。如果有人传递一个空字符串到这个字段,它就变成了一个空格。因此,当另一个应用程序/进程查询它时,如果不使用rtrim,它们将得到一个单独的空间。我们有xml文档,文件和其他程序,只显示一个空格,在可选字段和打破东西。
现在你要确保传递给char字段的是空值而不是空字符串。但这不是null的正确用法。这里是null的用法。假设您从供应商那里获得了一个文件
城市名字性别| |
鲍勃| |洛杉矶
如果没有指定性别,则在表中输入Bob、空字符串和Los Angeles。现在让我们假设你得到了文件,它的格式改变了,性别不再包括在内,而是在过去。
城市名称|
鲍勃|西雅图
好吧,现在由于性别不包括在内,我将使用null。Varchars毫无问题地支持这一点。
而夏尔则不同。你总是要发送null。如果你发送空字符串,你将得到一个包含空格的字段。
我可以继续在大约20年的开发过程中修复所有的错误。
我支持吉姆·麦基思的评论。
此外,如果您的表只有CHAR列,那么索引和全表扫描会更快。基本上,优化器将能够预测每条记录有多大,如果它只有CHAR列,而它需要检查每个VARCHAR列的大小值。
此外,如果您将VARCHAR列更新到比其先前内容更大的大小,则可能会强制数据库重新构建其索引(因为您强制数据库将记录物理地移动到磁盘上)。而对于CHAR列,这种情况永远不会发生。
但是,除非表很大,否则您可能不会关心性能受到的影响。
记住吉布拉的至理名言。早期的性能优化是万恶之源。
There are performance benefits, but here is one that has not been mentioned: row migration. With char, you reserve the entire space in advance.So let's says you have a char(1000), and you store 10 characters, you will use up all 1000 charaters of space. In a varchar2(1000), you will only use 10 characters. The problem comes when you modify the data. Let's say you update the column to now contain 900 characters. It is possible that the space to expand the varchar is not available in the current block. In that case, the DB engine must migrate the row to another block, and make a pointer in the original block to the new row in the new block. To read this data, the DB engine will now have to read 2 blocks. No one can equivocally say that varchar or char are better. There is a space for time tradeoff, and consideration of whether the data will be updated, especially if there is a good chance that it will grow.
推荐文章
- 如何在Ruby On Rails中使用NuoDB手动执行SQL命令
- 查询JSON类型内的数组元素
- 确定记录是否存在的最快方法
- 获得PostgreSQL数据库中当前连接数的正确查询
- 在SQL选择语句Order By 1的目的是什么?
- 我如何循环通过一组记录在SQL Server?
- 如何在SQL Server中一次更改多个列
- 如何从命令行通过mysql运行一个查询?
- 外键约束可能导致循环或多条级联路径?
- 使用LIMIT/OFFSET运行查询,还可以获得总行数
- 当恢复sql时,psql无效命令\N
- 货币应该使用哪种数据类型?
- 如何选择每一行的列值不是独特的
- 如何改变字符集(和排序)在整个数据库?
- mySQL:: insert到表,数据从另一个表?