【问题标题】:Migrate from NHibernate ids (hilo) to SQL auto ids in SQL Server从 NHibernate ids (hilo) 迁移到 SQL Server 中的 SQL auto ids
【发布时间】:2021-10-16 10:33:32
【问题描述】:

有没有办法迁移包含所有表和关系的现有数据库以使用 SQL Server 自动 ID 而不是 Nhibernate (hilo) ID?

我们有一个使用 NHibernate 的 .NET 应用程序。但问题是,我们的int 用完了。

我知道这需要使用 id 设置为自动递增的新表重新创建表。有没有简单的迁移方法。例如,某种查询将复制表、保持关系,但现在使用 SQL Server id 而不是 hilo id。 hilo的最大问题,它使用共享ids,这使情况变得更糟。

例如,我们有一个包含 3 个表的数据库:

  • dbo.Users
  • dbo.RegistrationResults
  • dbo.UserNotes

表格:

dbo.Users

  • Id int(主要)
  • Emailnvarchar(255)
  • RegistrationResultFk int(外键)

dbo.RegistrationResults

  • Id int(主要)
  • ValidationOutcomenvarchar(255)

dbo.UserNotes

  • Id int(主要)
  • Messagenvarchar(255)
  • RegistrationResultFk int(外键)

数据填充如下:

dbo.Users

Id Email RegistrationResultFk
1 test@gmail.com 2
4 test2@gmail.com 5

dbo.RegistrationResults

Id ValidationOutcome
2 Awaiting confirmation
5 Confirmed

dbo.UserNotes

Id Message RegistrationResultFk
3 it's a test 2
6 it's a test 2 5

我们希望迁移后的数据如下所示:

dbo.Users

Id Email RegistrationResultFk
1 test@gmail.com 1
2 test2@gmail.com 2

dbo.RegistrationResults

Id ValidationOutcome
1 Awaiting confirmation
2 Confirmed

dbo.UserNotes

Id Message RegistrationResultFk
1 it's a test 1
2 it's a test 2 2

【问题讨论】:

  • 免责声明:我不太了解 NHibernate 的 HiLo,据我所知,NHibernate 管理和获取表的 id 的某种表。如果您检查 SQL Server 表,则每个表都有一列作为 Id INT(或 BIGINT),对吗?
  • 您的意思是要更改数据库中现有id 的值以消除由nhibernate 创建的“间隙”,并为您提供更多空间仍然使用int 数据类型,并更新所有使用这些值的外键?或者您是否可以接受将 id 数据类型从 int 更改为 bigint identity 列(其中数据类型更改会影响客户端应用程序,但在数据库端更容易做到)?
  • 最大,是的,每个表都有intid。但是这个int 在表之间共享。例如。我有桌子dbo.users。它有一行,ID 为 1。我还有另一个名为 dbo.permissions 的表,它以 id 2 开头。它是,因为 hilo 使用共享的 id。所以这就是为什么它非常可怕。因为我们有 20 多个使用共享 id 的表,而且增长速度非常快。
  • 这是一件非常难以自动化和完全正确的事情,仅适用于一个 ID 列(及其引用的列和表),它是 FK 和它的触发器,以及任何 View、sProcs 和/或引用该列的函数。为整个数据库做这件事是一项了不起的工作,专业的 DBA/顾问需要花费数周的时间来计划、编写脚本和准备,甚至需要工具来协助。在我的职业生涯中,我曾多次这样做,如果涉及 FK,仅验证该过程可能需要一周时间。
  • This article 描述了一位专业 DBA 仅仅为了更改 one 表的 ID 所经历的过程。我自己也会遵循同样的过程。对于整个数据库,这将被视为主要数据库运营项目。

标签: c# .net sql-server nhibernate


【解决方案1】:

我建议你,为了尽量减少影响,使用Sequences,它相当于自动增量字段,但存储在表之外。

下面是一个简单的表格示例

创建序列

此代码创建一个序列。
使用 SSMS,您还可以导航到数据库 -> 可编程性 -> 序列 ==> 右键单击新建序列。

Full Syntax.

CREATE SEQUENCE dbo.UserId 
    AS INT
    START WITH 1234 
    INCREMENT BY 1   
    ;  

仔细阅读语法以更好地设置序列,例如,您可能希望设置 CACHE 以提高性能,最大限度地减少生成序列号所需的 IO

获取身份证

要获取 ID,您必须使用 NHibernate 发出原始查询。
NHibarnate Reference
NEXT VALUE

public int GetNextUserId(Session session)
{
    var query = session.CreateSQLQuery("SELECT NEXT VALUE FOR dbo.UserId");
    var result = query.UniqueResult();
    return Convert.ToInt32(result);
}

【讨论】:

  • 感谢 Max 的回答。当我可以使用我的工作笔记本电脑时,我会试试这个。如果它到期,我将重新调用赏金。另外,我用示例更新了问题,这可能有助于更清楚地理解问题
  • @3lvinaz 我阅读了更新我相信我的解决方案适合您的情况。
  • 需要明确的是,虽然此答案可以用于解决重新排序的答案,但此答案本身并不解决重新排序请求。它甚至也没有解决重新创建表和外键的自动化问题。
猜你喜欢
  • 2012-09-04
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-17
  • 2011-06-17
  • 2014-05-24
相关资源
最近更新 更多