Postgresql 关于我的数据库设计的反馈(多租户)
SaaS工具的思想是拥有具有动态自定义字段和不同类型值的动态表,我们曾考虑使用“force.com/salesforce.com”示例,但它似乎过于复杂,无法继续前进,还需要创建一些具有巨大抽象级别的报告,所以我们提出了一个简单的想法,但我们必须确保这是一个不错的方法 这就是我们今天的架构(只需几个步骤)Postgresql 关于我的数据库设计的反馈(多租户),postgresql,database-design,rdbms,multi-tenant,saas,Postgresql,Database Design,Rdbms,Multi Tenant,Saas,SaaS工具的思想是拥有具有动态自定义字段和不同类型值的动态表,我们曾考虑使用“force.com/salesforce.com”示例,但它似乎过于复杂,无法继续前进,还需要创建一些具有巨大抽象级别的报告,所以我们提出了一个简单的想法,但我们必须确保这是一个不错的方法 这就是我们今天的架构(只需几个步骤) 每个租户在集群上都有自己的独立数据库(Postgres 12) TABLE TABLE,用于保留所有这些表作为引用,该实体与元表有多个关系,与数据表有多个关系 元表用于元数据配置,与字段有一对
TEXT/INTEGER/BOOLEAN/DATETIME
等,属性值-作为字符串,仅作为参考)50个字符变化的
列有多个关系,这些列的名称为:attribute1…50
,可以为空品牌、类别、年份、价格
列品牌=属性2,类别=属性5,年份=属性6和价格=属性7
SELECT[attr…2,5,6,7]FROM DATA
,然后向用户显示结果,如果用户决定对其进行一些筛选,则基于此数据,例如Year>2017和Class='a'
我们使用CAST()
SQL的功能,例如选择CAST(attribute6 AS int)和attribute5来自数据,其中CAST(attribute6为int)>2017,attribute5='A'代码>,这样我们就可以真正支持SQL的大多数原则
- 为更多租户管理这样的环境,同时我们将拥有更多的表
5 mil是我们允许的最大值,对于更大的数据,我们有BigQuery(例如,每个客户50个,每个表大约1-5 mil(
,这可能会影响查询的性能,特别是当我们提供了使用一些抽象语言管理简单WHERE语句(less、equal、null等)的可能性时,例如),这将在单个表数据中为我们提供50-250 mil行)
开发为类似于JQL(Jira查询语言)GET CARS[BRAND、CLASS、PRICE…]FILTER[EQ(CLASS、A)、MT(YEAR,2017)]
- 事务锁定,因为我们允许将CSV批量上传到
,所以一旦他们想要加载例如1GB的数据,它就有点锁定表,以便其他系统访问数据表数据_X
- 保留多个空列,这会稍微影响空间(因为现在我们不像创建表时那样害怕,客户可以决定他想要多少列,因此基于这一点,我们将此表分配给硬编码实体
,其中数字对应于属性列的限制,并且这些实体不同,我们将lso支持迁移选项,如果他们决定从5个属性切换到10个属性等DATA_5、DATA_10、DATA_15、DATA_20、DATA_30、DATA_50
如果它看起来不好,那么根据我共享的详细信息(基本上是无模式的RDBMS),您会推荐什么作为此解决方案的替代方案呢?IMHO,当您想要连接表和使用cast等时,我预计会出现问题 我们遵循了下面的方法,这将对您有所帮助 我们有一个名为
Cars
的表,还有两个类似CarsMeta
,CarsExtension
列的表。基础Cars
表将包含所有租户的公共字段。此外,我们还将让CarsMeta
表指出您可以为ex使用的列的类型处理Cars
实体。在CarsExtension
表中,您将有StringCol1…5、IntCol1…5、LongCol1…10等列
通过这种方式,您可以轻松地筛选数据,如
- 如果基础表上有一个筛选器,则执行搜索,如果找到结果,则将ID与
表匹配,以获取此实体的已执行行列表CarsExtension
- 如果过滤器位于扩展字段上,则在扩展表上进行搜索,并与基本实体ID的搜索相匹配
- 因为我们将有如下组织的扩展表 id-唯一id entityid-唯一ID(指向实体的主键) StringCol1-string IntCol1-int,
HTH感谢您的反馈,如果我理解正确,我们将有“Cars”表,其中包含一些常见数据,如Premium Ca