
1. 为什么SQL Server数据类型这么容易踩坑我刚入行那会儿最常被前辈骂的就是你这字段类型怎么选的。SQL Server的数据类型看似简单但实际用起来处处是雷。先说几个真实案例去年我们团队有个报表系统突然崩溃排查发现是有人用varchar(50)存了身份证号。看起来没问题对吧直到某天业务部门要求支持港澳台身份证那些18位的号码直接截断系统直接崩了。更惨的是等我们发现时已经有上千条数据被损坏。另一个经典案例是财务系统的金额字段。新人用float存金额结果季度报表对不上账差了几毛钱。财务总监直接冲到技术部拍桌子——你猜最后怎么着是因为float的精度问题导致0.10.2≠0.3这种基础问题。这些坑我都亲自踩过所以今天要跟你聊的不是教科书式的数据类型列表而是实战中那些容易忽略的细节。我会重点讲5个最要命的陷阱以及对应的避坑方案。2. 字符串类型你以为的varchar并不是你以为的2.1 varchar vs nvarchar字符编码的生死抉择先说结论在中文环境下99%的情况你应该用nvarchar。为什么来看这个实验CREATE TABLE TestChars ( regular_col VARCHAR(100), unicode_col NVARCHAR(100) ); INSERT INTO TestChars VALUES (你好世界, N你好世界);执行后你会发现varchar列存储的中文变成了乱码。这是因为varchar按字节存储每个中文字符占2-3字节而nvarchar按字符存储每个字符固定2字节。关键经验只要涉及多语言或特殊字符无脑用nvarchar。虽然会占用更多空间但比起数据损坏的代价这点存储成本微不足道。2.2 长度陷阱为什么你的字段总是不够用我见过太多这样的设计CREATE TABLE Users ( username VARCHAR(20), email VARCHAR(50) );看起来合理等业务说要支持企业邮箱时那些超长的公司邮箱地址直接GG。我的经验法则是用户名/昵称最少nvarchar(64)邮箱最少nvarchar(256)地址最少nvarchar(512)备注/描述直接nvarchar(MAX)记住现代存储很便宜但数据截断的修复成本极高。特别要注意的是SQL Server的varchar(MAX)和nvarchar(MAX)其实性能并不差不要被MAX吓到。3. 数字类型精度问题能让你加班到天亮3.1 永远不要用float/real存金额这是我见过最贵的错误之一。来看这个惊悚的例子DECLARE a FLOAT 0.1, b FLOAT 0.2; IF a b 0.3 PRINT 相等 ELSE PRINT 不相等; -- 这里会输出不相等解决方案很简单金额用decimal(19,4) —— 足够存万亿级别的金额精确到分百分比用decimal(5,2) —— 范围0-999.99%数量根据业务需求选int或bigint3.2 自增ID的坑int真的够用吗很多表这样设计CREATE TABLE Orders ( OrderID INT IDENTITY(1,1), -- 其他字段 );等业务跑几年后OrderID突破21亿时整个系统直接崩掉。我的建议是高频增长的表直接用bigint数据量小的表可以用int但要定期监控ID增长情况4. 日期时间类型时区问题能让你怀疑人生4.1 datetime vs datetime2精度与范围的权衡老系统常用datetime但它有几个致命缺陷精度只有3.33毫秒范围只有1753-9999年没错1753年之前的日期存不了存储要8字节而datetime2精度可达100纳秒范围0001-9999年存储6-8字节根据精度调整所以现代开发应该优先用datetime2。示例CREATE TABLE Events ( EventTime DATETIME2(7) -- 7表示纳秒精度 );4.2 时区陷阱你的时间不是我的时间最坑的是跨时区系统。假设你在北京时间2023-08-01 08:00:00存了条数据美国用户查出来显示什么取决于你用的是什么类型datetime不带时区信息直接按服务器时区显示datetimeoffset包含时区信息会自动转换解决方案CREATE TABLE GlobalEvents ( EventTime DATETIMEOFFSET -- 会存储时区信息 );插入时INSERT INTO GlobalEvents VALUES (2023-08-01T08:00:0008:00);这样查询时会自动按客户端时区转换显示。5. 二进制与特殊类型这些坑你可能还没遇到5.1 文件存储varbinary(MAX)的替代方案很多人喜欢把文件直接存数据库CREATE TABLE Documents ( Content VARBINARY(MAX) );这会导致数据库膨胀。更好的方案是小文件256KB可以存varbinary大文件存文件路径文件放专用存储5.2 XML和JSON现代SQL Server的新选择SQL Server 2016原生支持JSONCREATE TABLE Products ( Attributes NVARCHAR(MAX) CHECK (ISJSON(Attributes)1) -- 确保是合法JSON );查询时可以用JSON函数SELECT ProductID, JSON_VALUE(Attributes, $.color) AS Color FROM Products比以前用字符串自己拼JSON方便多了。6. 数据类型选择速查表最后送大家一张我整理的决策表数据场景推荐类型替代方案禁忌中文文本nvarchar(XX)nvarchar(MAX)varchar金额/财务decimal(19,4)moneyfloat/real自增IDbigintintsmallint精确时间datetime2(7)datetimeoffsetdatetime布尔值bittinyintvarchar(5)存true枚举值tinyint 约束nvarchar(20)直接用varchar无约束文件内容varbinary(MAX)文件路径text/ntext复杂结构JSON(nvarchar)XML自己拼字符串这张表是我用五年时间、踩过无数坑总结出来的。贴在你工位上下次设计表时先看一眼至少能避开80%的坑。