Nhibernate id 具有连续一步递增的 id(HiLo 的替代品)
Posted
技术标签:
【中文标题】Nhibernate id 具有连续一步递增的 id(HiLo 的替代品)【英文标题】:Nhibernate id’s with sequential one step incremented id’s (alternatives to HiLo) 【发布时间】:2010-05-20 11:40:09 【问题描述】:如何指示 Nhibernate 生成顺序的一步主键,就像 sql 生成的主键一样?
当前的 HiLo 算法会生成 4001、5010、6089 等密钥。我知道这是为了管理多个应用服务器等。但我没有这个问题。 我需要 nhibernate 在启动期间获取最高记录集值(比如 15),然后使用主键 16 生成下一条记录(非常类似于从 sql 端生成的 id)。
【问题讨论】:
为什么不使用 db 生成的 id? @Mattias fabiomaulo.blogspot.com/2009/02/… 我没有阅读整篇文章,所以如果我错过了重点,我很抱歉。但是使用 hilo 的常见原因是为了减少网络流量。如果你确实想要你的 id,那么无论如何你每次都必须去 db,所以使用它而不是 db 生成的 id 没有任何意义。可以用 hilo 来完成(只需将 maxlo 设置为 0)。但这没有任何意义,因为您将获得大量流量。问题不在于多个应用程序使用相同的数据库。它是多个用户使用同一个应用程序。如果你我都试图同时保存一些东西,那么我们就会发生冲突。 @Mattias 没有一个生成器,它在启动期间拉起最大值一次,然后在内存中保持最大值,每次分配发生时递增它。 是的,但它只保留与您设置的 maxlo 一样多的 id。因此,如果您将其设置为 0,它将仅保留 1 个 id,并在您需要更多时立即转到数据库。这就是为什么当你使用 hilo 时你会得到非连续的 id,因为你保留了一些 id,但你只使用了其中的几个。它不能在内存中增加,也不能保存到数据库中,因为当有多个用户时,这将意味着麻烦。 【参考方案1】:您为什么需要/期望 NHibernate 为您执行此操作?
NHibernate 很难为这样的场景提供通用解决方案,因为需求可能会略有不同,但是由于您完全了解自己的特定限制,因此您应该相对直接地提供自己的解决方案(使用手动分配的 ID)。
在应用程序启动时,查询数据库并获取当前最大 id 值。每次插入时增加该值。
【讨论】:
@Quintin - 那篇博文并没有真正告诉我任何我不知道的事情。我不确定您为什么选择它作为对我的回答的评论?【参考方案2】:创建表:
CREATE TABLE `seq` (
`ID` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`HI` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `seq` VALUES ('COMMENT', '0');
INSERT INTO `seq` VALUES ('POST', '0');
INSERT INTO `seq` VALUES ('USER', '0');
使用 FluentNHbiernate 添加这样的映射:
public class Comment_Map : ClassMap<Comment>
public Comment_Map()
Table("COMMENT");
Id(x => x.ID, "ID").GeneratedBy.HiLo("SEQ", "HI", "0", o => o.AddParam("where", "ID = 'COMMENT'"));
【讨论】:
@dmonlord,将 maxLo 设置为 0 几乎消除了首先使用 hilo 的优势。这样你最终会得到大量的网络流量,你可能会更好地使用 db 生成的 id。 我知道,但这就是他想要的。如果您不想实现自己的生成器,可能没有任何好的替代方案。 @dmonlord,我知道别无选择。我只是指出,您使用 hilo(或任何客户端生成的 id)的原因是因为您想要更少的网络流量。使用您的解决方案,您最终会获得更多的网络流量。以上是关于Nhibernate id 具有连续一步递增的 id(HiLo 的替代品)的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Fluent-NHibernate 和 MySQL 指定自动递增 (int) 标识列