我正在设计一个相当复杂的系统。我们主要关心的问题之一是支持 SQL Server 点对点复制。这个想法是支持多个地理上分离的节点。
第二个问题是在中间层使用现代 ORM。我们的首选一直是实体框架,主要是因为开发人员喜欢使用它。 (他们喜欢 LiNQ 支持。)
所以问题是这样的:
考虑到对等复制,我决定使用 uniqueidentifier 和默认值 newsequentialid() 作为每个表的主键。这似乎在避免键冲突和减少索引碎片之间提供了良好的平衡。
然而,事实证明当前版本的实体框架有一个非常奇怪的限制 http://blogs.msdn.com/dsimmons/pages/ef-faq-entity-services.aspx#Section_17:如果实体的键列是唯一标识符 (GUID),则无法将其配置为使用数据库提供的默认值 (newsequentialid())。应用程序层必须生成 GUID 并填充键值。
所以这是辩论:
- abandon Entity Framework and use another ORM:
- 使用 NHibernate 并放弃 LiNQ 支持
- 使用 linq2sql 并放弃未来的支持(更不用说在 DB 上绑定到 SQL Server)
- 放弃GUID并采用另一种PK策略
- 设计一种在应用层生成顺序 GUID(COMB?)的方法
我倾向于使用 linq2sql 的选项 1(我的开发人员非常喜欢 linq2[stuff])和选项 3。这主要是因为我对支持我们目标的复制方案同时保持理智的备用关键策略有些无知。开发者的视角。
任何见解或意见将不胜感激。
我赞同克雷格的建议——选项 4。
您始终可以使用由中间层填充的 GUID 列作为主键(这是一个逻辑构造)。
为了避免大量索引(因此:表)碎片,请使用其他一些键(最好是 INT IDENTITY 列)作为 CLUSTERING KEY - 这是一个物理数据库构造,可以与主键分开。
默认情况下,主键是集群键 - 但不一定如此。事实上,我通过在我“继承”的数据库上执行此操作,提高了性能并大大降低了碎片 - 添加一个 INT IDENTITY 列并将集群键放在那个小的、不断增加的、永不改变的 INT 上 - 效果非常好!
Marc
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)