Questions tagged «identity»

在表中创建一个标识列。此属性与CREATE TABLE和ALTER TABLE Transact-SQL语句一起使用。

10
人们为什么建议不要在标识列中使用名称“ Id”?
我被教导不要在Id表的标识列中使用该名称,但是最近我还是一直在使用它,因为它简单,简短并且对数据的真实性具有很强的描述性。 我见过有人建议Id给表名加上前缀,但这似乎对编写SQL查询的人(或者如果您使用的是诸如Entity Framework的ORM,则是程序员)做更多的工作,尤其是在较长的表名上,例如CustomerProductId要么AgencyGroupAssignementId 我们雇用了一个第三方供应商来为我们创建一些产品,实际上Ident是为了避免使用,而将其所有标识列都命名为Id。最初,我以为他们这样做是因为它Id是一个关键字,但是当我查看它时,发现它Id不是SQL Server 2005中的关键字,这就是我们正在使用的关键字。 那么为什么人们建议不要在Id标识列中使用该名称? 编辑:为澄清起见,我不是在问要使用哪种命名约定,也不是要在参数中使用一种命名约定。我只想知道为什么建议不要将其Id用于标识列名称。 我是一个程序员,而不是dba,对我而言,数据库只是存储我的数据的地方。由于我通常构建小型应用程序,并且通常使用ORM进行数据访问,因此使用Identity字段的通用字段名称要容易得多。我想知道这样做会导致我错过什么,以及是否有确凿的理由让我不这样做。

10
如何使用SELECT INTO复制表但忽略IDENTITY属性?
我有一个带有标识列的表说: create table with_id ( id int identity(1,1), val varchar(30) ); 众所周知, select * into copy_from_with_id_1 from with_id; 也会导致copy_from_with_id_1的身份也为id。 以下堆栈溢出问题提到显式列出所有列。 我们试试吧 select id, val into copy_from_with_id_2 from with_id; 糟糕,即使在这种情况下,id也是一个标识列。 我想要的是一张桌子 create table without_id ( id int, val varchar(30) );



6
我可以依靠顺序读取SQL Server身份值吗?
TL; DR:下面的问题归结为:插入行时,在生成新Identity值和锁定聚集索引中的相应行键之间是否存在机会之窗,外部观察者可以看到更新的值 Identity并发交易插入的价值?(在SQL Server中。) 详细版本 我有一个带有Identity名为的列的SQL Server表CheckpointSequence,这是表的聚集索引(也具有许多其他非聚集索引)的键。通过多个并发进程和线程将行插入表中(处于隔离级别READ COMMITTED,并且没有IDENTITY_INSERT)。同时,有些进程会定期从聚簇索引中读取行,并按该CheckpointSequence列排序(也处于隔离级别READ COMMITTED,并且该READ COMMITTED SNAPSHOT选项处于关闭状态)。 我目前依靠这样的事实,即读取过程永远不会“跳过”检查点。我的问题是:我可以依靠这个财产吗?如果没有,我该怎么做才能实现? 示例:当插入具有标识值1、2、3、4和5 的行时,阅读器在看到具有值4的行之前必须看不到具有值5的行。测试表明该查询包含一个ORDER BY CheckpointSequence子句(和一个WHERE CheckpointSequence > -1子句),只要要读取第4行但尚未提交,就可靠地阻塞,即使第5行已经提交。 我认为至少从理论上讲,这里可能存在一种竞争条件,可能会导致这一假设被打破。不幸的是,关于多个并发事务的工作方式的文档Identity并没有太多说明Identity,而只是说“每个新值都是基于当前的种子和增量生成的”。和“特定交易的每个新值都与表上的其他并发交易不同”。(MSDN) 我的推理是,它必须以这种方式工作: 事务开始(显式或隐式)。 生成标识值(X)。 根据身份值在聚集索引上获取相应的行锁(除非发生锁升级,在这种情况下整个表都被锁定)。 该行已插入。 事务已提交(可能要花很多时间),因此将再次删除该锁。 我认为在第2步和第3步之间,有一个很小的窗口, 并发会话可以生成下一个标识值(X + 1)并执行所有其余步骤, 因此,允许阅读者恰好在该时间点阅读值X + 1,而忽略了X的值。 当然,这种可能性似乎很小。但仍然-可能会发生。可以吗 (如果您对上下文感兴趣:这是NEventStore的SQL Persistence Engine的实现。NEventStore实现一个仅附加事件存储,其中每个事件都获得一个新的,升序的检查点序列号。客户端从按检查点排序的事件存储中读取事件为了执行各种计算,一旦处理了带有检查点X的事件,客户就只考虑“较新的”事件,即带有检查点X + 1及更高版本的事件,因此,至关重要的是永远不能跳过事件,因为它们再也不会被考虑了,我目前正在尝试确定Identity基于-checkpoint的实现是否满足此要求。这些是所使用的确切SQL语句:Schema,Writer的query,读者查询。) 如果我是对的,并且可能出现上述情况,那么我只能看到两种处理方式,但都不令人满意: 在看到X之前看到检查点序列值X + 1时,关闭X + 1并稍后再试。但是,由于Identity当然会产生间隙(例如,当事务回滚时),因此X可能永远不会出现。 因此,相同的方法,但是在n毫秒后接受间隔。但是,我应该假定n的值是多少? 还有更好的主意吗?

