根据特定订阅限制帐户的最佳方法是什么?例如,我的基本计划可能允许订阅者最多创建2个用户帐户,最多可拥有50个客户; 高级计划可能允许10个用户和200个客户。
我能想到的唯一方法就是创建一个定义限制的subscription_plans
表,例如:
id description monthly_price max_users max_customers 1 Basic 40.00 2 50 2 Premium 60.00 2 200
并使用某种联接表将这些与帐户相关联。这听起来不是最好的方式,因为我经常需要查询用户/客户/任何人的数量(可能在每个页面上,虽然我想我可以使用缓存)所以我可以警告用户他们是否接近他们的限制。此外,如果需要升级,我还需要一种简单的方法让用户“自助服务”他们的帐户。我计划让第三方服务处理实际的订阅管理和定期计费。
有没有更好的方法来解决这个问题?
答案 0 :(得分:3)
用户帐户数据库是实体 - 属性 - 值(EAV)架构的完美候选者!
它通常足够小(不关心一个EAV的弱点,即性能/缩放),用户帐户配置通常是包装和规则永无止境变化的主题。
替代可以是对象数据库,其中下面描述的模型的对象实例被“休眠”到存储。后一种方法的缺点是,整个账户数据库的使用可能会更加困难
当然,一个糟糕的选择将是一个真正的关系模式(正如问题中暗示的那样),其记录更不直接暴露于应用程序级别。
简称EAV
数据“垂直”而不是“水平”存储。在问题的示例中,对于客户ID 1,我们在值表中有4条记录,每条记录用于描述,montly_price,max_users和max_customers。如果我们需要更多属性(例如,一个旨在提供对高级/高级功能的访问),其中一些可能具有多个值,我们只需在属性表中定义它们,并在同一个表中添加值记录。 / p>
更多细节:
数据库结构通常由3个表组成:
使用程序逻辑:
通常我们引入一个对象模型,其中一个帐户只是几个“标题”属性(Id,name),并且各种属性存储在散列(字典)的键值对中。这些对象或一些实用方法提供一个层,通过该层可以处理有关帐户的所有查询和操作,例如:
- bool CanUserAccess(FeatureName); //评估与FeatureName关联的规则(通常是对该帐户的属性的存在和/或值的一系列测试),如果帐户可以先验地访问所述特征,则返回true(另一层可能在给定时间阻止此类访问) ,因为并发数量的用户或其他...)
- int TakeLicenseFor(FeatureName);
- 等等。
这通常涵盖了它。许多细节仍有待解决,但上面提出的试验性架构提供了整个拼图的各种元素的松散耦合:
通过2层绝缘,即使数据库的物理布局发生变化或者某些业务规则来来去去,应用程序也不会受到困扰。当然在应用程序中有一个搭配:对这些“特征字符串”的引用,但这些引用通常可以放在脚本中(早期),允许在应用程序的页面/功能之间进行非常明显且易于更改的映射和描述的帐户管理逻辑。