经常在没有自然键的表中,用户仍然有用,能够具有唯一生成的标识符。如果表具有代理主键(并且在这种情况下,您当然期望它)如果该密钥会被暴露给用户,或者应该将另一个字段用于此目的吗?

一个原因不公开代理关键是现在您无法执行保存记录之间关系的操作,但更改键值,例如某些类型的删除/重新插入,许多复制数据的方法一个数据库到另一个数据库等。

暴露代理键的主要优点是使用您已经拥有的字段的简单性。

在什么情况下更好地直接将代理密钥暴露给用户?

有帮助吗?

解决方案

您需要准备好接触到需要更改的用户/客户的任何标识符,以及更改数据库中行的标识并将其传播到所有外语的变更只是要求打破数据。

如果数据没有自然业务密钥,则可以为“业务标识符”添加其他字段。应该针对它用于的过程进行优化。电话键盘条目意味着数字。通过电话/口头表示避免类似的探测符号(B / D,M / N等)。您甚至可以自动捕获一些易难忘的短语(“绿色果冻”)。

这的效果是,业务稍后可以更改它们如何提到记录,并且唯一的数据模式更改是为该样式添加一个新列,或者在那里转换IDS。该更改不会通过整个数据库传播,并且您仍然具有随时间有效的一个ID(代理人)。

简而言之,我会避免将代理钥匙暴露给用户。随着评论指出的,代理键几乎应该永远不会改变。相反,企业希望改变一切。如果替代键被曝光,商业希望改变它就是一个时间问题。

作为一个侧面笔记,当我说“曝光”这里,我的意思是为了向用户提供密钥,期望他们直接使用它(如呼吁支持他们的订单号)。

其他提示

In some cases, surrogate keys are expected and make sense to users. My favorite example is "order number". Order number isn't really a natural key: a natural key might be timestamp plus user, or maybe more than that if you expect users to generate more than one order within the granularity of your timestamp.

Nonetheless, users understand and expect the convenience of an order number. There is no harm, and lots of value, if you let users know about them.

On the other hand, some surrogate keys make no sense to a user. Sure, my health insurance company has some surrogate key that identifies me based on my member id, date of birth, carrier, etc, but I don't care about that, I care about the info on my card (which often includes ids based on my employer and are not unique across the universe... Hence the surrogate key at the insurance company).

In layman's words:

  • Surrogates should be hidden from the user.
  • You should expose some other business candidate key to the user.
  • If no other candidate key exist you should show the PK. But in this case the PK is not considered a surrogate since it's not a substitute for other column.

you should ONLY expose a field to a user that provides useful information to the user, either directly or in reporting defects to you.

conversely, you should ALWAYS expose "surrogate primary keys" when they are the principal means of identifying a record (simple or complex) for an interaction the user performs.

You should only expose a surrogate key if it's a properly generated GUID/UUID*. Exposing sequential surrogate keys is number 4 on the OWASP Top 10 security issues.

* In practice, it's best to assume that it wasn't properly generated for these purposes unless you know that it was created by a cryptographically secure random or pseudo-random number generator.

If a table has no natural key, surrogate keys allow rows like this.

surrogate_key  some_name
--
1              Wibble
2              Wibble
...
17             Wibble
...
235            Wibble

I'd call these artificial keys instead of surrogate keys, but that distinction isn't important for this question.

Now, assuming that there's important data referencing these surrogate keys through foreign keys, how would the end users know which row to update if they don't know the surrogate key values?

It shouldn't matter whether you expose the keys or not to the end user. Your application should perform the necessary authorization such that simply knowing an order id, for example, can't allow them access to something they normally wouldn't have access to.

caveat: this assumes a web based or n-tier application where server side authorization is possible/feasable. If you have a VB app thats directly executing sql, thats a whole 'nother issue.

According to the principle of encapsulation, which is a foundational concept in OOP, you should hide implementation details. Once a surrogate becomes public it becomes data. One man's surrogate key is the next man's natural key.

In practice I think surrogate keys should be encapsulated at the boundary of a service layer. If you have a service for some aggregate root then the internal domain objects and repository would all use the surrogate key. These internals would all be encapsulated. The public API would use some other format which could include nesting to hide parent keys, so hiding the surrogate key of the root record isn't exactly a seven year leap.

One health-care company that I did a project for had a nasty problem with their "provider IDs." These were originally hand-managed and they contained embedded information. A single provider might have more than one ID, and had to know the "right" one to use at each clinic. And, unfortunately, some provider-IDs had been assigned to more than one provider at a time!

To solve the problem and to allow several different systems to communicate with each other unambiguously, I created an internal-only system of surrogate keys: they were simply random strings of letters that were the same length as the old (numeric) provider-ID strings. This was done so that column-sizes and data types didn't have to be changed.

One master system had to take a provider-ID, "figure out who it meant," and return the proper surrogate key, which always corresponded 1:1 to a single person.

Sometimes, that same system had to go the other way ... "which (legacy) provider-ID should we give them when referring to [this_person_surrogate] in [that_system]?"

Each of the downstream systems was now re-coded to use these unambiguous surrogate keys to refer to persons, knowing that every other system would be using only the same surrogate value.

Within each system's database, auto-increment integers were conveniently used as primary and foreign keys, and these keys were of course never shared with any other system. The record for each "person" contained its surrogate.

Any request that one system made to another system always used the surrogate. No system ever knew what any other system's "primary keys" were.

Carrying this concept one step further, surrogate keys were never published externally. The company eventually re-vamped its provider-ID system in an effort to clean up their mess, but when they did so we created a new provider-id "for public consumption," and tied those values to the surrogates just as we had done with the old IDs. Thus, the "purity" of the surrogates was not compromised, and the company didn't have to give its providers "ugly character strings."

许可以下: CC-BY-SA归因
scroll top