首页 > MySql数据表设计问题,求优化。

MySql数据表设计问题,求优化。

遇到一个表设计问题,需求如下:
为了描述人与标签的关系,1个人对应1或n个标签,多个人可对应1个标签,根据人找标签和根据标签找人。

例子:
(人)-- (标签)
小明 -- 诚实、可爱
小丽 -- 可爱
小王、小明 -- 老实
小张、小丽 -- 美丽
小张、小王、小丽 -- 俊俏

此时,
找小明可以找到标签:诚实、可爱、老实
找小明&&小王可以找到:老实
找小张&&小丽可以找到:美丽
找小张&&小丽&&小王可以找到:俊俏

请教:这样的数据表如何设计会很比较合理,查询效率会高些?


本人现在的设计是这样的:
表Person(ID、Name)
表Tag(ID、TagName、PersonIDs)
PersonIDs是Person表中ID的集合,如:[1,2,3,4]这样存储,检索的时候用 like。
困惑:如果此处用like,数据较大的时候查询会很慢...


两张表为什么要用like。
我觉得用PersonID做关联就行。


典型的多对多关系:

Person (PersonId, Name)
Tag (TagId, Name)
PersonTag (PersonId FK1, TagId FK2)

查询Person 'P1'的Tag:

SELECT t.Name as TagName
FROM PersonTag pt
JOIN Tag t ON t.TagId = pt.TagId
WHERE pt.PersonId = 'P1'

查询具有 Tag 'T1' 的 Person:

SELECT p.Name as PersonName
FROM PersonTag pt
JOIN Person p ON p.PersonId = pt.PersonId
WHERE pt.TagId = 'T1'

查询'P1', 'P2'共同的Tag:

SELECT t.Name as TagName
FROM Tag t
WHERE (
    SELECT COUNT(*)
    FROM PersonTag
    WHERE TagId = t.TagId AND PersonId IN ('XM', 'XH')
    ) = (
    SELECT COUNT(*)
    FROM Person
    WHERE PersonId IN ('XM', 'XH')
    )

或者:

SELECT pt.TagId
FROM PersonTag pt
CROSS JOIN Person p
LEFT OUTER JOIN PersonTag pt2 on pt2.PersonId = p.PersonId AND pt2.TagId = pt.TagId
WHERE pt.PersonId IN ('XM', 'XH', 'XL')
    AND p.PersonId IN ('XM', 'XH', 'XL')
GROUP BY pt.TagId
HAVING SUM(CASE WHEN pt2.TagId IS NULL THEN 1 ELSE 0 END) = 0

多加一张标签表(TagMap), tagID, personID,人物增加,减少标签都需要更新这个表,查询时按索引,效率高,不过好像这种问题,用nosql更好处理

【热门文章】
【热门文章】