1
依靠INSERT的OUTPUT子句的顺序是否安全?
给定此表: CREATE TABLE dbo.Target ( TargetId int identity(1, 1) NOT NULL, Color varchar(20) NOT NULL, Action varchar(10) NOT NULL, -- of course this should be normalized Code int NOT NULL, CONSTRAINT PK_Target PRIMARY KEY CLUSTERED (TargetId) ); 在两种略有不同的方案中,我想插入行并从标识列返回值。 场景1 INSERT dbo.Target (Color, Action, Code) OUTPUT inserted.TargetId SELECT t.Color, t.Action, t.Code …

6
始终将单个整数列作为主键的不利之处是什么?
在我正在处理的一个Web应用程序中,所有的数据库操作都使用在Entity Framework ORM上定义的一些通用存储库来抽象。 但是,为了对通用存储库进行简单设计,所有涉及的表都必须定义一个唯一的整数(Int32在C#中,int在SQL中)。到目前为止,这始终是表格的PK以及IDENTITY。 外键被大量使用,它们引用这些整数列。它们是一致性和ORM生成导航属性所必需的。 应用程序层通常执行以下操作: 从表(*)加载初始数据 -SELECT * FROM table 更新 -UPDATE table SET Col1 = Val1 WHERE Id = IdVal 删除 -DELETE FROM table WHERE Id = IdVal 插入 -INSERT INTO table (cols) VALUES (...) 不太频繁的操作: 批量插入 - BULK INSERT ... into table所有数据加载后跟(*)(以检索生成的标识符) 批量删除 -这是正常的删除操作,但是从ORM的角度来看,这是“笨拙的”:DELETE FROM table where …

2
IDENTITY列中出现意外间隔
我正在尝试生成从1开始并以1递增的唯一采购订单号。我有一个使用以下脚本创建的PONumber表: CREATE TABLE [dbo].[PONumbers] ( [PONumberPK] [int] IDENTITY(1,1) NOT NULL, [NewPONo] [bit] NOT NULL, [DateInserted] [datetime] NOT NULL DEFAULT GETDATE(), CONSTRAINT [PONumbersPK] PRIMARY KEY CLUSTERED ([PONumberPK] ASC) ); 使用此脚本创建的存储过程: CREATE PROCEDURE [dbo].[GetPONumber] AS BEGIN SET NOCOUNT ON; INSERT INTO [dbo].[PONumbers]([NewPONo]) VALUES(1); SELECT SCOPE_IDENTITY() AS PONumber; END 在创建时,这可以正常工作。当存储过程运行时,它将以所需的编号开始,并以1递增。 奇怪的是,如果我关闭计算机或使其进入休眠状态,那么下一次该过程运行时,序列将增加近1000。 查看以下结果: 您会看到数字从8跃升至1002! …

3
重设IDENTITY值
我有一个带有IDENTITY列的表。在开发时,我会不时删除这些行,然后再次添加它们。但是,当我再次添加IDENTITY值时,它们始终保持增加,并且不是从1开始。现在我的ID是从68-> 92,这使我的代码崩溃。 如何重置IDENTITY值?

3
为什么SSMS在表格顶部而不是底部插入新行?
每当我在SQL Server Management Studio 2008(数据库是SQL Server 2005)中的表中手动插入一行时,新行就会出现在列表的顶部而不是底部。我正在使用标识列,这会导致类似 id row 42 first row 1 second row 2 third row 当获取行且未明确对其进行排序时。当为Web应用程序获取行并更改TOP 1查询返回的内容时,这将导致外观不同。 我知道我可以order by,但是为什么会这样呢?我的大部分数据都是通过Web应用程序插入的,来自此应用程序的所有插入都将按照先进先出的顺序进行,例如最新插入在底部,因此id都排成一行。服务器或Management Studio中是否有某些设置会导致这种不正确的订购?

4
向现有PK添加自动增量
我在另一个数据库中已经存在的数据库中创建了一个表。最初是用旧的DB数据填充的。该表的PK必须接收那些记录上已经存在的值,因此它不能是自动递增的。 现在,我需要新表将其PK作为自动增量。但是,在PK已经存在并且有数据之后,我该怎么办?

3
如何在仅具有IDENTITY列的表中插入?
给定只有IDENTITY列的表,您如何插入新行?我尝试了以下方法: INSERT INTO TABLE (Syntax error) INSERT INTO TABLE VALUES() (Syntax error) INSERT INTO TABLE (Id) VALUES() (Syntax error) 我正在测试某些东西,只需要IDENTITY列。它不是用于生产。否则,这样的表可以用作序列生成器,而无需其他列。

1
SQL Server在哪里将表的IDENTITY VALUE物理存储在哪里?
我希望有人可以指出我在这个方向上的正确方向。到目前为止,这是我的工作。 SELECT * FROM sys.identity_columns是一个提供“ last_value”的系统视图,但是该视图的定义使用了内部函数IdentityProperty(colName, 'LastValue')-因此是死胡同(不是从系统表中拉出它)。 互联网上的任何地方(我看过的地方)都建议使用DBCC IDENT_...命令来发现该值,但这仍然使我不清楚其实际存储位置。 因此,我开始DBCC PAGE(TestDB,1,1325,3)针对测试工具数据库搜索单个页面,并使用RESEED命令在值10和12之间重新设定种子。 在执行此操作时,我注意到上的十六进制值IAM: Header,IAM: Single Page Allocations并且IAM: Extent Alloc Status Slot 1所有值都已更改。(并且意识到它们无论如何都会随着bUse1值的变化而定期变化,而bUse1值本身也会逐渐变化)。 所以另一个死胡同,我全都没主意了。我还能在哪里搜索? 我正在运行SQL Server2014。我对内部知识有无限的渴望,并且还没有遇到像这样难以捉摸的东西。它引起了我的注意,因为从理论上讲,它(一个绝对值)存储在某个位置,并且应该(可以说)是可定位的。在我探索内部存储的数据/元数据的位置时,这个特殊的值使我感到难以捉摸。我猜测/希望有人会来告诉我,您可以接受,DBCC PAGE但我找错了地方。

2
复合主键效率作为外键
我有一个带有复合主键(由4列组成)的表,该键用于确保没有重复项输入到表中。我现在需要一个新表,该表需要将该表中的键作为外键引用。 我的问题是哪种方法对查找速度更有效: 1)我是否创建包括所有4列的新表,并在外键中引用它们。 要么 2)我是否在主键表中创建了一个新的标识列,并将其用作新表中的外键。 预计该数据库将存储大量数据,因此到目前为止,我已经建立了该数据库,以最大程度地减少每个表中存储的数据量。考虑到这一点,选项2将是最好的方法,因为我将为每行保存2个int列和一个datetime列,但是我想避免不必要的增加查找时间。

