0

根据特定订阅限制帐户的最佳方法是什么?例如,我的Basic计划可能允许订阅者最多创建 2 个用户帐户并拥有最多 50 个客户;高级计划可能允许 10 个用户和 200 个客户。

我能想到的唯一方法是创建一个subscription_plans定义限制的表,例如:

id descriptionmonthly_price max_users max_customers
1 基本 40.00 2 50
2 保费 60.00 2 200

并使用某种连接表将这些与帐户相关联。这听起来不是最好的方法,因为我必须经常查询用户/客户/其他的数量(可能在每个页面上,尽管我想我可以使用缓存)所以我可以警告用户是否接近他们的限制。如果用户需要升级,我还需要一种简单的方法让用户“自助服务”他们的帐户。我计划让第三方服务处理实际的订阅管理和定期计费。

有没有更好的方法来处理这个?

4

1 回答 1

3

用户帐户数据库是实体-属性-值 (EAV) 模式的完美候选者!
它通常足够小(无需担心一个 EAV 的弱点,即性能/缩放),并且用户帐户配置通常是包装和规则永无止境的变化的主题。替代方案
可以是对象数据库,由此 下面描述的模型的对象实例“休眠”到存储。后一种方法的缺点是可能更难以将帐户数据库作为一个整体来使用。当然,一个糟糕的选择将是一个真正的关系模式(如问题中所暗示的那样),其记录更不直接暴露于应用程序级别。

简而言之 EAV
数据是“垂直”存储的,而不是“水平”存储的。在问题示例中,对于客户 ID 1,我们在值表中有 4 条记录,分别用于描述、montly_price、max_users 和 max_customers。当我们需要更多属性(例如,一个旨在提供对高级/高级功能的访问的属性)时,其中一些可能具有多个值,我们只需在属性表中定义它们,并在同一个表中添加值记录。

更详细地说:
数据库结构通常由 3 个表组成:

  • tblEntity(在此称为 TblAccount),每个实体(帐户)有一个恰好一行。它包含给定帐户的通用信息:AccountId、Name、可能是 Login/pawsord、可能是到期日期,但通常很少。
  • tblAttribute 它保存了一个属性的定义:一个AttributeId,一个Name,一个Type
  • tblValues 如前所述,每个属性值都有一个记录分配给特定实体(帐户)

与程序逻辑相结合
通常我们引入一个对象模型,其中一个帐户只不过是几个“标题”属性(Id,名称),并且各种属性存储在哈希(字典)的键值对中。这些对象或一些实用方法提供了一个层,通过该层处理有关帐户的所有查询和操作,例如:
- bool CanUserAccess(FeatureName); // 评估与 FeatureName 关联的规则(通常是对该帐户的存在和/或属性值的一系列测试),如果帐户可以先验访问所述功能,则返回 true(另一层可能会在给定时间阻止此类访问, 因为并发用户数或其他...)
- int TakeLicenseFor(FeatureName);
- ETC。

这通常涵盖了它。许多细节仍有待深入,但上面提出的暂定架构提供了拼图各个元素的整体松散耦合

  • 数据库可以立即接受新的属性,无需更改 SQL 的架构,仅更改应用程序级架构(主要是属性表)
  • 数据库用于在登录时加载代表帐户的对象
  • 应用程序使用符号名称(字符串)来指定应用程序的功能(如果您愿意,可以分段)并通过业务规则层查询底层帐户的此类功能的可用性(允许帐户属性和特征:在不改变账户的情况下,可以添加或删除一些特征,如果它们可以映射到一个或多个账户属性。

有了2层绝缘,即使数据库的物理布局发生变化,或者某些业务规则来来去去,应用程序也不会受到困扰。应用程序中当然有一个关联:对这些“功能字符串”的引用,但这些引用通常可以放在脚本中的较高位置(早期),从而允许在应用程序的页面/功能之间进行非常可见且易于更改的映射以及描述的账户管理逻辑。

于 2009-11-20T02:51:05.153 回答