1

我们需要以企业使用的格式存储人员,他们的“人员编号”。目前,他们使用手动流程为人员提供数字,例如 FP123456。下一个添加的人得到下一个数字,所以 FP123457。

根据该号码在系统中进行搜索。

我的想法是使用主键作为数字部分,带有 IDENTITY(123456,1),然后有一个计算列(不知何故),它将当前前缀(FP)附加到主键,给出 FPxxxxxx

我在考虑可能在 PersonNumber 列上使用默认值(如果可能的话),在插入时,它只是 'FP' + Id。

这是个好主意,还是可能存在问题?另外,我将如何在插入时默认该列。也许触发器会更好?

4

4 回答 4

2

I would certainly keep this PersonNumber separate from the Primary Key.

You will find folks who disagree, but in my experience using a natural key as the primary key always turns out to be a bad choice. Things change*.

  • Today you format the PersonNumber one way. Tomorrow you get a new boss with new ideas, and the format changes. Then you have the problem of updating not only the one original column "PersonNumber", you have to update foreign keys as well.
  • Tomorrow you may need to federate, meaning share records across multiple databases or other systems. So you would have to change the way you do your primary key, such as using UUID values rather than integer values.
  • At some point you may well need to rebuild your tables, involving exporting and importing your data. At that point you would want to keep your PersonNumber values but generate new primary key values.

Bottom line is that the job of generating a primary key may seem to be the same kind of job as generating PersonNumber, but they are really two different jobs. Separation of concerns is a guiding principal to avoid brittle (easily broken) software. For example, if the PersonNumber generator gets messed up somehow, at least the rest of the database (primary keys in this table and foreign keys in related tables) would still continue to function.

So use a surrogate key for the primary key. Then separately work out a strategy for managing the PersonNumber.

That strategy may involve the user interface or server-side app incrementing a number to generate the PersonNumber, as suggested by SDReyes on this page.

Another strategy is leveraging the database server to generate a sequence/serial for PersonNumber. If you have a serious database server such as MS SQL Server or Postgres, you should be able to create a sequence/serial generator without being tied to a primary key. You can create a trigger that calls on that sequence generator to assign a default value for new records. A serious database server will be built to handle the concurrency problem pointed out by SDReyes so that the numbers are generated without duplicates. But read the doc, as some serial number generators may have gaps in the sequence, especially if a transaction rollback happens. If that is unacceptable, you may need to find another route.


*If you think this unlikely, ask a programmer or sysadmin with grey hair.

于 2013-08-01T01:14:48.183 回答
2

是的,您可以使用计算列。您可以索引一个持久的计算列。

ALTER TABLE YourTable ADD PersonNumber AS 'FP' + CAST(ID AS VARCHAR(15)) PERSISTED NOT NULL
go

请参阅 SQL 小提琴

于 2013-08-01T00:17:28.663 回答
1

我建议您使用不同的自动生成列作为 id,例如 int。为什么?因为它非常有效地进行连接,例如,您可以在不破坏外部引用完整性的情况下更改人员编号。

另一个名为“人员编号”的列将包含具有唯一性约束的此类编号(例如 FP1337)。

于 2013-07-31T23:47:07.027 回答
0

如果您的号码是在外部生成的,那么只需使用它。听起来你已经有了你的PK。你只会在未来的某个时候弄错。

如果您建议从现在开始需要在数据库中生成它们,那么只需使用 IDENTITY 并且不要打扰 FP 前缀 - 只需在 UI 上将其取下即可。

于 2013-07-31T23:49:03.220 回答