大家好,我是刚子。 image

一个写了六年代码、踩过无数数据库坑的.NET程序员。今天不整那些虚的,就想跟你唠唠SQL Server里那些让人头大的数据类型。

说实话,我刚入行那会儿,看见varchar和nvarchar也是一脸懵,心想“能存进去不就行了?”结果线上出过乱码,表空间爆过,甚至还因为float存钱对不上账,被财务小姐姐追着骂了一下午……

所以今天这几个坑,我是真心想跟你聊聊。文章不长,但保证看完能少走弯路。

1. char(3) 和 varchar(3):铁盒子 vs 塑料袋

这俩的区别,你就想成装东西的容器。

char(3) 像个铁盒子,大小固定。你往里放“AB”,它也要占满3个位置,后面给你补个空格。放“ABC”,刚好塞满。不管放多放少,它都占3个位置。

varchar(3) 像个塑料袋,最大能装3个,但你只放“AB”的时候,它就缩成2个的大小,绝不浪费。

所以怎么选?

存那种长度基本固定的(比如性别、手机号区号),用char,读取快一丢丢。

存那种长短不一的(比如地址、昵称、备注),用varchar,省空间,别跟磁盘过不去。

2. varchar(20) 和 nvarchar(20):英文袋 vs 国际袋

这组最坑人,也是我当年被骂得最惨的一次。

varchar 是“英文专用袋”。一个英文字母占1个格子,所以varchar(20)能装20个字母。但中文呢?一个字要占2个格子,所以只能装10个汉字。更难受的是,如果你没设置好编码,汉字直接变乱码,你都不知道用户当初写的啥。

nvarchar 是“国际通用袋”。不管英文、中文、日文,每个字符都占2个格子,统一对待。nvarchar(20)就是铁了心能装20个字符,无论什么语言。

所以怎么选?

如果你的系统百分百确定只存英文数字(比如老外的纯英文软件),用varchar省点空间。

但凡有一丝丝可能存中文、表情、多语言,直接上nvarchar,别犹豫。咱们写.NET的,C#里的string就是Unicode,对应到SQL Server就是nvarchar,用这个最省心。

3. float 和 decimal:马大哈 vs 会计

这组没啥好纠结的,一句话说透:

float 是个“马大哈”。科学计算挺在行,但它存的是近似值。你让它算0.1+0.2,它敢给你算出0.30000000000000004。你要拿它存钱,月底对账的时候财务能把你吃了。

decimal 是“会计”。每一分钱都给你算得清清楚楚,精确到你指定的小数位数。比如decimal(18,2),总共有18位数字,小数点后面保留2位,绝不会多出一分钱的零头。

所以怎么选?

做物理、地理、图表那种“差不多就行”的计算,用float没问题。

只要是钱、单价、库存、任何跟账目相关的,打死也得用decimal。这是原则问题,别问我怎么知道的。

4. 顺便说一句 default 是啥

有人问我“float和default有啥区别”,这俩根本不是一码事。

float是数据类型,default是默认值约束。比如你建表时加一列CreateTime datetime default getdate(),意思就是“如果你不填,我就自动给你填上当前时间”。它不跟任何数据类型PK,只是帮你偷个懒而已。

给.NET兄弟的一张对照表

最后,作为.NET程序员,我习惯把SQL Server类型和C#类型对应起来,这样用EF或者手写SQL时心里有数: