生成唯一的主键

本文关键字:唯一 | 更新日期: 2023-09-27 18:09:19

我有一个SQL Server数据库,它将包含许多表,所有连接,每个主键。我有一个Dictionary,它跟踪每个表的主键字段。我的任务是每天从以属性为中心的XML文件中提取数据,并将它们插入主数据库。每个XML文件都有相同的模式。我通过使用XMLReader并将数据导入DataSet来做到这一点。

我不能使用AutoNumber作为键。假设昨天的XML文件产生了一个类似于下面的DataTable,它被导入到数据库

-------------------------------------
| Key | Column1 | Column2 | Column3 |
|-----------------------------------|
|  0  | dsfsfsd | sdfsrer | sdfsfsf |
|-----------------------------------|
|  1  | dertert | qweqweq | xczxsdf |
|-----------------------------------|
|  2  | prwersd | xzcsdfw | qwefkgs |
-------------------------------------

如果今天的XML文件产生以下DataTable

-------------------------------------
| Key | Column1 | Column2 | Column3 |
|-----------------------------------|
|  0  | sesdfsd | hjghjgh | edrgffb |
|-----------------------------------|
|  1  | wrwerwr | zxcxfsd | pijghjh |
|-----------------------------------|
|  2  | vcbcvbv | vbnvnbn | bnvfgnf |
-------------------------------------

然后当我使用SqlBulkCopy将新数据导入数据库时,就会有重复的键。我的解决方案是使用DateTime.Now.Ticks来生成唯一的密钥。理论上,这应该总是创建一个唯一的密钥。

然而,由于某些原因,DateTime.Now.Ticks不是唯一的。例如,一行中的5条记录可能都具有键635387859864435908,而接下来的7条记录可能具有键635387859864592164,即使我在不同的时间生成该值。我想说问题的原因是我的脚本在更新时间之前多次调用DateTime.Now.Ticks

还有人能想到更好的方法来生成密钥吗?

生成唯一的主键

DateTime。出于性能原因,现在会缓存一小段时间。我们做了类似的事情,我们使用两个可能的选项:

  1. 保留一个你在服务器上使用过的号码列表,如果你能确定这个号码已经被使用过,则增加这个号码
  2. 将字段转换为字符串,并在其末尾附加GUID或其他随机标识符。GUID可以用System.Guid.NewGuid().ToString();
  3. 创建

显然,这两种计划都不能使碰撞的风险为零,但它们可以帮助降低碰撞的风险。

如果你有大量的数据,你需要有一个唯一的键为每一行只需使用GUID

您可以执行以下操作来获取唯一id (SQL Fiddle):

SELECT
CONCAT(YEAR(GETDATE()), DATEDIFF(DAY, STR(YEAR(GETDATE()), 4) + '0101',
GETDATE() ) + 1,  ROW_NUMBER() OVER(ORDER BY id DESC)) UniqueID
FROM supportContacts s

如果每天只运行一次查询,这将有效。如果你每天运行它不止一次,你需要抓取秒或其他东西(SQL Fiddle):

SELECT CONCAT(CurrYear, CurrJulian, CurrSeconds, Row) AS UniqueID
FROM
(
  SELECT
  YEAR(GETDATE()) AS CurrYear, 
  DATEDIFF(DAY, STR(YEAR(GETDATE()), 4) + '0101', GETDATE() ) + 1 AS CurrJulian,  
  ROW_NUMBER() OVER(ORDER BY id DESC) AS Row,
  datediff(second, left(convert(varchar(20), getdate(), 126), 10), getdate()) AS CurrSeconds
  from supportContacts s
) AS m