SQL Server 中创建两个表的典型语法
CREATE TABLE tb_name( id int IDENTITY (1,1) NOT NULL, name varchar (50) COLLATE chinese_PRC_CI_AS NULL ) CREATE TABLE tb_user( id int NULL, name varchar(10) COLLATE Albanian_CI_AI_WS )
这段代码展示了在 SQL Server 中创建两个表的典型语法,里面包含了一些关键且容易混淆的参数。我们逐行拆解:
第一个表:tb_name
sql
CREATE TABLE tb_name( id int IDENTITY (1,1) NOT NULL, name varchar (50) COLLATE chinese_PRC_CI_AS NULL)
| 参数 | 含义 | 说明 |
|---|---|---|
IDENTITY (1,1) | 自动编号 | 第一个 1 是种子(起始值),第二个 1 是增量(每次加1)。插入数据时不需要指定 id,数据库会自动生成:1,2,3... |
NOT NULL | 不允许为空 | id 列必须有值(自动生成,所以没问题) |
varchar(50) | 可变长度字符串 | 最多存 50 个字符,中文英文都算 1 个字符 |
COLLATE chinese_PRC_CI_AS | 排序规则 | 告诉数据库如何比较和排序这列的数据 |
NULL | 允许为空 | name 列可以不填值 |
重点:COLLATE 排序规则解读
chinese_PRC_CI_AS 拆解:
| 缩写 | 全称 | 含义 |
|---|---|---|
chinese_PRC | 中国(中华人民共和国) | 针对简体中文的排序规则 |
CI | Case-Insensitive | 不区分大小写('A' = 'a') |
AS | Accent-Sensitive | 区分重音('é' ≠ 'e') |
效果:
sql
-- 在 CI 下,下面两个查询结果一样SELECT * FROM tb_name WHERE name = '张三';SELECT * FROM tb_name WHERE name = '张 san'; -- 不对,这个例子不好-- 更好的例子:'ABC' = 'abc' -- ✅ 相等(CI)'cafe' ≠ 'café' -- ✅ 不等(AS 区分重音)
第二个表:tb_user
sql
CREATE TABLE tb_user( id int NULL, name varchar(10) COLLATE Albanian_CI_AI_WS)
| 参数 | 含义 | 说明 |
|---|---|---|
id int NULL | 整数,可为空 | 没有 IDENTITY,需要手动插入 id 值 |
varchar(10) | 字符串,最多 10 个字符 | 比上面的 50 更短 |
COLLATE Albanian_CI_AI_WS | 阿尔巴尼亚语排序规则 | 针对阿尔巴尼亚语的规则 |
第二个排序规则解读
Albanian_CI_AI_WS 拆解:
| 缩写 | 全称 | 含义 |
|---|---|---|
Albanian | 阿尔巴尼亚语 | 按阿尔巴尼亚语的字母顺序排序 |
CI | Case-Insensitive | 不区分大小写 |
AI | Accent-Insensitive | 不区分重音('é' = 'e') |
WS | Width-Sensitive | 区分全角/半角('A' ≠ 'A',注意前者是全角) |
两个表的关键区别对比
| 对比项 | tb_name | tb_user |
|---|---|---|
| id 是否自动增长 | ✅ IDENTITY(1,1) | ❌ 无,需手动插入 |
| id 是否可为空 | ❌ NOT NULL | ✅ NULL |
| name 最大长度 | 50 字符 | 10 字符 |
| 排序规则 | 简体中文(区分重音) | 阿尔巴尼亚语(不区分重音,区分宽度) |
| name 是否可为空 | ✅ NULL(明确写了) | ⚠️ 未写(下面解释) |
重要细节:NULL 的默认行为
sql
-- tb_name 的 name 列name varchar(50) COLLATE chinese_PRC_CI_AS NULL -- 明确允许 NULL-- tb_user 的 name 列name varchar(10) COLLATE Albanian_CI_AI_WS -- 没写 NULL 也没写 NOT NULL
没写会怎样? 取决于数据库设置:
| 数据库设置 | 效果 |
|---|---|
| 默认(大多数) | 等同于 NULL(允许为空) |
设置了 ANSI_NULL_DFLT_ON | 等同于 NULL |
设置了 ANSI_NULL_DFLT_OFF | 等同于 NOT NULL |
最佳实践: 永远明确写 NULL 或 NOT NULL,不要省略。
实际使用示例
sql
-- 插入 tb_name(id 自动生成)INSERT INTO tb_name (name) VALUES ('张三'); -- id 自动变成 1INSERT INTO tb_name (name) VALUES ('李四'); -- id 自动变成 2-- 插入 tb_user(需要手动指定 id)INSERT INTO tb_user (id, name) VALUES (1, 'John');INSERT INTO tb_user (id, name) VALUES (2, 'Alice');-- 如果允许 NULL,可以这样INSERT INTO tb_user (id, name) VALUES (3, NULL);排序规则的实际影响
sql
-- 在 tb_name(chinese_PRC_CI_AS)中'中国' = '中国' -- ✅'ABC' = 'abc' -- ✅(CI 不区分大小写)'cafe' = 'café' -- ❌(AS 区分重音)-- 在 tb_user(Albanian_CI_AI_WS)中'cafe' = 'café' -- ✅(AI 不区分重音)'ABC' = 'abc' -- ✅(CI 不区分大小写)'A' = 'A' -- ❌(WS 区分全角半角)
总结
| 关注点 | 结论 |
|---|---|
IDENTITY(1,1) | 自动编号,从 1 开始每次 +1 |
COLLATE | 定义字符串的比较和排序规则 |
NULL/NOT NULL | 最好明确写出,不要省略 |
| 两个表的区别 | 一个自动 id + 中文规则,一个手动 id + 阿尔巴尼亚语规则 |
一句话:这两个表创建语句演示了 SQL Server 中自动编号、排序规则、空值约束的核心语法