如何使用UUID但仍与现有数据库ID兼容?

时间:2010-06-24 12:49:53

标签: sql api architecture uuid

我们目前正在为我们的产品设计API。 API提供对包含类型之间关系的图表的访问,例如用户,帖子等。

现在,这些对象在我们的数据库中由主键id引用,但由于每个对象都在不同的表中,因此这些ID在没有对象类型(= table)信息的情况下发生冲突。

这似乎不是问题,但它确实适合我们 - API设计与错误位置的ID碰撞/类型信息更加不一致。

现在出现了使用UUID的想法,并且由于我们将来可能会从SQL db迁移到K / V存储,这可能不是最糟糕的想法,UUID也提供了更好的唯一性并且还可以扩展更好。因此,从各种角度来看,在我们的API中实现UUID并不是最糟糕的事情。

但是,对于过渡期,我们仍然需要通过DB id访问对象,并且应该从id生成UUID并允许从UUID推断出id,反之亦然。

550e8400-e29b-11d4-YYYY-XXXXXXXXXXXX之类的东西浮现在脑海中,其中X将是数据库中的主键,而YYYY将是对象类型的代码。

有没有“正确”的方法来做到这一点?我可以用这种方法破坏任何东西吗?全部或部分保存其他UUID信息实际上不是一种选择。

感谢您的见解, 菲利普

4 个答案:

答案 0 :(得分:1)

想到两件事:

创建单个序列,并使用它来填充所有主键。这不是真正的UUID,但在当前系统中是唯一的。 (即在一个实例中你会没事的,但共享数据可能是其他系统的问题)

创建一个地图表。类似EXTERNAL_KEY的东西,包含internal_id,internal_table,external_id。使用每个表上的ON INSERT触发器中的一行填充它,并在您的应用程序中使用external_id作为UUID。

顺便说一句 - 我会建议强烈反对创建一个带有某些值的子串的“智能”键等。

HTH

答案 1 :(得分:1)

根据定义,代理键与数据本身无关。因此,无论您使用的是整数还是guid,使用代理键的假设是无法仅通过密钥来确定有关实体本身的任何信息。正因为如此,您必须对代理主键之外的表中的其他内容具有唯一约束。因此,我不会尝试将任何信息烘焙到新的代理键模式中。相反,我会使guids“独特”并像使用整数键一样使用它们。反对试图将信息融入指导的论点是简单性,从而具有成本效益。我怀疑你是否会使用在guid中加入的魔法,但它会让它产生痛苦。

现在,通过“独特”,我暗示了guids的一个问题:它们的索引不好。虽然它们的独特性是一种优势,但在这方面也是一个弱点。常见的解决方案是使用所谓的COMB guid,它用日期时间值替换部分guid。 guid仍然大多是独一无二的,但它的一部分现在是顺序的,并且指数很好。

答案 2 :(得分:0)

我不知道任何具体问题,但建议使用version 4 GUIDs

  

版本4 UUID的格式为xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx   使用x的任何十六进制数字但是   对于y,只有8,9,A或B中的一个。例如   f47ac10b-58cc- 4 372- a 567-0e02b2c3d479。

您可以将数据放在“随机”部分。只是声称你有一个非常垃圾的随机数生成器。您还可以包含校验和以防止数据损坏冲突,因为您的GUID将以数字方式彼此靠近。

答案 3 :(得分:0)

也许我有点过于简单,但是如果你愿意改变传递的标识符的数据类型,关于创建计算列的方法,请输入包含ServerName / Instance.db_name的varchar(?)。 schema_name.table_name.id。鉴于servername / Instance对您的环境是唯一的,对您的实例是db,对您的db是架构,对于您的架构和对您的表的id - 它们都应该,所以唯一性是有保证的。

对于这种用途的数据去标准化,我没有任何问题。我有一个很大的问题是有人使用这样的字段来提问 - 在代码中 - 例如,给我所有来自Server02的记录。这将是一个字符串字段,并且不会像GUID那样可搜索,但是,根据它们在哪里/如何存储,在它们的原始表之外,我怀疑它不是索引碎片整理的原因它们属于哪个。

  • 对于sql server中的'ordered'guids,请参阅Creating and Modifying Identifier Columns

    CREATE TABLE dbo.Globally_Unique_Data (guid uniqueidentifier CONSTRAINT Guid_Default DEFAULT NEWSEQUENTIALID() ROWGUIDCOL,     Employee_Name varchar(60) CONSTRAINT Guid_PK PRIMARY KEY(guid));