nhibernate - 如何使用 Fluent NHibernate 创建聚集索引?

标签 nhibernate fluent-nhibernate automapping clustered-index

我正在使用 Fluent-NHibernate(带有自动映射)来生成我的表,但我想选择与默认使用的 ID 字段不同的聚集索引。如何使用 Fluent NHibernate 在默认主键字段以外的字段上创建聚集索引?

这背后的主要原因很简单。我将 Guids 用于我的主键字段。默认情况下,NHibernate 在主键字段上创建聚集索引。由于 Guid 通常不是顺序的,因此在主键字段上进行聚类会导致性能问题。

众所周知,在表的末尾追加记录比在表中插入记录要便宜得多。此外,表中的记录在物理上按照聚集索引中的项目顺序存储。由于 Guid 在某种程度上是“随机的”并且不是连续的,因此可能会生成小于表中已有的其他 Id Guid 值的新 Guid - 导致表插入而不是追加。

为了尽量减少这种情况,我有一个名为 CreatedOn 的列,它的类型为 DateTime。我需要将表聚集在 CreatedOn 列上,以便追加而不是插入所有新记录。

欢迎任何关于如何实现这一点的想法!!!

注意:我意识到我可以使用 Sequential Guid,但出于安全原因,我不想走这条路。


注意:我仍然没有对这篇文章的答案,但我目前正在思考一些想法。

  1. 在没有 Fluent 的情况下使用 NHibernate,我认为可以直接在 NHibernate 中创建聚集索引。我对 NHibernate 的了解还不够,不知道如何做到这一点。我只是很漂亮(几乎绝对)确信可以做到。

  2. Fluent-NHibernate 曾经包含一种在最近重写之前在 SQL 对象上设置属性(例如,像聚集索引)的方法。现在这个选项似乎已经消失了。我可能会在某处发布一个问题,看看该选项是否仍然可用。如果是这样,我可能会用它来设置聚集索引。

  3. Fluent-NHibernate 能够在流畅构建后公开配置以进行手动编辑。我没有尝试过此功能,但希望它可以提供设置聚集索引所需的粒度级别。

  4. 在最坏的情况下,我可以编写一个 SQL 脚本来更改我所有表上的聚簇索引,一旦它们生成。但是,我对这种方法有几个问题。 A. 由于我使用自动模式生成,NHibernate 会在下次评估配置时“撤消”我的聚集索引更改吗? 2. NHibernate 检测到聚集索引被改变了会报错吗?我需要对此进行测试,但还没有这样做。我真的很讨厌这个解决方案。我正在针对 SQLServer2008 和 MySQL 测试我的数据库。 NHibernate 的部分优点在于它与数据库无关。一旦我们引入脚本,所有的赌注都没有了。

  5. 在流畅的约定中使用了一个名为 IPropertyInstance 的接口(interface),从该接口(interface)继承的类有一个 Index 属性,允许在字段上创建索引。问题是没有标志或其他选项允许将索引创建为聚集索引。最简单的解决方案是向此方法添加一个属性以允许创建聚集索引。我想我可能会向 Fluent-NHibernate 开发人员建议这个。

最佳答案

这是一个旧帖子,但我希望可以帮助其他人。这来 self 在 MS SQL Server 上的经验。我相信不同的平台需要不同的解决方案,但这应该是一个很好的起点。

NHibernate 不会在主键上设置 CLUSTERED 索引。这是 SQL Server 的默认行为。由于每个表只能有一个 CLUSTERED,我们首先需要避免在主键上创建 CLUSTERED。

我发现完成此操作的唯一方法是创建自定义方言,覆盖属性 PrimaryKeyString。 NHibernate的默认来自Dialect.cs:

    public virtual string PrimaryKeyString
    {
        get { return "primary key"; }
    }

对于 SQL Server

    public override string PrimaryKeyString
    {
        get { return "primary key nonclustered"; }
    }

这将强制 SQL Server 创建一个非集群主键。 现在您可以通过 XML 映射文件中的标记在您喜欢的列上添加自己的 CLUSTERED 索引。

<database-object>
  <create>
    create clustered index IX_CustomClusteredIndexName on TableName (ColumnName ASC)
  </create>
  <drop>
    drop index IX_CustomClusteredIndexName ON TableName
  </drop>
</database-object>

关于nhibernate - 如何使用 Fluent NHibernate 创建聚集索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1356467/

相关文章:

nhibernate - NHibernate 可以使用的只读集合属性

nhibernate - 即使使用持久的配置优化,Fluent nHibernate 启动仍然很慢

nhibernate - 如何将 Fluent NHibernate Automapping 与实体中的多个相同类型的列表一起使用?

nhibernate - 如何使用 Fluent NHibernate 自动映射一组组件?

configuration - 如何使用 Fluent NHibernate 自动映射来映射字典?

wcf - 3 层 nhibernate + wcf + Silverlight

mysql - 无法从 NHibernate.Driver.MySqlDataDriver 创建驱动程序

sql - NHibernate 是否支持从 SQL View 映射?

c# - 将 CaSTLe ActiveRecord 与 Fluent NHibernate 结合使用?

linq - Nhibernate 为 fetch 生成 OUTER JOIN