向用户公开代理键

时间:2011-11-28 15:32:20

标签: database nhibernate architecture orm primary-key

我正在设计一个新的应用程序,并且有一个表格,其中包含用户希望用数字唯一标识的项目。该表将有一个代理键,可以用于此目的,但是如果我应该将它暴露给用户,我还没有决定。他们只会将此id用作只读和查找,应用程序将处理幕后密钥的创建。

这个想法是为了避免潜在的问题。如果密钥是由dbms自动生成的标识字段,那么您无法控制密钥。我在我的应用程序中使用NHibernate,所以我可以通过使用HiLo控制密钥,如我所说的here所述。如果重要,DBMS就是Oracle。

通过揭露钥匙,我可能遇到的一些潜在问题是什么?

  1. 让我们假设用户通过制作一些使用此密钥的Excel电子表格来构建对它的依赖。钥匙能改变吗?
  2. 如果某些记录在数据库损坏或意外中丢失,并且我想避免与旧密钥发生冲突,我是否只能在NHibernate中调整我的起点以跳过先前生成的数字?
  3. 如果用户想要更改其他识别其记录的方法,该怎么办?假设他们想要从一些有意义的字符代码开始。我可以不显示计算(未存储)标识符,或者根据我的代理主键随时创建新的备用键列吗?
  4. 如果某人能够展示一个明确的示例,说明如何向用户公开托管代理主键可能会成为问题,我将创建一个替代密钥以呈现给用户,否则我将公开代理主键。

    谢谢!

4 个答案:

答案 0 :(得分:1)

前三个问题很容易

  1. 不容易。这是代理键的主要好处。可以更改的候选密钥在它们是主密钥时会导致麻烦。
  2. 是的,但你不应该因为#1
  3. 是的你应该。
  4. 这个更难。

      

    如果有人能够展示如何公开托管的明确示例   用户的代理主键可能会成为我的问题   将创建一个替代密钥,以呈现给用户,否则我会   暴露代理主键。

    但是有两个常见的问题。

    1. 用户习惯于看到没有洞的数字增量。但迟早他们会得到一个或多个,他们会要求填补这些漏洞。他们并没有很多很好的理由,你需要推迟这一点。

    2. 如果您的系统允许按ID查找或通过ID输入更糟糕的数据,则可能会出现问题。这是因为有数字的拼写错误很容易。由于这个原因,信用卡号码使用汉明功能使得很难错误输入有效号码的信用卡号码。

    3. 因此,如果您确保用户不利用代理键的顺序性质而您不将其用于用户数据输入,那么您应该没问题,否则您可能需要考虑使用密钥生成你可以在哪里发现错别字。

答案 1 :(得分:1)

代理密钥可以改变吗?是。假设您的公司被另一家公司收购,他们决定合并数据库。如果有人的身份证号码必须改变,那将是你的,而不是他们的。我参与了两次这样的系统整合,并且不是漂亮。

虽然我还没有这样做,但我相信你可以改变NHibernate的起点。 (在大多数ORM中,您至少可以创建自己的类,扩展ORM的类。然后编写您想要的行为。)

您可以根据您的身份证号码向用户显示计算密钥吗?不是一般情况。当用户提出关键的想法时,它们通常不是很好,并且几乎总是需要一些手动调整。所以你几乎肯定要存储它。没有错。 (除了让用户设计具有编码含义的键。)

  

如果。 。 。向用户公开托管代理主键可能会成为一个   未来的问题我将创建一个替代密钥来呈现给   用户,否则我将公开代理主键。

  • 用户必须能够识别事物。
  • SQL数据库使用键来识别事物。
  • 要识别SQL数据库中的内容,用户至少需要查看一个 自然的关键。

(有例外,但并不多。)

因此,如果您使用隐藏的代理键,则至少需要一个自然键才能呈现给用户。为什么一个自然键?没有一个,你最终会冒这样的表格。

id    title
--
1     An Introduction to Database Systems
2     An Introduction to Database Systems
3     An Introduction to Database Systems
4     An Introduction to Database Systems
8     An Introduction to Database Systems
15    An Introduction to Database Systems
37    An Introduction to Database Systems

但是通过隐藏代理人,用户可以看到这一点。

title
--
An Introduction to Database Systems
An Introduction to Database Systems
An Introduction to Database Systems
An Introduction to Database Systems
An Introduction to Database Systems
An Introduction to Database Systems
An Introduction to Database Systems

如果需要更新与其中一个标题相关的行,用户将如何知道要选择哪个标题?

答案 2 :(得分:1)

ID通常并且通常应该是实现问题,用户不应该关心它们。我建议你重新考虑是否真的需要向用户显示标识符。不知道你的具体情况,也许是,但我对此表示怀疑。用户不应该关心更新记录12345或者他们是客户54321.用户应该知道我正在更新我的地址或购买特定商品。

如果将标识符暴露给用户实际上只是让它出现在查询字符串中,那么使用代理主键是完全合适的。

如果确实是业务需求,则用户需要查看id:

  1. 密钥永远不需要改变,它不应该改变。 catcall获取并将此信息合并到另一个数据库的示例是边缘情况,即使在采集中也可能不会发生,并且除了更改id之外还有其他方法可以使用单独的表或创建复合键。我不担心。

  2. 是的,无论哪种方式 - identity或hilo - 您都可以更改身份种子或更新hibernate_unique_key表以更新新ID的范围。我建议在使用nhibernate时你从不使用身份并且总是喜欢hilo(或guid)。身份生成器需要进入数据库来获取id,这与nhibernate喜欢在会话中对操作进行批处理并在flush上进入数据库的方式形成对比。有些事情与nhibernate不兼容,如果你使用身份,你会看到微妙和意想不到的错误,因为nhibernate做的事情与你在这种情况下预期的不同(有些事情不起作用)。 / p>

  3. 是的,那些肯定是选择。

  4. 我不认为暴露id是一个问题,除了它几乎在所有情况下可能不是用户想要的。但是没有技术理由不这样做。

答案 3 :(得分:1)

如果要求用户准确更新单个元组,那么他们将需要一个密钥,通过该密钥,他们可以识别他们感兴趣的信息。这通常是所谓的业务密钥。代理密钥是没有商业意义的密钥,通常意味着代理密钥不会暴露给用户(否则它在业务领域内获得意义)。

确保用户至少看到每个表的一个键是明智的。虽然不是“代理”键。如果一个密钥用于识别作为业务流程一部分的信息,那么它并不是真正的代理密钥,并且没有太多意义来调用它。

所有密钥都可以并且确实有理由进行更改,其中包括代理人。