4
标识栏重新设置种子:何时需要?
在大学的最后一课中(我是学生),讲师要求我们开发数据库(如果重要的话,请使用MySQL Server)和小型客户端应用程序,该应用程序会将数据库用作数据源。 要求之一是,身份列(每个表中的PK)必须是顺序的,因为这是一种好习惯(按照讲师的话)。也就是说,当删除表行时,必须在后续插入中重用它的PK。我对RDBMS,PK和标识列有一般的了解。据我了解,标识列只是让数据库在插入行时自动生成PK的一种方式。标识列值不得以任何方式与行属性相关(只要它不是自然键即可)。 这个要求(严格按照顺序标识列)对我来说是可疑的。我试图问讲师,如果身份不是顺序的(由于删除引起的空白),那又有什么问题,但是却得到了非常抽象的答案,例如“它对用户方便,对维护数据库的数据库管理员有用”。没有具体的例子。“方便用户”这一说法听起来很愚蠢,因为它在业务领域没有任何意义。 因此,我很好奇这些原因是否真实?我只想到一种情况,即需要重新分配标识列种子时–当标识空间用尽时。但是,当标识列类型选择不正确时,例如用“ simple” int代替,bigint或者uniqueidentifier表包含十亿行时,这将是更多的设计问题。假设身份列是聚集索引:身份列中的间隙会影响索引性能吗?也许还有其他现实原因导致我不知道的每次删除后重新自动标识列的种子? 提前致谢!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.