Pergunta

Várias encarnações de esta questão ter sido convidado aqui antes, mas eu pensei que eu iria dar-lhe outro tiro.

Eu tinha um esquema de banco de dados terrível. A única entidade (widget) foi dividida em duas tabelas:

CREATE TABLE widgets (widget_id int(10) NOT NULL auto_increment)

CREATE TABLE widget_data ( widget_id int(10), field ENUM('name','size','color','brand'), data TEXT)

este era menos que ideal. se queria encontrar os widgets de um nome específico, cor e marca, eu tinha que fazer uma de três vias juntar-se sobre a mesa widget_data. assim que eu convertido para o tipo de tabela razoável:

CREATE TABLE widgets (widget_id int(10) NOT NULL auto_increment, name VARCHAR(32),size INT(3),color VARCHAR(16), brand VARCHAR(32))

Isso faz com que a maioria das consultas muito melhor. Mas torna a pesquisa mais difícil. Ela costumava ser que se eu queria para procurar os widgets para, digamos, '% preto%', gostaria apenas SELECT * FROM widget_data WHERE data LIKE '%black%'. Isso me daria todas as instâncias de widgets que estão na cor preta, ou são feitas por indústrias Blackwell, ou o que quer. Eu até sei exatamente qual campo combinado, e pode mostrar isso para o meu usuário.

Como faço para executar uma pesquisa similar usando o novo layout da tabela? Eu poderia naturalmente fazer WHERE name LIKE '%black%' OR size LIKE '%black%'... mas que parece desajeitado, e eu ainda não sei quais campos correspondida. Eu poderia executar uma consulta separada para cada coluna eu quero corresponder em que me daria todos os jogos e como eles correspondiam, mas isso seria um acerto de desempenho. quaisquer ideias?

Foi útil?

Solução

Você tem duas exigências conflitantes. Você deseja pesquisar, como se todos os seus dados estão em um único campo, mas você também quer identificar quais campo específico foi correspondido.

Não há nada de errado com a sua expressão WHERE name LIKE '%black%' OR size LIKE '%black%'.... É uma pesquisa perfeitamente válida sobre a mesa como você definiu. Porque não basta verificar os resultados no código para ver qual deles combinado? É uma sobrecarga mínima.

Se você quer uma sintaxe mais limpa para o seu SQL, então você pode criar um ponto de vista sobre a mesa, adicionando um campo extra que consiste em concatenar os outros campos:

CREATE VIEW extra_widget_data AS
  SELECT (name, size, color, brand,
          CONCAT(name, size, color, brand) as all_fields)
  FROM widget_data;

Em seguida, você teria que adicionar um índice neste campo, o que requer mais espaço, tempo de CPU para manter etc. Eu não acho que vale a pena é isso.

Outras dicas

Você pode incluir parte da expressão WHERE em colunas seleção. Por exemplo:

SELECT 
  *, 
  (name LIKE '%black%') AS name_matched,
  (size LIKE '%black%') AS size_matched
FROM widget_data 
WHERE name LIKE '%black%' OR size LIKE '%black%'...

Em seguida, verifique o valor da name_matched no lado do script.

Não tenho certeza como ele vai afetar o desempenho. Feal libertar para testá-lo antes de ir para produção

Você provavelmente vai querer olhar para MySQL capacidade de pesquisa de texto completo, isso permite que você para o jogo contra várias colunas do tipo varchar.

http://dev.mysql.com/doc /refman/5.1/en/fulltext-search.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top