我有一个系统,可以让我处理书籍和人们在寻找书籍时可以做的研究。
数据库是mysql,我有两个主要表BOOKS
和RESEARCHES
。
BOOKS(id *int*, author *string*, title *string*, price *string*, tags *set('sci-fi', 'literature', 'theatre', 'drama', 'romance', 'recent', ...)*, ...)
RESEARCHES is (researches_id, price_max, author, ...)
当我在数据库中添加一本书时,我希望得到与这本新书相匹配的研究。
由于人们可以在他们的研究中使用很多标签(超过30个),我决定创建另一个表格,而不是在RESEARCHES
中使用标签列,这可能是SET
,
因为我认为SET
列上没有索引,因此我的数据库无法快速处理我的请求。
RESEARCHES_TAGS(id, researches_id, tag).
如果我添加PK Dick的书,标签为'sci-fi','drama',我希望将标签为NULL
或标签('sci-fi','')进行研究戏剧')并排除
与其他标签一起研究。
所以我正在做以下请求:
SELECT * FROM RESEARCHES
LEFT JOIN RESEARCHES_TAGS ON RESEARCHES.researches_id = RESEARCHES_TAGS.researches_id AND RESEARCHES_TAG.tag IN ('literature', 'theatre', 'romance', ...)
WHERE RESEARCHES_TAGS.tag IS NULL
请注意,指定的tags数组不包含标记'sci-fi','drama'。
我的问题是:有更好的解决方案吗?
答案 0 :(得分:1)
我认为重点是排除与标签“文献”,“剧院”,“浪漫”等相关联的行,并且只保留没有标准的行或符合匹配条件的行(sci)电影或戏剧或两者兼而有之)。 你提出的查询恰恰相反。
我自己通常会使用LEFT JOIN j WHERE j.id IS NULL
语句,但这显然是一种反直觉的解决方案。
也许重新定义表结构会允许更简单和/或更快的查询?让我们重新解释一下这个问题......
Will asks for any products
Jane asks for products with at least A and B
John asks for products with at least C
Yael asks for products with at least A and C
Mark asks for products with at least A
您拥有符合A和B要求的产品。你是谁卖给它的?
答案是Will,Jane和Mark,你怎么把它放在表格和查询中?
如果您只有几种类型的要求,则为每个要求添加一个字段,并要求WHERE C = 0 AND D = 0
,因为您不想联系需要您不具备的内容的人。但是如果你有越来越多的标准呢?你不能只是继续添加字段。使用set字段将排除使用索引的可能性。
答案 1 :(得分:0)
您应该将JOIN
条件与WHERE
条件分开。此外,INNER JOIN
对我来说更有意义,因为如果没有相应的RESEARCHES_TAGS
行,您将没有RESEARCHES
行...对吗?
SELECT * FROM RESEARCHES
INNER JOIN RESEARCHES_TAGS ON RESEARCHES.researches_id = RESEARCHES_TAGS.researches_id
WHERE RESEARCHES_TAGS.tag IS NULL OR tag IN ('literature', 'theatre', 'romance', ...)
此外......您应该澄清此查询以指明哪个表tag
属于。