Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL数据类型VARCHAR(1)有什么意义吗?_Sql_Sql Server 2005_Types - Fatal编程技术网

SQL数据类型VARCHAR(1)有什么意义吗?

SQL数据类型VARCHAR(1)有什么意义吗?,sql,sql-server-2005,types,Sql,Sql Server 2005,Types,在我最近不得不使用的数据库中,我碰到了很多VARCHAR(1)字段。我翻了翻眼睛:很明显,设计师对此一无所知。但也许我是那个需要学习的人。使用VARCHAR(1)数据类型而不是CHAR(1)是否有任何可能的原因?我认为RDM会自动将一个转换为另一个 数据库是MS SQL 2K5,但它是从当时的Access演变而来的。AFAIK,No VARCHAR(1)需要3个字节的存储(存储大小是输入的数据的实际长度+2个字节) 字符(1)需要1个字节 从存储的角度来看:经验法则是,如果小于或等于5字符,考虑

在我最近不得不使用的数据库中,我碰到了很多VARCHAR(1)字段。我翻了翻眼睛:很明显,设计师对此一无所知。但也许我是那个需要学习的人。使用VARCHAR(1)数据类型而不是CHAR(1)是否有任何可能的原因?我认为RDM会自动将一个转换为另一个

数据库是MS SQL 2K5,但它是从当时的Access演变而来的。

AFAIK,No

VARCHAR(1)
需要3个字节的存储(存储大小是输入的数据的实际长度+2个字节)

字符(1)需要1个字节

从存储的角度来看:经验法则是,如果小于或等于5字符,考虑使用固定长度的char列。


避免使用varchar(1)的一个原因(除了它们传达糟糕的设计推理之外,IMO)是在使用Linq2SQL时:

是的,这是有意义的

  • 在语言中更容易定义它。定义varchar以允许1-8000比说它需要2+或3+到8000更容易

  • VARCHAR(1)的可变字符方面正是如此。它可能不是存储的最佳选择,但传达了一个特定的含义,即数据要么是1字符(课堂代码),要么是空白(外部活动),而不是空(未知/尚未分类)

存储在其中所起的作用很小—查看CHAR(1)的数据库模式,您几乎可以预期它必须始终具有1个CHAR值,例如信用卡必须具有16位数字。对于某些数据而言,情况并非如此,因为它可以是一个,也可以是无

对于那些认为三态[1-CHAR | 0-CHAR | NULL]完全无用的人来说,使用VARCHAR(1)与CHAR(1)+NULL组合也有不同之处。它允许使用如下SQL语句:

select activity + '-' + classroom
from  ...
如果您使用char(1)+NULL,这将更加困难,因为它可以传递相同的信息,但有细微的差异。

A
varchar(1)
可以存储长度为零的(“空”)字符串。A
char(1)
不能,因为它将被填充到单个空间。如果这种区别对您很重要,您可以选择
varchar

除此之外,如果设计者希望考虑到将来可能需要更多字符的可能性,则可以使用这种情况

将固定长度的数据类型从
char(1)
更改为
char(2)
意味着需要更新所有表行,并首先删除访问此列的任何索引或约束

在生产中对大型表进行这些更改可能是一项非常耗时的操作,需要停机时间

将列从
varchar(1)
更改为
varchar(2)
容易得多,因为这是一个仅元数据的更改(引用该列的FK约束需要删除并重新创建,但无需重建索引或更新数据页)

此外,每行2字节的保存可能不会始终实现。如果行定义已经很长,这不会始终影响数据页上可以容纳的行数。另一种情况是,如果在Enterprise Edition中使用压缩功能,则数据的存储方式与Mitch中提到的完全不同无论如何都要回答。
varchar(1)
char(1)
最终将以相同的方式存储在短数据区域中

@托马斯-例如,试试这个表格定义

CREATE TABLE T2
(
Code VARCHAR(1),
Foo datetime2,
Bar int,
Filler CHAR(4000),
PRIMARY KEY CLUSTERED (Code, Foo, Bar)
)

INSERT INTO T2
SELECT TOP 100000 'A', 
                  GETDATE(), 
                  ROW_NUMBER() OVER (ORDER BY (SELECT 0)),
                  NULL
FROM master..spt_values v1,  master..spt_values v2

CREATE NONCLUSTERED INDEX IX_T2_Foo ON T2(Foo) INCLUDE (Filler);
CREATE NONCLUSTERED INDEX IX_T2_Bar ON T2(Bar) INCLUDE (Filler);
对于
varchar
来说,将列定义从
varchar(1)
更改为
varchar(2)
是很简单的。这只是元数据更改

ALTER TABLE T2 ALTER COLUMN Code VARCHAR(2) NOT NULL
如果更改从
char(1)
更改为
char(2)
,则必须执行以下步骤

  • 从表中删除PK。这会将表转换为堆,意味着所有非聚集索引都需要使用RID而不是聚集索引键进行更新
  • 更改列定义。这意味着表中的所有行都将更新,以便
    code
    现在存储为
    char(2)
  • 重新添加聚集PK约束。以及重建CI本身,这意味着所有非聚集索引都需要使用CI键作为行指针而不是RID再次更新

  • 我可以看出,实现禁止VARCHAR(1)并没有真正的理由,但我想问的是,是否会有任何设计上的好处。关于第二点,我想澄清一下,您指出VARCHAR(1)可以是空字符串,但CHAR(1)不能?我可以看到;选择VARCHAR(1)而不是CHAR(1)的一个模糊的原因,但可以想象这是一个有效的字符。“•更容易在语言中定义。”-你能用elborate吗?好吧,从Oracle的角度来看,Tom Kite不同意!我永远不会使用varchar(1)。Char(1)对我来说意味着一列将包含1个字符,并且正好包含一个字符。我会质疑具有varchar(1)或Char(1)的架构设计可以为空。@Mitch-对于每一个专业人士,都有不同的人可能不同意。这不是针对个人的,但就好像我不同意你所说的一切,仅仅因为你是微软MVP。还有其他微软MVP在不同的主题上持有不同的观点。
    没有人
    是对的
    所有人
    时间。数据是e1个字符(课堂代码)或空白(外部活动)。假设“空白”不是指null,这种对正意味着使用长度为零的字符串,这是它自己可疑的设计选择,也会违反最不令人惊讶的规则。使用带有null的
    合并
    和长度大于零的值更明确、更灵活。这不是一个好的经验法则。固定长度的问题4与varchar(4)的比较是
    char(4)+'-x'
    有不需要的空格。是的,您可以修剪,但这增加了不需要简单使用varchar(4)的复杂性。@Mi