Armazenando distâncias em MySQL
-
12-09-2019 - |
Pergunta
Eu tenho uma tabela "cores" no meu banco de dados.
O usuário digita uma cor através da interface do usuário, e as pesquisas de back-end para a cor olhando semelhante mais existente na tabela de cores, calculando a distância das cores no espaço HCL.
Vou implementar um algoritmo de cache, o que deve armazenar a distância entre as distâncias de cor previamente calculados, para evitar operações matemáticas repetidas.
O que é o melhor layout de tabela para tal finalidade?
Solução
Como Osama disse, esta parece ser otimização prematura. Com base na sua descrição do algoritmo, eu o faria:
- Pré-calcular os vetores HCL para todas as cores no banco de dados e armazenar uma tabela que mapeia uma ID de cor para seu vetor HCL.
- A tabela deve ser armazenado usando o MySQL espacial extensões , que permitem que você consulta para os vizinhos de um ponto.
- Quando uma nova cor é escolhido, transformá-lo em HCL e consulta para os vizinhos de seu ponto no espaço HCL.
- Se o cache é necessário em tudo, gostaria de cores cache de granulação grossa, para que haja alguma chance de que usuários revisitar uma cor previamente selecionada.
Outras dicas
você poderia fazer isso:
table colors(r,g,b)
table colordistance(user_r,user_g,user_b,r,g,b,distance)
mas você espera que seus usuários para manter inserindo os mesmos números ??? O número máximo de linhas nesta tabela é 16777216 se você incluir apenas a cor mais próxima.
Eu ainda suspeitam que o acesso ao banco é mais lento do que o cálculo, por isso estou pensando na frase " otimização prematura é a raiz de todo o mal ".
Eu executá-lo sem qualquer cache do cálculo até que eu vejo isso como um problema real.
Eu assumo que sua cor "distâncias" são calculadas como algo como:
sqrt((r1-r2)^2 + (g1-g2)^2 + (b1-b2)^2)
Assumindo que você está usando 8 bit pixels, haveria (256 ^ 3) ^ 2 mapeamentos distintos em sua mesa. Isso é um monte de espaço de tabela. (Você provavelmente poderia compactá-lo muito, mas ... ver o próximo ponto).
A outra coisa que você precisa considerar é o custo de uma pesquisa de banco de dados para encontrar uma distância de cor versus o custo de fazer o cálculo. Meu palpite seria que uma pesquisa de banco de dados levaria um milésimo de segundo ou mais, mas o cálculo de métrica deve tomar 1 microssegundo ou menos.
Ao todo, usando uma tabela de banco de dados soa como uma idéia muito ruim para mim.
Aqui está o que eu recomendo:
table colors(color_id, color_name, r, g, b)
table color_distances(color_1_id, color_2_id, distance)
índices: PRIMÁRIA (color_1_id, color_2_id) INDEX (color_1_id, distância, color_2_id)
color_distances conteria todas as combinações possíveis color_id, e só seria atualizado conforme necessário.
A seleção, então, seria simples:
SELECT similar_colors.*
FROM colors as similar_colors, color_distances
WHERE color_distances.color_1_id = <selected_color_id>
ORDER BY color_distances.distance ASC
Eu não estou muito familiarizado com HCL, mas com base na descrição em Cor: : Similaridade :: HCL parece que duas cores são necessários como uma entrada para a distância
.Então, eu acho que, pelo menos, dois conjuntos de RGB e a distância de acordo entre eles deve ser armazenado. Eu não tenho certeza do seu caso de uso, mas se o leque de opções é selecionada, você pode querer armazenar o-seleção do usuário também.
Parece que haveria apenas um número finito de combinações embora? Parece que você poderia fazer a matemática uma vez para cada combinação, e só tem uma tabela de pesquisa?