高效的搜索查询

时间:2011-09-17 22:56:40

标签: php mysql

我在数据库中有一个表,结构如下 关键字

  • id int(11)
  • U_id int(11)
  • keywords text
  • create_date int(11)

U_id是外键,id是主键

关键字字段是由逗号分隔的用户创建的字词列表 我想知道是否有人可以提出有效的查询来搜索这样的表格。

4 个答案:

答案 0 :(得分:2)

您应该更改数据库设计,以便拥有一个名为user_keyword的表,并将每个关键字存储在一个单独的行中。然后,您可以将此表编入索引并轻松有效地进行搜索:

WHERE keyword = 'foo'

如果您无法修改数据库,那么您可以使用FIND_IN_SET,但效率不高:

WHERE FIND_IN_SET('foo', keywords) 

答案 1 :(得分:1)

在自己的表格中单独keywords,通过FOREIGN KEY将其“连接”到旧表,对其进行索引,然后您就能够有效地搜索关键字前缀的确切关键字。

例如:

id U_id keywords create_date
1  -    A,B,C    -

变为:

PARENT_TABLE:
id U_id create_date
1  -    -

CHILD_TABLE:
id keyword
1  A
1  B
1  C

如果keyword上有索引,则以下查询应该有效:

SELECT * FROM PARENT_TABLE
WHERE id IN (SELECT id FROM CHILD_TABLE WHERE keyword = ...)

<强> --- --- EDIT

根据Johan的评论,似乎InnoDB使用Oracle下的“索引组织表”或大多数其他数据库下的“集群”。如果您不需要查询“从父级到子级”(即“给我所有给定ID的关键字”),CHILD_TABLE上的PRIMARY KEY应该是:

{keyword, id}

由于keyword是复合索引中的第一个字段,WHERE keyword = ...(或WHERE keyword LIKE 'prefix%')可以直接使用此索引。

答案 2 :(得分:0)

如果您使用MyISAM,则可以在字段keywords上创建全文索引。然后使用:

进行搜索
select * from keywords k where match('test') against(k.keywords);

当然,数据库中的CSV几乎是你能做的最糟糕的事情。您应该将关键字放在单独的表中。确保对所有表使用InnoDB。

Table tags
-------------
id integer auto_increment primary key
keyword_id integer foreign key references keywords(id)
keyword varchar(40)

现在您可以选择使用:

SELECT k.* FROM keywords k
INNER JOIN tags t ON (t.keyword_id = k.id)
WHERE t.keyword LIKE 'test' //case insensitive comparison.

比CSV快得多。

答案 3 :(得分:-1)

您有两个选择:

  1. 重新构建您的数据库,创建一个名为Keywords的额外表格,其中应包含一个U_id,它将是映射到您的用户表格的外键,这样您就可以轻松地将每个关键字插入关键字表格然后搜索它使用的东西:
  2. SELECT * FROM Keywords WHERE keyword LIKE %KEYWORD%

    1. 您可以获取关键字字段,分隔关键字并使用首选语言将它们放入数组中,然后搜索数组。