{"status":"sucesso","dados":{"itens":[{"uuid":"d1e1c690-4557-4e95-b09f-920dbef3c0ea","categoria_uuid":"cde892ac-4ec9-42a4-a0de-ec304c42cfe9","titulo":"Olá, sou Adimael","slug":"ola-sou-adimael-f600747","subtitulo":"Portfolio","conteudo_html":"\u003Cp class=\u0022isSelectedEnd\u0022\u003EMeu nome é Adimael e sou desenvolvedor de software.\u003C\/p\u003E\u003Cp\u003ENeste portfólio, apresento projetos que desenvolvi e compartilho conteúdos sobre desenvolvimento, bancos de dados, APIs e infraestrutura. Também mostro problemas que encontrei durante a construção dos sistemas e como consegui resolvê-los.\u003C\/p\u003E","status":"publicado","midias":[],"criado_em":"2026-08-02T05:11:57+00:00","publicado_em":"2026-08-02T05:11:57+00:00"},{"uuid":"9923fc59-2185-49f7-a391-610f3cfef61a","categoria_uuid":"dae8ede4-df75-49e4-8ba4-dc0267e02171","titulo":"LIKE ou Full-Text Search: qual usar nas buscas do sistema?","slug":"like-ou-full-text-search-qual-usar-nas-buscas-do-sistema-9a660d5","subtitulo":"Qual usar? LIKE ou Full-Text Search?","conteudo_html":"\u003Cp class=\u0022isSelectedEnd\u0022\u003E\u003C\/p\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003E\u003C\/p\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EQuando precisamos colocar uma busca em um sistema, normalmente a primeira solução que vem à cabeça é o \u003Ccode\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022color: rgb(186, 186, 186)\u0022\u003E\u003Cspan style=\u0022color: rgb(0, 0, 0)\u0022\u003E\u003Cspan style=\u0022background-color: rgb(201, 201, 201)\u0022\u003ELIKE\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/code\u003E.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EEle é fácil de entender, funciona no \u003Cspan style=\u0022font-weight: bold\u0022\u003EPostgreSQL\u003C\/span\u003E e no \u003Cspan style=\u0022font-weight: bold\u0022\u003EMySQL\u003C\/span\u003E e resolve boa parte das buscas simples:\u003C\/p\u003E\u003C\/span\u003E\u003C\/span\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003E\u003C\/p\u003E\u003C\/span\u003E\u003C\/span\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003E\u003C\/p\u003E\u003Cpre\u003E\u003Ccode\u003ESELECT titulo, subtitulo\nFROM publicacoes\nWHERE titulo LIKE \u0027%postgresql%\u0027;\u003C\/code\u003E\u003C\/pre\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003E\u003C\/p\u003E\u003Cspan\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003E\u003C\/p\u003E\u003Cspan\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EEsse comando procura a palavra \u003Ccode\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan style=\u0022background-color: rgb(214, 214, 214)\u0022\u003Epostgresql\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/code\u003E em qualquer parte do título. Para um sistema pequeno, com poucos registros, ele pode funcionar muito bem.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EEntão por que pensar em outra solução?\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EA resposta está no tipo de busca que queremos oferecer e na quantidade de dados que o sistema precisa consultar.\u003C\/p\u003E\u003C\/span\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003E\u003C\/p\u003E\u003C\/span\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003E\u003C\/p\u003E\u003Ch4\u003EPor que o LIKE é tão utilizado?\u003C\/h4\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO \u003Ccode\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(209, 209, 209)\u0022\u003ELIKE\u003C\/span\u003E\u003C\/span\u003E\u003C\/code\u003E costuma ser a primeira escolha por alguns motivos:\u003C\/p\u003E\u003Cul\u003E\u003Cli\u003EÉ simples de aprender.\u003C\/li\u003E\u003Cli\u003ENão exige a criação de uma estrutura específica para busca.\u003C\/li\u003E\u003Cli\u003EFunciona bem em tabelas pequenas.\u003C\/li\u003E\u003Cli\u003EPode procurar partes de uma palavra.\u003C\/li\u003E\u003Cli\u003EEstá disponível nos bancos de dados mais conhecidos.\u003C\/li\u003E\u003C\/ul\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ETambém é comum aprender \u003Ccode\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(199, 199, 199)\u0022\u003ELIKE\u003C\/span\u003E\u003C\/span\u003E\u003C\/code\u003E logo no início dos estudos de \u003Cspan style=\u0022font-weight: bold\u0022\u003ESQL\u003C\/span\u003E. Já o \u003Cspan\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(196, 196, 196)\u0022\u003EFull-Text Search\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E exige entender índices, configuração de idioma e relevância dos resultados.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EPortanto, usar \u003Ccode\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(204, 204, 204)\u0022\u003ELIKE\u003C\/span\u003E\u003C\/span\u003E\u003C\/code\u003E não significa que o código esteja errado. O problema aparece quando ele é usado para realizar buscas mais completas em uma quantidade maior de textos.\u003C\/p\u003E\u003Ch4\u003EQuando o LIKE pode se tornar um problema?\u003C\/h4\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EUma busca como esta começa com o caractere \u003Ccode style=\u0022font-weight: bold\u0022\u003E%\u003C\/code\u003E:\u003C\/p\u003E\u003Cpre\u003E\u003Ccode\u003EWHERE titulo LIKE \u0027%postgresql%\u0027\u003C\/code\u003E\u003C\/pre\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ENesse caso, um índice \u003Cspan style=\u0022font-weight: bold\u0022\u003EB-tree\u003C\/span\u003E comum normalmente não consegue ajudar da mesma forma que ajudaria em uma busca iniciada por um texto conhecido, como:\u003C\/p\u003E\u003Cpre\u003E\u003Ccode\u003EWHERE titulo LIKE \u0027postgresql%\u0027\u003C\/code\u003E\u003C\/pre\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ENa primeira consulta, o banco pode precisar verificar uma quantidade maior de registros para encontrar o texto pesquisado.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EOutro ponto é que o \u003Ccode\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(209, 209, 209)\u0022\u003ELIKE\u003C\/span\u003E\u003C\/span\u003E\u003C\/code\u003E procura uma sequência de caracteres. Ele não foi criado para entender quais resultados são mais importantes.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EConsidere estas duas publicações:\u003C\/p\u003E\u003Cpre\u003E\u003Ccode\u003EPostgreSQL: criando uma busca com Full-Text Search\nConfigurando um servidor que utiliza PostgreSQL\u003C\/code\u003E\u003C\/pre\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ESe a pessoa pesquisar por \u003Ccode style=\u0022font-weight: bold\u0022\u003E\u003Cspan\u003E\u003Cspan\u003E\u003C\/span\u003E\u003C\/span\u003E\u003Cspan style=\u0022background-color: rgb(189, 189, 189)\u0022\u003E\u003Cspan\u003E\u003Cspan\u003EPostgreSQL\u003C\/span\u003E\u003C\/span\u003E busca\u003C\/span\u003E\u003C\/code\u003E, o primeiro conteúdo provavelmente deveria aparecer antes. Com \u003Ccode\u003E\u003Cspan\u003E\u003Cspan style=\u0022background-color: rgb(186, 186, 186); font-weight: bold\u0022\u003ELIKE\u003C\/span\u003E\u003C\/span\u003E\u003C\/code\u003E, seria necessário criar condições adicionais para tentar chegar a esse resultado.\u003C\/p\u003E\u003Ch4\u003EO que muda com o Full-Text Search?\u003C\/h4\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO \u003Cspan\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(199, 199, 199)\u0022\u003EFull-Text Search\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E prepara os textos para que possam ser pesquisados como palavras, e não apenas como sequências de caracteres.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ECom ele, podemos:\u003C\/p\u003E\u003Cul\u003E\u003Cli\u003EPesquisar várias palavras.\u003C\/li\u003E\u003Cli\u003EOrdenar os resultados por relevância.\u003C\/li\u003E\u003Cli\u003EDar mais importância ao título do que ao subtítulo.\u003C\/li\u003E\u003Cli\u003EUtilizar um índice próprio para busca textual.\u003C\/li\u003E\u003Cli\u003ETratar melhor pesquisas em campos com textos maiores.\u003C\/li\u003E\u003C\/ul\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ENo \u003Cspan style=\u0022font-weight: bold\u0022\u003EPostgreSQL\u003C\/span\u003E, por exemplo, podemos definir que uma palavra encontrada no título tenha um peso maior do que a mesma palavra encontrada no subtítulo.\u003C\/p\u003E\u003Ch4\u003ECriando um exemplo para testar\u003C\/h4\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EPrimeiro, vamos criar uma tabela pequena:\u003C\/p\u003E\u003Cpre\u003E\u003Ccode\u003ECREATE TABLE publicacoes (\n    id SERIAL PRIMARY KEY,\n    titulo VARCHAR(200) NOT NULL,\n    subtitulo VARCHAR(255)\n);\u003C\/code\u003E\u003C\/pre\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EAgora podemos inserir alguns conteúdos:\u003C\/p\u003E\u003Cpre\u003E\u003Ccode\u003EINSERT INTO publicacoes (titulo, subtitulo) VALUES\n(\n    \u0027PostgreSQL: busca com Full-Text Search\u0027,\n    \u0027Como melhorar a pesquisa de publicações\u0027\n),\n(\n    \u0027Primeiros passos com PHP\u0027,\n    \u0027Criando uma API conectada ao PostgreSQL\u0027\n),\n(\n    \u0027Configurando um servidor Linux\u0027,\n    \u0027Preparação do ambiente para publicar uma aplicação\u0027\n);\u003C\/code\u003E\u003C\/pre\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EAntes de continuar, execute uma busca com \u003Ccode\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(194, 194, 194)\u0022\u003ELIKE\u003C\/span\u003E\u003C\/span\u003E\u003C\/code\u003E:\u003C\/p\u003E\u003Cpre\u003E\u003Ccode\u003ESELECT id, titulo\nFROM publicacoes\nWHERE titulo ILIKE \u0027%postgresql%\u0027\n   OR subtitulo ILIKE \u0027%postgresql%\u0027;\u003C\/code\u003E\u003C\/pre\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EResultado esperado:\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003E\u003C\/p\u003E\u003Cdiv class=\u0022editor-table-wrap\u0022\u003E\u003Ctable class=\u0022editor-content-table table-theme-accent\u0022\u003E\u003Cthead\u003E\u003Ctr\u003E\u003Cth scope=\u0022col\u0022\u003Eid\u003C\/th\u003E\u003Cth scope=\u0022col\u0022\u003Etitulo\u003C\/th\u003E\u003C\/tr\u003E\u003C\/thead\u003E\u003Ctbody\u003E\u003Ctr\u003E\u003Ctd\u003E1\u003C\/td\u003E\u003Ctd\u003EPostgreSQL: busca com Full-Text Search\u003C\/td\u003E\u003C\/tr\u003E\u003Ctr\u003E\u003Ctd\u003E2\u003C\/td\u003E\u003Ctd\u003EPrimeiros passos com PHP\u003C\/td\u003E\u003C\/tr\u003E\u003C\/tbody\u003E\u003C\/table\u003E\u003C\/div\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003E\u003C\/p\u003E\u003Cp\u003E\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO \u003Ccode\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(204, 204, 204)\u0022\u003EILIKE\u003C\/span\u003E\u003C\/span\u003E\u003C\/code\u003E é uma opção do \u003Cspan style=\u0022font-weight: bold\u0022\u003EPostgreSQL\u003C\/span\u003E que realiza a comparação sem diferenciar letras maiúsculas de minúsculas.\u003C\/p\u003E\u003Ch4\u003EFull-Text Search no PostgreSQL\u003C\/h4\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ENo \u003Cspan style=\u0022font-weight: bold\u0022\u003EPostgreSQL\u003C\/span\u003E, podemos criar uma coluna que prepara o título e o subtítulo para a busca:\u003C\/p\u003E\u003Cpre\u003E\u003Ccode\u003EALTER TABLE publicacoes\nADD COLUMN busca_textual tsvector\nGENERATED ALWAYS AS (\n    setweight(\n        to_tsvector(\u0027portuguese\u0027, coalesce(titulo, \u0027\u0027)),\n        \u0027A\u0027\n    ) ||\n    setweight(\n        to_tsvector(\u0027portuguese\u0027, coalesce(subtitulo, \u0027\u0027)),\n        \u0027B\u0027\n    )\n) STORED;\u003C\/code\u003E\u003C\/pre\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO título recebeu o \u003Cspan style=\u0022font-weight: bold\u0022\u003Epeso \u003Ccode\u003EA\u003C\/code\u003E\u003C\/span\u003E, enquanto o subtítulo recebeu o \u003Cspan style=\u0022font-weight: bold\u0022\u003Epeso \u003Ccode\u003EB\u003C\/code\u003E\u003C\/span\u003E. Isso informa que uma palavra encontrada no título deve ter mais importância.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EEm seguida, criamos um índice \u003Cspan style=\u0022font-weight: bold\u0022\u003EGIN\u003C\/span\u003E:\u003C\/p\u003E\u003Cpre\u003E\u003Ccode\u003ECREATE INDEX publicacoes_busca_textual_idx\nON publicacoes\nUSING GIN (busca_textual);\u003C\/code\u003E\u003C\/pre\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EAgora podemos fazer a busca:\u003C\/p\u003E\u003Cpre\u003E\u003Ccode\u003ESELECT\n    id,\n    titulo,\n    ts_rank_cd(\n        busca_textual,\n        websearch_to_tsquery(\u0027portuguese\u0027, \u0027postgresql busca\u0027)\n    ) AS relevancia\nFROM publicacoes\nWHERE busca_textual @@\n      websearch_to_tsquery(\u0027portuguese\u0027, \u0027postgresql busca\u0027)\nORDER BY relevancia DESC;\u003C\/code\u003E\u003C\/pre\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO primeiro conteúdo tende a receber uma relevância maior porque possui as duas palavras pesquisadas no título.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EA função \u003Ccode\u003E\u003Cspan style=\u0022background-color: rgb(166, 166, 166); font-weight: bold\u0022\u003Ewebsearch_to_tsquery\u003C\/span\u003E\u003C\/code\u003E também permite receber pesquisas mais próximas das que fazemos em um buscador. Ela aceita palavras, frases entre aspas e exclusões sem gerar erro facilmente por causa da forma como o usuário digitou.\u003C\/p\u003E\u003Ch4\u003EE como funciona no MySQL?\u003C\/h4\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ENo MySQL, primeiro criamos um índice \u003Ccode style=\u0022font-weight: bold\u0022\u003EFULLTEXT\u003C\/code\u003E:\u003C\/p\u003E\u003Cpre\u003E\u003Ccode\u003EALTER TABLE publicacoes\nADD FULLTEXT INDEX publicacoes_busca_idx (titulo, subtitulo);\u003C\/code\u003E\u003C\/pre\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EDepois utilizamos \u003Ccode style=\u0022font-weight: bold\u0022\u003EMATCH\u003C\/code\u003E e \u003Ccode style=\u0022font-weight: bold\u0022\u003EAGAINST\u003C\/code\u003E:\u003C\/p\u003E\u003Cpre\u003E\u003Ccode\u003ESELECT\n    id,\n    titulo,\n    MATCH(titulo, subtitulo)\n        AGAINST(\u0027postgresql busca\u0027 IN NATURAL LANGUAGE MODE)\n        AS relevancia\nFROM publicacoes\nWHERE MATCH(titulo, subtitulo)\n      AGAINST(\u0027postgresql busca\u0027 IN NATURAL LANGUAGE MODE)\nORDER BY relevancia DESC;\u003C\/code\u003E\u003C\/pre\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO modo natural calcula a relevância dos registros encontrados. Também existe o modo booleano, que oferece operadores para exigir, excluir ou combinar termos.\u003C\/p\u003E\u003Ch4\u003EPostgreSQL e MySQL fazem isso da mesma forma?\u003C\/h4\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO objetivo é parecido, mas a implementação muda:\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003E\u003C\/p\u003E\u003Cdiv class=\u0022editor-table-wrap\u0022\u003E\u003Ctable class=\u0022editor-content-table table-theme-accent\u0022\u003E\u003Cthead\u003E\u003Ctr\u003E\u003Cth scope=\u0022col\u0022\u003EPostgreSQL\u003C\/th\u003E\u003Cth scope=\u0022col\u0022\u003EMySQL\u003C\/th\u003E\u003C\/tr\u003E\u003C\/thead\u003E\u003Ctbody\u003E\u003Ctr\u003E\u003Ctd\u003EUsa \u003Ccode style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(184, 184, 184)\u0022\u003Etsvector\u003C\/span\u003E\u003C\/code\u003E para armazenar o texto preparado\u003C\/td\u003E\u003Ctd\u003EUsa um índice \u003Ccode\u003E\u003Cspan style=\u0022background-color: rgb(181, 181, 181); font-weight: bold\u0022\u003EFULLTEXT\u003C\/span\u003E\u003C\/code\u003E nos campos\u003C\/td\u003E\u003C\/tr\u003E\u003Ctr\u003E\u003Ctd\u003EPesquisa com \u003Ccode style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(179, 179, 179)\u0022\u003Etsquery\u003C\/span\u003E\u003C\/code\u003E\u003C\/td\u003E\u003Ctd\u003EPesquisa com \u003Ccode style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(158, 158, 158)\u0022\u003EMATCH\u003C\/span\u003E\u003C\/code\u003E e \u003Ccode style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(163, 163, 163)\u0022\u003EAGAINST\u003C\/span\u003E\u003C\/code\u003E\u003C\/td\u003E\u003C\/tr\u003E\u003Ctr\u003E\u003Ctd\u003EPode usar \u003Ccode style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(156, 156, 156)\u0022\u003Ets_rank\u003C\/span\u003E\u003C\/code\u003E ou \u003Ccode style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(140, 140, 140)\u0022\u003Ets_rank_cd\u003C\/span\u003E\u003C\/code\u003E\u003C\/td\u003E\u003Ctd\u003EO próprio \u003Ccode style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(153, 153, 153)\u0022\u003EMATCH\u003C\/span\u003E\u003C\/code\u003E retorna a relevância\u003C\/td\u003E\u003C\/tr\u003E\u003Ctr\u003E\u003Ctd\u003EPermite configurar pesos com \u003Ccode\u003E\u003Cspan style=\u0022background-color: rgb(148, 148, 148); font-weight: bold\u0022\u003Esetweight\u003C\/span\u003E\u003C\/code\u003E\u003C\/td\u003E\u003Ctd\u003EA relevância é calculada pelo mecanismo do MySQL\u003C\/td\u003E\u003C\/tr\u003E\u003Ctr\u003E\u003Ctd\u003EO índice GIN é indicado para esse tipo de busca\u003C\/td\u003E\u003Ctd\u003EO índice utilizado é o \u003Ccode style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(179, 179, 179)\u0022\u003EFULLTEXT\u003C\/span\u003E\u003C\/code\u003E\u003C\/td\u003E\u003C\/tr\u003E\u003C\/tbody\u003E\u003C\/table\u003E\u003C\/div\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003E\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003E\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ENão é necessário decorar todas essas funções. O mais importante é entender que cada banco possui sua própria maneira de preparar, indexar e pesquisar os textos.\u003C\/p\u003E\u003Ch4\u003EO Full-Text Search também tem pontos negativos?\u003C\/h4\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ESim. Ele não substitui o \u003Ccode\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(222, 222, 222)\u0022\u003ELIKE\u003C\/span\u003E\u003C\/span\u003E\u003C\/code\u003E em todas as situações.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO \u003Cspan\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(224, 224, 224)\u0022\u003EFull-Text Search\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E exige uma configuração inicial, ocupa espaço com índices e pode precisar de ajustes relacionados ao idioma e às palavras ignoradas pelo banco.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ETambém não é a melhor opção quando precisamos procurar apenas uma parte da palavra.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EPor exemplo, uma busca por \u003Ccode style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(219, 219, 219)\u0022\u003Egres\u003C\/span\u003E\u003C\/code\u003E pode encontrar \u003Ccode style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(199, 199, 199)\u0022\u003EPostgreSQL\u003C\/span\u003E\u003C\/code\u003E com:\u003C\/p\u003E\u003Cpre\u003E\u003Ccode\u003EWHERE titulo ILIKE \u0027%gres%\u0027\u003C\/code\u003E\u003C\/pre\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ENo \u003Cspan\u003E\u003Cspan\u003E\u003Cspan style=\u0022background-color: rgb(204, 204, 204); font-weight: bold\u0022\u003EFull-Text Search\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E, isso pode não acontecer porque a pesquisa trabalha principalmente com palavras e termos preparados.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EPalavras muito curtas também merecem atenção. O \u003Cspan style=\u0022font-weight: bold\u0022\u003EMySQL\u003C\/span\u003E possui configurações de tamanho mínimo das palavras e listas de termos ignorados. Dependendo da configuração, uma palavra pode não entrar no índice.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EBuscas com erros de digitação também não são resolvidas automaticamente. No \u003Cspan style=\u0022font-weight: bold\u0022\u003EPostgreSQL\u003C\/span\u003E, a extensão \u003Ccode style=\u0022font-weight: bold\u0022\u003Epg_trgm\u003C\/code\u003E pode ser uma alternativa quando o sistema precisa encontrar palavras parecidas ou incompletas.\u003C\/p\u003E\u003Ch4\u003EEntão qual devo usar?\u003C\/h4\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO \u003Ccode\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(196, 196, 196)\u0022\u003ELIKE\u003C\/span\u003E\u003C\/span\u003E\u003C\/code\u003E continua sendo uma boa escolha quando:\u003C\/p\u003E\u003Cul\u003E\u003Cli\u003EA tabela possui poucos registros.\u003C\/li\u003E\u003Cli\u003EA busca é simples.\u003C\/li\u003E\u003Cli\u003EPrecisamos encontrar parte de uma palavra.\u003C\/li\u003E\u003Cli\u003ENão precisamos ordenar por relevância.\u003C\/li\u003E\u003Cli\u003EO campo pesquisado possui valores curtos.\u003C\/li\u003E\u003C\/ul\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO \u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(209, 209, 209)\u0022\u003EFull-Text Search\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E \u003C\/span\u003E\u003C\/span\u003Eo quando:\u003C\/p\u003E\u003Cul\u003E\u003Cli\u003EA busca envolve títulos, descrições ou textos maiores.\u003C\/li\u003E\u003Cli\u003EO sistema possui muitos registros.\u003C\/li\u003E\u003Cli\u003EQueremos pesquisar várias palavras.\u003C\/li\u003E\u003Cli\u003EPrecisamos mostrar primeiro os resultados mais relevantes.\u003C\/li\u003E\u003Cli\u003EA busca é uma parte importante da experiência do usuário.\u003C\/li\u003E\u003C\/ul\u003E\u003Ch4\u003EO que utilizei no meu projeto\u003C\/h4\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ENa busca de publicações do meu portfólio, utilizei \u003Cspan\u003E\u003Cspan\u003E\u003Cspan\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(222, 222, 222)\u0022\u003EFull-Text Search\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E porque precisava pesquisar no título e no subtítulo, dando mais importância ao título.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ENo \u003Cspan style=\u0022font-weight: bold\u0022\u003EPostgreSQL\u003C\/span\u003E, criei uma coluna \u003Ccode style=\u0022font-weight: bold\u0022\u003Etsvector\u003C\/code\u003E, configurei o idioma como português e adicionei um índice \u003Cspan style=\u0022font-weight: bold\u0022\u003EGIN\u003C\/span\u003E. A busca utiliza \u003Ccode style=\u0022font-weight: bold\u0022\u003Ewebsearch_to_tsquery\u003C\/code\u003E e os resultados são ordenados com \u003Ccode style=\u0022font-weight: bold\u0022\u003Ets_rank_cd\u003C\/code\u003E.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003ETambém preparei uma implementação para \u003Cspan style=\u0022font-weight: bold\u0022\u003EMySQL\u003C\/span\u003E utilizando índice \u003Ccode style=\u0022font-weight: bold\u0022\u003EFULLTEXT\u003C\/code\u003E e \u003Ccode\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003EMATCH\u003C\/span\u003E ... \u003Cspan style=\u0022font-weight: bold\u0022\u003EAGAINST\u003C\/span\u003E\u003C\/code\u003E.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO objetivo não foi apenas substituir uma consulta por outra. A mudança permitiu organizar os resultados por relevância e preparar a busca para o crescimento da quantidade de publicações.\u003C\/p\u003E\u003Ch4\u003EConclusão\u003C\/h4\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO \u003Ccode\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(207, 207, 207)\u0022\u003ELIKE\u003C\/span\u003E\u003C\/span\u003E\u003C\/code\u003E não é uma solução ruim. Ele é simples, útil e pode ser exatamente o que um projeto pequeno precisa.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO problema é continuar utilizando a mesma solução quando a busca começa a trabalhar com muitos textos, várias palavras e resultados que precisam ser organizados por importância.\u003C\/p\u003E\u003Cp class=\u0022isSelectedEnd\u0022\u003EO \u003Cspan\u003E\u003Cspan style=\u0022font-weight: bold\u0022\u003E\u003Cspan style=\u0022background-color: rgb(209, 209, 209)\u0022\u003EFull-Text Search\u003C\/span\u003E\u003C\/span\u003E\u003C\/span\u003E exige um pouco mais de preparação, mas oferece recursos criados especificamente para pesquisa textual. Saber quando usar cada opção ajuda a evitar tanto consultas limitadas quanto uma estrutura mais complexa do que o projeto realmente precisa.\u003C\/p\u003E\u003Ch3\u003EFontes consultadas\u003C\/h3\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca href=\u0022https:\/\/www.postgresql.org\/docs\/current\/textsearch-controls.html\u0022 target=\u0022_blank\u0022 rel=\u0022noopener noreferrer\u0022\u003EPostgreSQL: controles da busca textual\u003C\/a\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ca href=\u0022https:\/\/www.postgresql.org\/docs\/current\/indexes-types.html\u0022 target=\u0022_blank\u0022 rel=\u0022noopener noreferrer\u0022\u003EPostgreSQL: tipos de índices\u003C\/a\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ca href=\u0022https:\/\/www.postgresql.org\/docs\/current\/textsearch-indexes.html\u0022 target=\u0022_blank\u0022 rel=\u0022noopener noreferrer\u0022\u003EPostgreSQL: índices para busca textual\u003C\/a\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ca href=\u0022https:\/\/www.postgresql.org\/docs\/current\/pgtrgm.html\u0022 target=\u0022_blank\u0022 rel=\u0022noopener noreferrer\u0022\u003EPostgreSQL: extensão pg_trgm\u003C\/a\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ca href=\u0022https:\/\/dev.mysql.com\/doc\/refman\/8.4\/en\/fulltext-natural-language.html\u0022 target=\u0022_blank\u0022 rel=\u0022noopener noreferrer\u0022\u003EMySQL: Full-Text Search em linguagem natural\u003C\/a\u003E\u003C\/li\u003E\u003Cli\u003E\u003Ca href=\u0022https:\/\/dev.mysql.com\/doc\/refman\/8.4\/en\/fulltext-stopwords.html\u0022 target=\u0022_blank\u0022 rel=\u0022noopener noreferrer\u0022\u003EMySQL: palavras ignoradas no Full-Text Search\u003C\/a\u003E\u003C\/li\u003E\u003C\/ul\u003E","status":"publicado","midias":[{"tipo":"imagem","url":"https:\/\/i.ibb.co\/272q3ncp\/capa-like-ou-full-text-search.png","largura":100,"altura":675,"ordem":0}],"criado_em":"2026-08-02T03:03:10+00:00","publicado_em":"2026-08-02T03:03:10+00:00"}],"paginacao":{"limite":15,"tem_mais":false,"proximo_cursor":null}}}