Database design 在关系数据库中实现全局唯一标识符的优缺点和方法?

Database design 在关系数据库中实现全局唯一标识符的优缺点和方法?,database-design,primary-key,relational-database,uniqueidentifier,unique-key,Database Design,Primary Key,Relational Database,Uniqueidentifier,Unique Key,关于我问题的第一部分:我最近问自己,在关系数据库中为某些表使用唯一标识符的好处和利弊是什么。例如,Facebook(FB)Graph API允许使用同一URL获取不同类型的对象,如“用户”、“事件”、“页面”等,例如返回“事件”类型的对象,而返回“组”类型的对象 与提供不太“通用”的API相比,这种方法的好处是什么。在这种情况下,可能会对不同的对象类型使用类似的标识符,因为每个对象类型都有其标识符范围 关于问题的第二部分:实现全局唯一标识的选项是什么 我想到的两个选择是: 使用基于继承的方法(每

关于我问题的第一部分:我最近问自己,在关系数据库中为某些表使用唯一标识符的好处和利弊是什么。例如,Facebook(FB)Graph API允许使用同一URL获取不同类型的对象,如“用户”、“事件”、“页面”等,例如返回“事件”类型的对象,而返回“组”类型的对象

与提供不太“通用”的API相比,这种方法的好处是什么。在这种情况下,可能会对不同的对象类型使用类似的标识符,因为每个对象类型都有其标识符范围

关于问题的第二部分:实现全局唯一标识的选项是什么

我想到的两个选择是:

  • 使用基于继承的方法(每个类的表、单个表等)。假设使用每类表的方法(超级表仅包含唯一标识符作为主键,表示对象类型的子表包含与超级表相同的标识符和其他数据),超级表和子表之间需要连接,因为超级表成为瓶颈,所以这两个表之间的连接看起来扩展性很差

  • 提供一个包含3列的表,其中包含

    • 唯一标识符
    • 对象类型指定的主密钥,以及
    • 表名
    每个对象类型的附加表,包含引用唯一标识符作为外键的列。每个对象类型特定的表都有自己的主键作用域

  • 这两种方法都允许提供类似上述FBAPI的通用API。第二种方法允许在内部使用特定于对象表的主键,并且只公开全局唯一标识符。但是,如果可以在内部使用全局唯一标识符,则第二种方法也需要连接

    关于全球唯一标识符的优点/缺点以及实施它的最佳实践,是否有任何经验?

    “一个问题说得好,是一个已经解决了一半的问题”

    在我看来,你把几个概念混在一起了。你检查了其他数据库应用程序,但似乎你变得更加困惑,而不是更加知情

    您有几个不同类的对象,您想知道如何将它们存储在数据库中。这通常被称为对象关系映射(O.R.M.)的“花式名称”

    此外,您希望使用全局唯一标识符(G.U.I.D.)来标识一个对象,该对象既是业务/编程对象,也是表中的一行

    此外,您还需要使用G.U.I.D.来标识特定类型的类或对象

    假设您正在构建一个应用程序。这里有几个对象。有几类对象,如“用户”、“事件”、“页面”等。您可以拥有多个相同类/类型的对象,但需要一种方法来识别其中一个。识别密歇根州的“约翰·多伊”,昆士兰州的“约翰·多伊”。假设您的对象将使用类型为G.U.I.D的属性

    因此,让我们支持您为每个类创建一个表(“user”代表“Users”,table standard id.是单数和小写,尽管您可以忽略它,“event”代表“events”,等等)。每个表都有几个字段,表示每个对象的属性。所以“user”将有一个类似“user\u key GUID”的字段,可能还有“user\u name varchar(100)”和“user\u birthdate datetime”。其他桌子也是如此

    我曾使用过“supertable”,但只用于一个非常特定的应用程序,而不是普通的应用程序。我认为你不需要一个混合了“用户”、“事件”、“页面”的表格。我有一个例子,我们有一个超级表“customers”,加上带有特定附加字段的“company”和“person”子表。有时,我们必须检查所有客户的销售额,并与“客户”表进行联接。有时,我们不得不为产品提供公司折扣,并浏览“公司”子表

    如果希望此泛化/“是”超表,则不需要为超表主键和明细表主键指定不同的字段,可以是相同类型的字段

    我建议不惜一切代价避免使用复合/复合键(“主键”加上“其他”字段),使用单个字段主键。我还建议使用编程来分配G.U.I.D.密钥,而不是在数据库中

    与整数密钥相比,G.U.I.D.使用了更多的内存和磁盘空间,但是,它非常快速且容易获得一个很难复制的密钥


    同样,您的问题更多的是如何在数据库中表示对象,而不是使用G.U.I.D.

    您提出的两种实现全局标识符的方法都涉及到大表的联接和数据库中记录数的有效加倍(每个对象都独立存在,但其具有全局ID的父/记录也是如此)

    我有一种感觉,在应用程序/数据访问层实施全局ID会更好。 这可以通过强制每个特定类型的对象的ID只来自可能ID的子集来实现。例如,您可以保留所有ID的最后/前x位以指定对象类型。ID的剩余部分将是“实际ID”

    如果在为特定表分配ID时担心出错,可以添加一个检查约束,以强制执行ID是否正确(例如ID<4000和ID>10000)。
    如果您担心标识符中对象类型所浪费的位/字节,那么可以仅在数据库访问API中公开全局ID,这将把对象的ID(实际存储在表中)与其类型ID(从对象类型派生)连接起来

    “同样,你的问题更多的是如何表示数据库中的对象,而不是G.U.I.D.的用法。”错了,我问题的第一部分提到