键盘敲烂,月薪过万作业不做,等于没学
当前系列: 垃圾桶 修改讲义

为了快速的找到某一行数据,我们通常为每一行设置一个“编号”,编号(又称之为Id)好比学号身份证号证书编号,应该是唯一的、不能重复的。

设置编号这个工作机械琐碎而且易错(error-prone),不如委托给SQL Server!、

实际上,我们总是推荐使用SQL Server自动生成的值做(逻辑)编号,哪怕表中有可以区分行数据的(实体)编号(比如身份证号)。这样可以:

  • 确保Id不会因为用户输入重复或错误
  • 让系统更有弹性(flexible),比如方便以后更改(详见:外键)

自动编号通常被设置为主键。

T-SQL为我们提供了两种自动编号:


NEWID()

使用NewId()可以生成GUID(Global Unique Id),它是根据当前时间和网卡的MAC地址、由SQL Server自动生成的一个绝对不会重复的字符串。

我们需要将其设置为VARCHAR类型,然后在插入数据时直接使用,如下所示:

CREATE TABLE GUIDSample(Id VARCHAR(50) ) 
INSERT GUIDSample VALUES(NEWID())


IDENTITY自增列

自增列的类型必须是整数。

这样,才能每插入一条新数据,就在上一条数据编号的基础上自增(通常是加1)作为新数据的编号。

CREATE TABLE Student( 
	Id INT IDENTITY --只能是整数类型 
)

在INSERT插入数据的时候,自增列不能再由开发人员赋值。所以我们在使用INSERT语句的时候,这样是不行的:

-- 试图把Id设成20
INSERT INTO Student(Id, [Name]) VALUES (20, N'于维谦') 

只能写成这样:

-- Id由数据库自动生成
INSERT INTO Student([Name]) VALUES (N'于维谦') 




可以检查数据库:

23由SQL Server自动生成。

一个表中只能有一个IDENTITY列。

演示:插入数据后自增列的变化

注意:IDENTITY列的值可以不连续,因为:

  • 即使没有成功插入,IDENTITY值也会增加

  • Id一旦生成,不能更改;即:删除一条数据,IDENTITY不会被“压缩”

  • SQL Server为保证IDENTITY不重复,会在某些情况(如session中断)自动大幅增加IDENTITY值

  • ……


指定起始值和步增

IDENTITY默认从1(起始值)开始,每次+1(步增)。

但也可以修改,比如IDENTITY(10,3),意思是从10开始,每次增加3。

演示:略

什么时候需要设置IDENTITY(10,3)呢?

通常当我们使用数据库集群(可简单理解为同一张表分别放在多个数据库中)的时候,为了保证所有数据库里的表的ID都不会重复。

比如3台数据库A,B,C,如果设置成默认的IDENTITY,就必然出现冲突:

  • A数据库上表的ID是1,2,3,4...

  • B数据库上表的ID还是1,2,3,...

  • C数据库上表的ID也是1,2,3,4,5...

用SELECT * FROM T WHERE Id = 3 会取出3行数据出来,完全不对劲!

所以我们就这样设置他们某表上的ID列:

  • A:IDENTITY(1,3),于是A数据库上的ID只能是1,4,7,10...

  • B:IDENTITY(2,3),于是B数据库上的ID只能是2,5,8...

  • C:IDENTITY(3,3),于是C数据库上的ID只能是3,6,9,12,15...

他们的ID是不是就永远不会重复了?


关闭IDENTITY

在某些特定情景,我们可能需要在插入数据时指定自增列数值。

这时候我们要先运行:

SET IDENTITY_INSERT Student ON;

关闭自增列的自动生成。

不要问我为什么是ON(开启),——勉强翻译成“可指定自增列值的插入”吧,(*/ω\*)

然后,这样的代码就是OK的

SET IDENTITY_INSERT Student ON 
INSERT INTO Student ([Id], [Name]) VALUES (100, N'fegei')
INSERT INTO Student ([Id], [Name]) VALUES (105, N'xiaoyu') 
SET IDENTITY_INSERT Student OFF

注意:

  • 这时候,INSERT时必须在表名(Student)后指明列名(Id)
  • 总是记得在完成你的“非常规”操作之后,使用SET IDENTITY_INSERT Student OFF还原

不能直接改变列的自增(IDENTITY)状态


如何选择

和GUID想比较,IDENTITY的:

  • 优势是:直观,性能更高(整数累加比生成一个GUID快太多)
  • 劣势是:要小心集群冲突,必须在INSERT之后(通过@@IDENTITY)才能得到新插入行的Id


作业

  1. 观察一起帮的“关键字”功能,新建Keyword表,要求带一个自增的主键Id,起始值为10,步长为5;并存入若干条数据
  2. 将User表中Id列修改为可存储GUID的类型,并存入若干条包含GUID值的数据
  3. Problem表已有Id列,如何给该列加上IDENTITY属性?【难/选】


学习笔记
源栈学历
大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 垃圾桶 中继续学习:

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码