sql-server – SQL Server – 基于GUID的PK是支持基于租户的水平分区的最佳实践

前端之家收集整理的这篇文章主要介绍了sql-server – SQL Server – 基于GUID的PK是支持基于租户的水平分区的最佳实践前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在设计一个需要在未来进行水平分区的多租户数据库模式时,试图找出最佳方法.

数据库上的一些粗糙数字..

租户总数约为10,000.每个租户存储的数据量在500MB之间变化 – > 3GB.租户的数量将从小开始,并在几年内增长到10,000,所以最初我们可以从单个多租户数据库开始,但从长远来看,这需要横向扩展以提高性能
原因.

更新 – 一个复杂的因素是偶尔租户(公司)可以合并在一起,我也需要支持这个…,

多租户将使用共享数据库,共享模式体系结构实现,如本文http://msdn.microsoft.com/en-us/library/aa479086.aspx中所述

鉴于我们将来会面临水平分区,并且很可能我们会在客户安定下来之前将客户端从一个数据库移动到另一个数据库几次,我认为最好将GUID用作每个表的主键以及唯一的tenantID列.

我知道使用GUID作为主键存在性能开销,但这是我需要接受的权衡吗?还有另一种设计水平分区的方法吗?

下面是一个例子 – 让我说我想在未来将公司与租户100和200合并,
如果PK是一个整数,当我将数据库2中的行复制到数据库1时可能会发生冲突,{guids}我保证不会发生碰撞……

数据库1数据库2
tenantid,id,description tenantid,description
100,1,’foo’200,’xxx’
100,2,’boo’200,’yyy’

数据库1数据库2
tenantid,{aaa},{ccc},{bbb},{ddd},’yyy’

解决方法

GUID似乎是您主键的自然选择 – 如果您真的必须,您可能会争辩将其用于表的PRIMARY KEY.我强烈建议不要使用GUID列作为群集密钥,默认情况下sql Server会执行此操作,除非您明确告知不要这样做.

你真的需要分开两个问题:

1)主键是一个逻辑结构 – 一个候选键,它唯一且可靠地标识表中的每一行.这可以是任何东西,真的 – 一个INT,一个GUID,一个字符串 – 选择对你的场景最有意义的东西.

2)聚类键(在表上定义“聚簇索引”的一列或多列) – 这是一个与物理存储相关的东西,这里,一个小的,稳定的,不断增加的数据类型是你最好的选择 – INT或BIGINT作为默认选项.

默认情况下,sql Server表上的主键也用作群集键 – 但不一定是这样!我个人看到将以前基于GUID的主/群集密钥分解为两个单独的密钥 – GUID上的主(逻辑)密钥以及单独的INT IDENTITY上的群集(排序)密钥(1,1)专栏.

正如Kimberly Tripp – 索引女王 – 以及其他人已多次说过 – GUID因为聚类键不是最佳的,因为由于其随机性,它将导致大量页面和索引碎片以及通常不良的性能.

是的,我知道 – 在sql Server 2005及更高版本中有newsequentialid() – 但即使这样也不是真正的,完全顺序的,因此也会遇到与GUID相同的问题 – 只是不那么突出.

然后还有另一个需要考虑的问题:表格上的聚类键也会添加到表格中每个非聚集索引的每个条目上 – 因此您确实希望确保它尽可能小.通常,具有20亿行的INT应该足以用于绝大多数表 – 并且与作为群集密钥的GUID相比,您可以在磁盘和服务器内存中节省数百兆字节的存储空间.

快速计算 – 使用INT与GUID作为主要和群集密钥:

>基准表,1’000’000行(3.8 MB对15.26 MB)
> 6个非聚簇索引(22.89 MB对91.55 MB)

总计:25 MB对106 MB – 这只是在一张桌子上!

还有一些值得深思的东西 – 金佰利特里普的优秀作品 – 阅读,再读一遍,消化它!这是sql Server索引福音,真的.

> GUIDs as PRIMARY KEY and/or clustered key
> The clustered index debate continues
> Ever-increasing clustering key – the Clustered Index Debate……….again!
> Disk space is cheap – that’s not the point!

猜你在找的MsSQL相关文章