我在SaaS工作,任何租户都可以拥有多个联系人列表,每个列表可以有任意数量的自定义字段,此列表的联系人可以存储,列表中的任何数量的组可以包含(使用组)用于分割列表的联系人).每个联系人都有一个必填字段:email_address和为我所提到的列表定义的任意数量的用户定义字段.我们必须能够根据它们所在的组以及用户定义值的值来查找列表的联系人.我们必须提供最多30个用户定义的字段.我现在看到解决这个问题的三种方法:
使用一种EAV(我们尝试这样做),但它看起来相当复杂.我们有一个表列表(租户列表),相关表custom_fields,存储列表订阅者的email_addreses的相关表订阅者,与订阅者和custom_fields表相关的表subscriber_custom_data(订阅者的自定义字段的存储值) .
字段表模式.它的描述在http://blog.springsource.com/arjen/archives/2008/01/24/storing-custom-fields-in-the-database/.在这种情况下,我们将使用与自定义字段相关的字段,该字段将在列中存储所有自定义字段,例如,具有30列以存储每个可能的自定义字段的值,以及存储列的名称和用户名称的映射的表领域.它看起来也很复杂.我们必须至少有30个索引才能按自定义字段的值进行搜索,还有其他问题,
使用某种NoSQL数据库至少用于存储用户定义的字段以及列表的组.您是否认为此类数据库可以在此处提供帮助,如果可以,则如何设计用于存储自定义字段和组.我试着看看不同类型的NoSQL,例如面向文档的MongoDb,但是我立刻看不出它如何帮助解决这个问题.我们可以在这里存储任意属性,但是为了搜索我们需要提前索引它们的自定义字段的值,所以我们必须知道我们将拥有哪些自定义字段.
感谢您提供有关它的任何信息.
如果您希望始终为所有字段编制索引,请尝试使用Apache Solr等技术对所有字段进行索引.Solr的主要目的是成为一个全文搜索引擎,但它基本上是一个面向文档的数据库.
以下是有关其他选项的评论:
EAV不好,我反对使用它.它打破了关系数据库设计的许多规则,并且它不会扩展.我已经在Stack Overflow上写了很多,所以在标签下搜索我的答案eav
.
您不需要仅30个索引 - 您需要最多30个因子索引来处理任何可能的索引组合.请记住,您可以创建多列索引,这些类型的索引对于支持某些查询很重要.当然,创建这么多索引是完全不切实际的; 您需要创建索引以匹配要优化的查询.如果您不知道您将拥有哪些字段以及您将对它们提出哪些疑问,则无法进行优化.
像MongoDB/CouchDB这样的面向文档的数据库并不神奇,无论他们的拥护者试图声称他们是多少.它们要求您为快速搜索索引文档,这意味着您需要知道文档的可索引字段.
在运行时创建索引是一个问题,因为它可能需要很长时间,具体取决于索引的数据量.您必须找到一种方法来"脱机"运行索引创建(即,不要让用户在单个http请求期间等待它),然后在完成时通知它们.
您应该阅读有关FriendFeed如何使用MySQL存储无模式数据的信息.它们使用序列化LOB,基本上将所有自定义属性组合到一个XML或JSON blob中.因此,用户可以随时创建任意数量的其他自定义字段.但是,在可以搜索给定的自定义字段之前,您将创建一个子表,该子表引用该字段包含给定值的行.因此,您获得的索引仅与给定用户定义的自定义字段的实例数一样大.而且您不需要使每个字段都可搜索.