在绿色字段项目中,我有一个实体Resource
,它有许多子实体Attributes
。为了对模式进行建模,我在属性表中创建了一个FK。
资源有name
和id
,属性有resourceId
,属性name
和属性value
。
number of attributes
和name 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)不应该存在,因为它们具有相同的name
和attributes
以及same number of attributes
。我可以以编程方式强制执行唯一性,但是想知道是否有方法在数据库级别强制执行它,并且可能重新设计表或查询以便更容易和有效地查找。
我需要查询此表并使用其属性查找确切的资源。为此我编写了以下查询并且工作正常(可能没有优化,因为资源可以有很多属性,查询会变得很长):
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 :(得分:0)
我能想到的最好的方法是在Attributes
表,name
和value
两列上添加唯一约束:
ALTER TABLE Attributes ADD UNIQUE `idx` (`name`, `value`);
这将确保给定的resource_id
必须具有name
和value
的唯一组合。
您可以编写一个触发器来检查插入后给定属性的行数是否不超过20。