AID*_*SEY 7 sql-server partitioning guid multi-tenant
我在设计一个需要在未来进行水平分区的多租户数据库模式时,试图找出最佳方法.
数据库上的一些粗糙数字..
租户总数约为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,id,description 100,1,'foo'200,1,'xxx'100,2,'boo'200,2,'yyy'
数据库1数据库2 tenantid,id,description tenantid,id,description 100,{aaa},'foo'200,{ccc},'xxx'100,{bbb},'boo'200,{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因为聚类键不是最佳的,因为由于其随机性,它将导致大量页面和索引碎片以及通常不良的性能.
是的,我知道 - newsequentialid()在SQL Server 2005及更高版本中 - 但即使这样也不是真正的,完全顺序的,因此也会遇到与GUID相同的问题 - 只是不那么突出.
然后还有另一个需要考虑的问题:表格上的聚类键也会添加到表格中每个非聚集索引的每个条目上 - 因此,您确实希望确保它尽可能小.通常,对于绝大多数表来说,具有2亿行的INT应该足够了 - 并且与作为群集密钥的GUID相比,您可以在磁盘和服务器内存中节省数百兆字节的存储空间.
快速计算 - 使用INT与GUID作为主要和群集密钥:
总计:25 MB对106 MB - 这只是在一张桌子上!
还有一些值得思考的东西 - 金伯利·特里普的优秀作品 - 阅读,再读一遍,消化它!这是SQL Server索引福音,真的.
渣
| 归档时间: |
|
| 查看次数: |
2508 次 |
| 最近记录: |