2016-06-22 46 views
0

在绿色字段项目中,我有一个实体Resource,其中有许多子实体Attributes。为了对模式建模,我在属性表中创建了一个FK。如何在子表中具有数据的表上执行唯一性

资源具有nameid,属性具有resourceId和属性name和属性value

对于资源名称,number of attributesname and value of those attributes必须是唯一的。我无法在数据库级别对资源实施唯一性。

例如, MMG(ID:1)具有(a:1,B:ABC)valid MMG(ID:2)具有(a:1)valid MMG(ID:3)具有:(a: 1,b:ABC)not valid

在资源表,MMG(ID:2)是完全有效的,因为它只有一个属性比较其余但是MMG(ID:3)不是,因为它具有完全相同的属性为mmg(id:1)。它基本上是相同的资源。

mmg(id:3)不应该存在,因为它们具有相同的nameattributessame number of attributes。我可以以编程方式实施唯一性,但是想知道是否有办法在数据库级别实施它,并且可能重新设计表或查询以进行更容易和高效的查找。

Resource Table Attributes Table

我需要查询此表并找到利用它的属性的确切资源。为此,我写了下面的查询,并能正常工作(可能不是最优的,虽然因为资源可以有许多属性和查询将变得很长):

select * from (SELECT 
    groupedByResourceId.resource_id 
FROM 
    (SELECT 
     taggedElements.resource_id, 
      COUNT(*) AS count1, 
      SUM(taggedElements.a_ind) AS a_sum, 
      SUM(taggedElements.b_ind) AS b_sum 
    FROM 
     (SELECT 
     resource_id, 
      CASE 
       WHEN (name = 'a' AND value = '1') THEN 1 
       ELSE 0 
      END AS a_ind, 
      CASE 
       WHEN (name = 'b' AND value = 'abc') THEN 1 
       ELSE 0 
      END AS b_ind 
    FROM 
     resource_attribute) AS taggedElements 
    GROUP BY 1) AS groupedByResourceId 
WHERE 
    groupedByResourceId.count1 = 2 
     AND groupedByResourceId.a_sum = 1 
     AND groupedByResourceId.b_sum = 1) as attr, resource where resource.id = attr.resource_id 

注:平均每个资源可能有高达20个属性(含0)。

注意:resourceId正被其他表使用。

+0

如果给定资源已有20个属性,并且有人试图插入另一个属性,那么您希望发生什么? –

+0

我不太关心它们可以添加到资源的最大属性数量。它可能会使查询更长,更短的性能,但问题是目前他们可以多次插入相同的资源及其属性。在资源表上,mmg(id:2)是完全有效的,因为它只有一个属性,与其余的相比,但mmg(id:3)不是,因为它具有与mmg(id:1)相同的确切属性。 – Alidad

+0

为什么你有一个名称/值对的表?理想情况下,您只需为每个可能的属性使用实际列。 – jpmc26

回答

0

我能想到的是对Attributes表中添加唯一约束是最好的,在两列namevalue

ALTER TABLE Attributes ADD UNIQUE `idx` (`name`, `value`); 

这将确保一个给定的resource_id必须有name的独特组合和value

您可能可以编写触发器来检查插入后给定属性的行数不会超过20。

+0

谢谢蒂姆,那个约束不会解决现有的问题。资源(名称)由其属性组合在一起应该是唯一的。在我的示例中,mmg(id:3)及其属性不应该被允许插入,因为mmg(id:1)已经存在,并且具有相同的属性和相同的名称。 – Alidad

相关问题