首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在关系数据库中存储智能列表规则

如何在关系数据库中存储智能列表规则
EN

Stack Overflow用户
提问于 2012-07-26 01:44:28
回答 2查看 319关注 0票数 3

我正在建立的系统有聪明的团队。所谓智能组,我指的是根据以下规则自动更新的组:

  1. 包括与给定客户端关联的所有人员。
  2. 包括所有与给定客户相关的人,他们都有这些职业。
  3. 包括一个特定的人(即按身份证)

每个智能组可以组合任意数量的这些规则。因此,例如,一个特定的智能列表可能具有以下特定规则:

  1. 包括所有与客户端1相关联的人员
  2. 包括所有与客户端5相关联的人员
  3. 包括人6
  4. 包括所有与客户10相关的人,以及从事2、6和9职业的人。

这些规则或组合在一起组成小组。我正在考虑如何最好地将这些规则存储在数据库中,因为除了支持这些规则之外,我希望将来能够在不太痛苦的情况下添加其他规则。

我想到的解决方案是为每种规则类型建立一个单独的模型。该模型上将有一个方法,返回一个查询集,该查询集可以与其他规则的查询集相结合,从而最终生成一个人员列表。我能看到的一个缺点是,每条规则都有自己的数据库表。我该担心这个吗?也许有更好的方法来存储这些信息?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-16 19:05:15

下面是我们为处理这个场景而实现的模型。

代码语言:javascript
复制
class ConsortiumRule(OrganizationModel):
    BY_EMPLOYEE = 1
    BY_CLIENT = 2
    BY_OCCUPATION = 3
    BY_CLASSIFICATION = 4
    TYPES = (
        (BY_EMPLOYEE, 'Include a specific employee'),
        (BY_CLIENT, 'Include all employees of a specific client'),
        (BY_OCCUPATION, 'Include all employees of a speciified  client ' + \
            'that have the specified occupation'),
        (BY_CLASSIFICATION, 'Include all employees of a specified client ' + \
            'that have the specified classifications'))

    consortium = models.ForeignKey(Consortium, related_name='rules')
    type = models.PositiveIntegerField(choices=TYPES, default=BY_CLIENT)
    negate_rule = models.BooleanField(default=False,
        help_text='Exclude people who match this rule')


class ConsortiumRuleParameter(OrganizationModel):
    """ example usage: two of these objects one with "occupation=5" one
    with "occupation=6" - both FK linked to a single Rule
    """

    rule = models.ForeignKey(ConsortiumRule, related_name='parameters')
    key = models.CharField(max_length=100, blank=False)
    value = models.CharField(max_length=100, blank=False)

起初,我不喜欢在CharField中存储对其他对象的引用(选择了CharField,因为它是最通用的),所以我不喜欢这个解决方案。稍后,我们可能会有一个规则,与任何名字以‘Jo’开头的人相匹配。但是,我认为这是将这种映射存储在关系数据库中的最佳解决方案。这是一种很好的方法,原因之一是它相对容易清除挂起的引用。例如,如果一家公司被删除,我们只需:

代码语言:javascript
复制
ConsortiumRuleParameter.objects.filter(key='company', value=str(pk)).delete()

如果参数存储为序列化对象(例如,注释中建议的Q对象),这将更加困难和耗时。

票数 0
EN

Stack Overflow用户

发布于 2013-01-15 10:03:43

为什么不使用Q对象

代码语言:javascript
复制
rule1 = Q(client = 1)
rule2 = Q(client = 5)
rule3 = Q(id = 6)
rule4 = Q(client = 10) & (Q(occupation = 2) | Q(occupation = 6) | Q(occupation = 9))

people = Person.objects.filter(rule1 | rule2 | rule3 | rule4)

然后将它们的腌制字符串存储到数据库中。

代码语言:javascript
复制
rule = rule1 | rule2 | rule3 | rule4
pickled_rule_string = pickle.dumps(rule)
Rule.objects.create(pickled_rule_string=pickled_rule_string)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11661199

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档