2008-11-17 39 views
3

我在SQL 2008服务器中有几个表,我需要为其生成唯一的ID。我已经查看了“身份”列,但ID确实需要是唯一的,并在所有表格之间共享。因此,如果我有5个表“风格资产基础设施”的表格,并且我想用它们之间的唯一ID作为一个组合组运行,我需要某种类型的生成器来查看所有(5)五张桌子,并发行下一个身份证,这个身份证在这五(5)个故事中没有重复。生成唯一的ID以与多个表共享SQL 2008

我知道这可以用某种存储过程来完成,但我不知道如何去做。有任何想法吗?

+0

@Jonathan你似乎正在修复我所有的错别字:)干杯。 – 2008-11-17 05:33:53

回答

4

为什么不使用GUID?

+0

由于guid不是用户友好的单一原因,这一点通常是为用户提供一个他们可以记住的短序列,并用于快速访问实体。 – 2009-04-30 06:47:32

4

你可以让他们每个人都有一个身份,这个身份的种子数量足够远,永远不会相互碰撞。

GUID可以工作,但它们很丑陋,而且如果这很重要,它们就是非连续的。

另一种常见技术是使用一个标识为每列插入记录时分配下一个值的单列表。如果你需要从一个普通的序列中抽取它们,那么有第二个列指出它被分配到哪个表是不太可能的。

你意识到有这样的逻辑设计问题,对吧?

+0

将ID /身份作为查询字符串参数传递是非常常见的,如果该ID是唯一的,则不能在该域的外部使用该ID,即表/上下文。这也比你想象的要聪明得多。 – 2009-04-30 06:45:18

+0

只是一小点,但自SQL2005以来,您可以创建顺序的GUID。 – BlackWasp 2009-05-31 18:26:55

4

读入一个位,这听起来像你真正需要的是所谓的“资产”与标识列一个表,然后设计之一:

一)5资产的亚型附加表,每个都带有一个外键给Asset上的主键;或

b)资产上的5个视图,每个视图选择行的一个子集,然后对用户显示,就像现在的5个原始表一样。

如果表中的列全部相同,(b)是更好的选择;如果它们完全不同,(a)是更好的选择。这是超类型/子类型关系的典型数据库旋转。

或者,你可以做你正在谈论的事情,并用存储过程自己重新创建IDENTITY功能,该存储过程包装所有5个表的INSERT访问权限。请注意,如果您希望保证唯一性,则必须在其中放置TRANSACTION,并且如果这是一个受欢迎的表,那可能会使其成为性能瓶颈。如果这不是一个问题,这样的一个进程可能采取的形式:

CREATE PROCEDURE InsertAsset_Table1 (
    BEGIN TRANSACTION 
    -- SELECT MIN INTEGER NOT ALREADY USED IN ANY OF THE FIVE TABLES 
    -- INSERT INTO Table1 WITH THAT ID 
    COMMIT TRANSACTION -- or roll back on error, etc. 
) 

此外,SQL是高度帮助你出去了优化,如果你选择我上面提到的方式,而不能用于这种事情优化(在创建事务时会有开销,并且在进行此过程时您将在所有5个表上发布共享锁)。与使用上面的PK/FK方法比较,SQL Server确切地知道如何在没有锁的情况下或者只在1个表中插入视图方法。

0

我在谷歌搜索时发现了这个。我第一次面临类似的问题。我有想法有专门的ID表来生成ID,但我不确定它是否被认为是OK设计。所以我只想说感谢确认..它看起来是一个足够的溶剂,虽然不理想。

5

最简单的解决方案是在每张桌子上设置您的身份种子和增量,以免它们重叠。 表1:种子1,递增5 表2:种子2,增量5 表3:种子3,增量5 表4:种子4,增量5 表5:种子5,增量5

的身份列模块5会告诉您该记录位于哪个表中。您将快速使用您的身份空间五倍,因此请确保数据类型足够大。

0

我有一个非常简单的解决方案。它应该是很好的情况下,当表的数量少:

create table T1(ID int primary key identity(1,2), rownum varchar(64)) 

create table T2(ID int primary key identity(2,2), rownum varchar(64)) 

insert into T1(rownum) values('row 1') 
insert into T1(rownum) values('row 2') 
insert into T1(rownum) values('row 3') 

insert into T2(rownum) values('row 1') 
insert into T2(rownum) values('row 2') 
insert into T2(rownum) values('row 3') 

select * from T1 

select * from T2 

drop table T1 
drop table T2 
0

使用一桌子的人(称为人称单数,请)和每个人进行分类,例如医生时,例如,这是一个普遍的问题,患者,雇员,护士等

为每个这些人创建一张表,包含他们的特定类别信息(如员工开始日期和工资以及护士资格和数量)是很有意义的。

A例如,患者可能有许多护士和医生在他身上工作,因此在PERSON表中将患者链接到其他人的多对多表可以很好地促进这一点。在这张表中应该有一些关于这些人之间的关系的描述,这将我们带回到人们的分类。

由于Doctor和Patient可以在其​​自己的表中创建相同的主键ID,因此具有全局唯一ID或对象ID变得非常有用。

建议这样做的一个好方法是让一个表指定为自动增量主键。首先在该表上执行插入操作以获取OID,然后将其用于新PERSON。

我想更进一步。当事情变得丑陋时(某些新开发人员将他的手放在数据库上,或者甚至更糟糕,是一个非常老的开发人员,那么它对OID增加更多的含义非常有用。数据库引擎,但是如果你使用BIG INT来表示所有的主键ID,那么你就有很多空间给一个数字加上可视的可识别序列,例如所有的医生ID都可以从100开始,所有的患者都是110,所有的护士有120 。

要,我会追加说Julian日期或Unix的日期+时间,最后追加自动递增ID

这将导致相同的数字:

110,2455892,00000001 
120,2455892,00000002 
100,2455892,00000003 

自从Julian从现在开始的100年后只有2492087年,您可以看到7位数将充分存储此值。

BIGINT是一个范围为-9.22x10^18到9.22x10^18(-2^63到2^63 -1)的64位(8字节)有符号整数。注意exponant是18.这是你必须使用的18位数字。

使用此设计,您仅限于1亿OID,999类别的人员,并且可以...尽可能超过数据库的保质期,但我认为这对于大多数解决方案来说已经足够了。

像这样创建OID所需的操作都是乘法和除法,它可以避免所有的文本操作磨齿。

缺点是INSERT需要的不仅仅是一个简单的TSQL语句,而是它的优点是当你追踪错误的数据或者在你的查询中很聪明时,你的OID可视化地告诉你不仅仅是一个随机数或者更糟的是,像GUID这样的眼神。