Sql server SQL Server:标识约束的缺点

Sql server SQL Server:标识约束的缺点,sql-server,constraints,identity,Sql Server,Constraints,Identity,我想谈谈SQL Server中IDENTITY约束的缺点。在我看来,这是有帮助的,但可能会导致外键异常 例如: create table letters ( ID int identity, letter varchar(1) ) 现在我将创建两个字母: insert into letters (letter) values ('a'); insert into letters (letter) values ('b'); 并创建每个字母的参考表格: create table

我想谈谈SQL Server中
IDENTITY
约束的缺点。在我看来,这是有帮助的,但可能会导致外键异常

例如:

create table letters
(
    ID int identity,
    letter varchar(1)
)
现在我将创建两个字母:

insert into letters (letter) values ('a');
insert into letters (letter) values ('b');
并创建每个字母的参考表格:

create table references
(
    ID int identity,
    ID_letter int references letters(ID),
    value int
)
我想提及“b”字母,以便我:

insert into references (ID_letter,value) values (2,100)
但现在,如果我删除“a”字母并在另一个数据库中插入“b”,我必须将该引用更改为1而不是2,因为“b”的ID现在是1


这就是为什么我宁愿使用name作为主键并引用name,而不是ID标识。但对于较长的瓦尔查(Varchar),例如城市,这并不是一件容易的事——写一个城市的ID而不是全名要容易得多。你的观点是什么?

我的观点是你误解了身份是什么。这也是一个广泛的话题

标识只是特定行的(唯一)编号。除非您这样做,否则它不会自动成为主键或其他键。
它也不是数据库范围的,而且绝对不是全球唯一的。除非你做错了什么,否则它不会以这种方式使用

标识通常用作主键,以避免生成多行的复合键,因为它使查找更容易,并减少了索引的大小。 即使它是一个键,也不必是表的聚集索引,而可以是非聚集索引。这是一条相关的路线,尽管仍然是另一条路线,所以我不会在那个方向走得太深

因此,标识永远不会导致外键异常。您对标识的使用可能会导致问题,但这取决于您试图做什么,而不是工具本身

如果您希望数据键在多个数据库中保持一致,那么可以使用某种类型的“系统键”。通常建立在数据本身或根据数据计算。 为此,您通常会使用UniqueIdentifier(GUID)、应用程序中生成的序列号,或者在字母表的情况下,字母it self是一个有效的比较键

当涉及到城市时,如果你确信拼写会得到处理,你可以使用这个名称,否则,你会根据你想要在一起交谈的两个系统之间的逻辑以及交换数据的方式,包括另一个标识符

此外,在跨数据库交谈时,主键并不自动意味着相同,两个数据库之间的引用甚至更不相同;即使数据很容易关联。因为这在很大程度上取决于数据的使用方式(这又让我们回到了索引的构建)


Identity只是数据库工具箱中的一个工具。如何使用它取决于您自己,但作为任何工具,它更适合于某些任务,而不是每项任务。

我不确定我是否理解这个问题,您是否试图将外键引用到一个完全不同的数据库?这本身不是
身份
的问题,这是自然与代理主键之间永恒的圣战。这两种方法都有优点和缺点,所以一切都取决于你的具体情况。@jakub,我认为你的问题实际上是关于代理的主要优点和缺点。这个问题太宽泛了。如果需要在两个位置创建键值,那么IDENTITY可能不是正确的方法。但是请注意,一个表可以有多个键。您可以使字母唯一(以及ID),并将字母用作外部引用的更合适的键。