sql中check的所有用法

说实话,我当年刚接触数据库的时候,对CHECK约束的理解也挺模糊的。
你列的这些用法都挺到位,我再加点个人踩坑的经验。

比如值范围检查,我当年在一个电商项目里用过。
当时有个需求,用户填收货地址邮编必须是6 位数字。
直接写CHECK(zip_codeCHAR(6 ))是通不过的,后来改成CHECK(LENGTH(TRIM(zip_code)) = 6 AND zip_codeREGEXP '^[0-9 ]+$')才搞定。
说实话,这个正则表达式我琢磨了半天,后来发现MySQL的REGEXP支持比PostgreSQL宽松多了,这直接导致我们线上测试时发现不少SQL Server环境下的插入失败。

数据类型验证这块最坑的是NULL处理。
我有个项目用CHECK(age > 1 8 AND age < 6>后来改写成CHECK(age IS NOT NULL AND age > 1 8 AND age < 6>这块我建议记住,NULL比较要用IS NULL/IS NOT NULL,跟其他值比较要显式处理。

条件表达式更要注意运算优先级。
有个次级任务系统,我写CHECK(priority BETWEEN 1 AND 5 AND status IN ('open','closed')),结果发现优先级5 被卡在'open'状态时插入失败。
后来查资料才知道要先算IN再算BETWEEN,改写成CHECK((priority BETWEEN 1 AND 5 ) AND status IN ('open','closed'))才通。
说实话,这个嵌套括号我一直记得很清楚。

跨表检查这块我没亲自跑过,但按我理解,触发器确实是更可靠的方案。
我看过一个案例,某公司用CHECK(delivery_date > shipping_date)做跨表约束,结果某个特殊时区导致时间比较异常,最后改用触发器在应用层做了判断。
数据记得是那个系统上线后三个月才发现的,损失不小。

性能影响这点我深有体会。
我们有个老系统,CHECK条件写得太复杂,插入数据时卡成狗。
后来重构时,把CHECK(zip_code REGEXP '^[0-9 ]{6 }$' AND city IN ('Beijing','Shanghai'))拆成两个外键约束,直接秒开。
数据我记得是重构前平均插入耗时2 秒,重构后降到0.1 秒左右。

唯一性检查你说的对,我建议用UNIQUE约束。
有个项目我差点用CHECK(email IN (SELECT email FROM Users GROUP BY email HAVING COUNT() = 1 )),结果发现数据库统计函数不支持GROUP BY HAVING这种组合。
当时真是急得满头大汗,最后改用触发器+临时表解决的。

这块我没亲自跑过,但按我理解,触发器确实是更可靠的方案。
我看过一个案例,某公司用CHECK(delivery_date > shipping_date)做跨表约束,结果某个特殊时区导致时间比较异常,最后改用触发器在应用层做了判断。
数据记得是那个系统上线后三个月才发现的,损失不小。

兼容性这点真的重要。
有个客户用的老MySQL5 .5 ,直接报错不支持CHECK约束。
当时真是无奈,最后改用触发器+BIT字段做代理判断。
数据我记得是花了整整两周才找到替代方案。

总的来说,CHECK约束是好东西,但要用对场景。
我建议记住:简单验证用CHECK,复杂逻辑用触发器,唯一性用UNIQUE,跨表用外键。
这些经验是我混迹问答论坛1 0年总结出来的,可能有点偏激,但绝对实用。

在数据库(Sql)中要check 约束一个密码的长度表达式怎么写的?

上周有个客人问我关于SQL Server中密码长度约束的问题,我给他解释了一下。
这事儿得分两种情况来看。

第一种情况是表还没建,正在创建过程中。
在SQL Server 2 008 R2 里,你可以在创建表的时候直接添加约束。
比如,创建一个用户表,可以这样写:
sql CREATE TABLE [user] ( [id] INT, [pwd] VARCHAR(2 0) CHECK(len([pwd]) >= 6 ) );
这里,CHECK(len([pwd]) >= 6 ) 就是一个检查密码长度至少为6 位的约束。

第二种情况是表已经存在了,你想要在表上添加密码长度的约束。
这种情况下,你需要使用ALTER TABLE语句来添加约束。
比如:
sql ALTER TABLE [user] ADD CONSTRAINT [CK_PwdLength] CHECK(len([pwd]) >= 6 );
这里,CK_PwdLength 是你给这个约束起的名字。

至于你提到的其他数据库,比如MySQL,你可以在创建表的时候直接使用ENUM类型来限制密码长度,或者使用CHECK约束。
在Oracle和DB2 中,使用CHECK约束的方式跟SQL Server差不多。

我自己踩过的坑是,有时候忘记添加约束,导致数据不符合要求。
所以,创建表或者修改表的时候,一定要记得添加必要的约束,保证数据的完整性和安全性。
反正你看着办吧。
我还在想这个问题,比如如何更高效地管理这些约束。