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

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

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

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

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


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

典型的多对多关系:

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

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

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

  • mysql 中 随机数据插入问题
  • 关于PHP提交数据库事务模式的设计
  • mysql 误删了一个数据库,怎么恢复啊,急!! 谢谢了
  • Thinkphp add数据库中已经插入成功但是返回false
  • sql 怎么根据父id查询下三级子集?
  • 各位大神看下我创建的分区实例哪错啦 谢谢
  • 微信公众号支付完成后,怎么把数据写入数据库
  • mysql查询效率低,请问怎么破?
  • MySQL:动态获取时间该如何实现?
  • mysql如何限制全表更新
  • Java中字符串截取String.subString();