我正在使用 Fluent-NHibernate(带有自动映射)来生成我的表,但想选择与默认使用的 ID 字段不同的聚集索引。如何使用 Fluent NHibernate 在默认主键字段以外的字段上创建聚集索引?
这背后的主要原因很简单。我将 Guids 用于我的主键字段。默认情况下,NHibernate 在主键字段上创建聚集索引。由于 Guid 通常不是顺序的,因此在主键字段上进行聚类会导致性能问题。
众所周知,在表的末尾追加记录比在表中插入记录要便宜得多。此外,表中的记录在物理上按照聚集索引中的项目顺序存储。由于 Guid 在某种程度上是“随机的”并且不是连续的,因此可能会生成小于表中已经存在的其他 Id Guid 的值的新 Guid - 导致表插入而不是追加。
为了尽量减少这种情况,我有一个名为 CreatedOn 的列,它的类型为 DateTime。我需要将表聚集在这个 CreatedOn 列上,以便附加而不是插入所有新记录。
欢迎任何关于如何实现这一点的想法!!!
注意:我意识到我可以使用 Sequential Guid,但出于安全原因,我不想走这条路。
注意:我仍然没有对这篇文章的答案,但我目前正在思考一些想法。
在没有 Fluent 的情况下使用 NHibernate,我认为可以直接在 NHibernate 中创建聚集索引。我对 NHibernate 的了解还不够,不知道如何做到这一点。我只是很漂亮(几乎绝对)确信它可以完成。
Fluent-NHibernate 曾经包含一种在最近重写之前在 SQL 对象上设置属性(例如,聚集索引)的方法。现在这个选项似乎已经消失了。我可能会在某处发布一个问题,看看该选项是否仍然可用。如果是这样,我可能会使用它来设置聚集索引。
Fluent-NHibernate 提供了在流畅构建后公开配置以进行手动编辑的能力。我没有尝试过这个功能,但希望它可以提供设置聚集索引所需的粒度级别。
最坏的情况是,我可以编写一个 SQL 脚本来更改所有表上的聚簇索引,一旦它们生成。但是,我对这种方法有几个问题。A. 由于我使用自动模式生成,NHibernate 会在下次评估配置时“撤消”我的聚集索引更改吗?2. NHibernate 检测到聚集索引被改变了会报错吗?我需要对此进行测试,但还没有这样做。我真的很讨厌这个解决方案。我正在针对 SQLServer2008 和 MySQL 测试我的数据库。NHibernate 的部分优点在于它与数据库无关。一旦我们引入脚本,所有的赌注都没有了。
有一个在称为 IPropertyInstance 的流式约定中使用的接口,从该接口继承的类具有一个 Index 属性,该属性允许在该字段上创建索引。问题是没有标志或其他选项允许将索引创建为聚集索引。最简单的解决方案是向此方法添加一个属性以允许创建聚集索引。我想我可能会向 Fluent-NHibernate 开发人员建议这个。