因此,假设我正在使用支持多种方法的数据库,是否有一个简单的启发式来确定最适合我的选择?
如何分析/多个主人,性能要求,ORM使用,安全性和测试等考虑有哪些选择?
任何可能遇到的意想不到的缺点?
解决方法
除非这些是在增加单调序列中产生的,否则它们会严重伤害/分散索引.对UUID生成的支持因系统而异.虽然可用,但在大多数情况下,我不会使用UUID作为主要聚簇索引/ PK.如果需要,我可能会把它作为第二列,也许是索引,也许不是.
有人认为,UUID可用于安全地从任意数量的系统生成/合并记录.虽然UUID(取决于方法)通常具有很小的碰撞机会,但至少有一些外部输入或非常糟糕的运气可能会产生碰撞.我相信只有一个真正的PK应该在系统之间传输,我认为在大多数情况下我不会(或不应该)数据库生成的UUID.
自动增量/顺序键和序列表
这真的取决于数据库的支持.一些数据库支持更灵活的序列,简单的“自动增量”.这可能是或可能不是可取的(或者可能是这种任务的简单方法,甚至是).序列表通常更灵活,但是如果需要这种“灵活性”,我将很乐意回去参观设计模式,特别是如果涉及使用触发器.虽然我不喜欢“限制ORM”,但也可能在选择“更简单”的自动增量或序列类型/数据库支持方面有所作为.
不管使用何种方法,当使用代理主键时,仍然需要将真正的主键标识并编码到模式中.
此外,我认为“通过暴露自动序列PK来进行安全性妥协”是由于不正确地暴露内部数据库属性而导致的.虽然处理CRUD操作非常简单,但我相信内部按键和外露键(例如漂亮的客户编号)有区别.
只是我的两美分.
编辑,附加回复Tim:
I think the generated vs. true PK question is a very good one and one I need to consider also. I’d like UUIDs in general to the points you make. My hesitation was in size vs. an int/long. Was not aware of potential indexing de-optimizations,which is a much bigger concern for me.
我不会真的担心的大小 – 如果UUID是最好的,那么这是最好的.如果不是,那不是.在整体方案中,一个int的额外的12byte可能不会有太大的区别. sql Server 2005支持newsequentialid UUID生成功能,以避免与正常的UUID生成相关联的碎片.该页面讨论一些.我相信其他数据库有类似的解决方案.
And by “encoded into the schema”,do you mean more than adding a uniqueness constraint?
是.主键不一定是唯一的[unique]约束.只使用代理PK并不意味着数据库模型应该受到损害:-)附加索引也可以用来覆盖等.
And by “distinction between”,are you saying that surrogate primary keys never leak out?
我最初的帖子中的措词很难.这不是“永远不会”,如果他们这样做,那么这是另一个问题.人们常常通过猜想的数字来抱怨不安全感 – 例如如果您的订单是23,那么可能有一个订单22和24等.如果这是您的“保护”和/或可能泄漏敏感信息,那么系统已经有缺陷. (分离内部和外部ids并不固有地解决这个问题,仍然需要身份验证/授权.但是,使用“连续ids”提出了一个问题 – 我发现将一个随机数编码到分布式URL中可以处理我的用例相当好.)
更多的是我真正想跨越的:只是因为代理PK ID恰好是8942并不意味着它是8942的顺序.也就是说,保持与“一些字段是内部只有db”设计,顺序“数字“可能在表面上完全无关(但在DB模型中完全支持),例如”#2010-42c“或对业务需求有意义.在大多数情况下,这是外露的数字.
I feel that sometimes the generated key is really the true primary key as other fields are mutable (eg. user may change email and username).
这可能是数据库中的情况,我不会争论这个声明.然而,再次认为代理PK是数据库内部的,只需确保只导出/导入可以被很好识别的元组.如果用户名/电子邮件可能会更改,那么这可能非常好地包括在创建帐户时分配的UUID,并且很可能是代理PK本身.
当然,与所有的一样,保持开放并适应模型的问题,而不是模型的问题:-)对于像twitter这样的服务,他们使用自己的数字生成模式.请参见Twitter’s new ID generation.与[某些] UUID生成不同,twitter的方法(假设所有服务器都正确设置)保证所有分布式机器/进程都不会生成重复的ID,只需要64位,并保持粗略的排序(最重要的位是时间戳). (twitter生成的记录数可能与本地要求无关;-)
快乐编码.