Postar meta versus tabelas de banco de dados separadas


29

Ao desenvolver plug-ins que exigem armazenamento de dados, quais são os prós e os contras de usar um método ou outro?

A explicação dada no codex não é detalhada:

Antes de saltar com uma tabela totalmente nova, no entanto, considere se o armazenamento dos dados do seu plug-in no Post Meta do WordPress (também conhecido como Campos personalizados) funcionaria. Post Meta é o método preferido; use-o quando possível / prático.


FYI: MB Custom Table é um plug-in que pode armazenar metadados em tabelas personalizadas, em vez da meta-tabela posterior do WP.
Anh Tran

Respostas:


30

Bem, se eu pegar o chapéu de uma criança WP, minha resposta seria: use post_meta, sempre.

No entanto, eu sei uma coisa ou duas sobre bancos de dados, então minha resposta é: nunca, nunca, nunca, use um EAV (também conhecido como tabela post_meta) para armazenar dados que talvez você precise consultar.

Na frente do índice, basicamente não vale a pena usar nas meta-tabelas. Portanto, se você estiver armazenando dados do tipo XYZ e desejar consultar todas as postagens que têm XYZ com um valor de 'abc', bem ... boa sorte. (Veja todos os tickets relacionados a usuários / funções / bonés no WP trac para ter uma idéia de quão sangrento ele pode ficar.)

Na frente da junção, você entra rapidamente no limite em que o otimizador decide usar um algoritmo genérico em vez de analisar a consulta quando há vários critérios de junção.

Assim, não, não, não, não. Nunca, nunca, nunca use uma meta. A menos que o que você está armazenando seja cosmético e nunca faça parte de um critério de consulta.

Ele divide em seu aplicativo. Se você está armazenando, digamos, a data de nascimento de um diretor de cinema, isso é grande coisa. Use uma meta quanto quiser. Mas se você estiver armazenando, digamos, a data de lançamento de um filme, seria louco para não usar uma tabela separada (ou adicionar colunas à tabela de postagens) e adicionar um índice a essa coluna.


1
Sim, os plugins que estou desenvolvendo lidam com dados personalizados, como eventos, notícias, press releases, ofertas de emprego ... Fora do "WordPress World", usar tabelas não é realmente uma opção. Mas o conselho do WordPress Codex é um pouco confuso. Como os pedaços de dados serializados podem ser preferidos aos dados normalizados / estruturados / indexados?
Nassif Bourguig

1
Se você perguntar ao desenvolvedor médio do WP, ele provavelmente responderá "use uma meta" ou "use uma taxonomia". E eu concordo, até o ponto em que você precisa consultá-lo. Nesse caso, e acredito que seja o seu caso, minha única resposta é: adicione os campos à tabela de postagens ou crie uma tabela separada inteiramente. Caso contrário, você terá enormes problemas de desempenho quando se trata de consultas e, mais importante ainda, para listas de nós, classificação top-n.
Denis de Bernardy

1
Denis would you be able to elaborate on this a little more, I find it very informative but would love some more data, has anyone done tests?, what exactly are the major drawbacks and limitations, thanks.
Wyck

6
@ Denis - Bastante a defesa apaixonada contra o pós-meta, não é? Você sabe que está se opondo firmemente à ortodoxia e cairá das boas graças dos sumos sacerdotes da igreja de poesia em código, se persistir em tal conversa, não é? :-) Mas sério, você não acha que exagera um pouco? Realmente depende se haverá dezenas de milhares de meta-registros ou não. Em muitos casos, simplesmente não há registros suficientes para se preocupar. Um site complexo que estou implantando possui cerca de 10.000 meta registros com poucos novos registros planejados, e tudo bem (fyi, não é um blog). #
MikeSchinkel

1
@ Denis - Obrigado pelos comentários. E não me entenda mal, eu provavelmente me inclino muito mais na sua perspectiva, mas a combinação de 1.) um debate de uma hora com Matt no WordCamp Birmingham sobre os méritos dos campos semelhantes a Pods e 2.) a simplicidade da meta deve renunciar para concentrar minhas atenções em outros problemas que eu poderia mudar. No WCB, percebi que, enquanto Matt estiver no comando, isso não mudará porque (meu palpite é) Matt está tão apaixonado pela idéia de menos tabelas que não se permite reconhecer os aspectos negativos da indexação em 768 bytes chave. <sigh>
MikeSchinkel

5

Se o seu plug-in tiver MUITOS dados, use wp_postmetaNÃO é uma boa ideia, como demonstrado abaixo:

Tomando o WooCommerce como exemplo, em uma loja com ~ 30.000 produtos, haverá uma média de, digamos, ~ 40 post meta (atributos e tudo) por produto, 5 imagens de produto por produto, o que significa que haverá ~ 4 meta de imagem para cada imagem:

30.000 produtos x 40 meta cada = 1.200.000 linhas em wp_postmeta

+

30.000 produtos x 5 imagens cada x 4 meta de imagem para cada = 600.000 linhas em wp_postmeta

Portanto, com apenas 30.000 produtos, você espera ter 1.800.000 linhas wp_postmeta.

Se você adicionar mais propriedades a seus produtos ou imagens de seus produtos, esse número será multiplicado.

O problema disso é duplo:

  • As associações automáticas são muito caras com o MySQL
  • wp_postmetaA tabela não é indexada, a menos que você esteja usando versões posteriores do mysql (ou seja, nenhum índice FULLTEXT para meta_value)

Para dar um exemplo de um caso real:

SELECT meta_value FROM wp_postmeta WHERE meta_key LIKE '_shipping_city'

Isso seleciona a cidade de remessa de todos os detalhes do pedido em aproximadamente 3 segundos em um servidor dedicado de nível de entrada, mesmo que haja 5 a 10 pedidos . Isso ocorre porque a consulta é executada entre uma wp_postmetatabela que possui ~ 3 milhões de linhas na instalação ao vivo.

Até a página inicial é bastante lenta, porque o tema extrai vários elementos wp_postmeta- controles deslizantes, algumas inserções de revisão, algumas outras meta. Em geral, a listagem de produtos é muito lenta, as pesquisas são igualmente lentas ao listar produtos.

Você não pode consertar isso por qualquer meio normal. Você pode colocar o Elastic Search em seu servidor e usar um plug-in do Elastic Search no Wordpress, usar redis / memcached, usar um bom plug-in de cache de página, mas no final a questão fundamental permanecerá - buscando qualquer quantidade de dados de um inchado wp_postmetaA tabela ficará lenta, sempre que estiver pronta. No servidor em que testei a solução que implementei abaixo, todas foram instaladas e configuradas adequadamente e otimizadas, e o site funcionou de maneira agradável para usuários não conectados ou para consultas comuns desde que os plug-ins de cache foram lançados.

Mas no momento em que um usuário logado tentou fazer algo que não era comumente feito, ou os crons, plug-ins de cache ou qualquer outro utilitário quiseram buscar dados reais do banco de dados para armazená-lo em cache ou fazer qualquer outra coisa, as coisas ficaram muito lentas.

Então, tentei outra coisa:

Codifiquei um pequeno plug-in para levar toda a meta do produto (postmeta para produto do tipo pós ) a uma tabela personalizada gerada pelo código. Este plug-in pegou todas as meta para cada postagem e criou uma tabela adicionando cada meta como colunas e inserindo os valores em cada linha. Transformei o formato EAV em um formato relacional horizontal e plano. Eu também tinha o plugin para excluir o postmeta de todos os produtos movidos da wp_postmetatabela.

Enquanto estou nisso, movi o postmeta do anexo e a meta de todos os outros tipos de post para suas próprias tabelas.

Em seguida, liguei-me ao get_(post_type)_metafiltro para substituir a recuperação de metadados para servi-los de novas tabelas personalizadas.

Agora, a mesma consulta anterior, que levou ~ 3 segundos para buscar, wp_postmetaleva ~ 0,006 segundos. O site agora se comporta como se fosse uma nova instalação do WP.

....................

Naturalmente, fazer as coisas da maneira Wordpress é melhor. Na verdade, é a norma.

No entanto , também é óbvio o conhecimento de que a tabela EAV é muito ineficiente no dimensionamento. É infinitamente flexível e permite armazenar todos os dados, mas o preço pago por isso é o desempenho. É uma troca fundamental.

Nesse contexto, é difícil dizer a alguém que pretende ter uma tonelada de dados e - Deus não permita - consultar / pesquisar esses dados para usar a wp_postmetatabela com certeza. O sucesso no desempenho será ótimo.

O uso de suas tabelas personalizadas permitirá que seus dados se acumulem e continuem sendo rápidos o suficiente.

Assim como Pippin Williams, o criador do plug-in Easy Digital Downloads mencionou que ele usaria tabelas personalizadas se estivesse apenas começando a codificar seu plug-in, se você criar algo que será usado por muito tempo ou acumular muitos dados, é mais eficiente usar suas tabelas personalizadas se você as projetar bem.

Você deve se certificar de que qualquer outro desenvolvedor de plug-ins / addons tenha meios de se conectar ao seu plug-in para manipular seus dados antes e depois da recuperação dos dados. Se você fizer isso, será bastante sólido.


1
Coisas interessantes! Uma coisa a esclarecer é que o filtro "get_ (post_type) _meta" é realmente chamado de "get_ (tipo-meta) _metadados", onde o tipo-tipo é post, comentário ou usuário. Portanto, get_post_meta () passará pelo filtro get_post_metadata, independentemente do tipo de postagem. O valor de retorno do filtro é o que você deseja que o meta-valor final seja.
Berend 27/02

get_ (meta-type) _metadata -> de fato funciona com todos os tipos de post, e de fato a função final que é visitada é get_post_metadata. No entanto, o filtro funciona quando você o usa.
unity100

2

Depende do que você está fazendo. A maneira WP é usar as tabelas existentes, pois elas foram projetadas para serem flexíveis o suficiente; no entanto, ocasionalmente, você alcança uma nova classe de dados que não pode ser colocada em uma tabela existente, por exemplo, se você quisesse metadados de categoria , você pode optar por criar uma tabela wp_termsmeta.

No entanto, geralmente você pode armazenar seus dados com bastante facilidade nas diferentes tabelas existentes, e o local onde os dados são armazenados depende do que o seu plug-in faz.

  • Para configurações gerais de plug-ins, use a chamada da API get_option () - isso também será armazenado em cache.
  • Para configurações de plug-in específicas para uma postagem individual, use os metadados personalizados por postagem com get_post_meta () . Isso geralmente é suficiente para o que você precisa.

O cache é implementado no WordPress para acelerar também o tempo de resposta.


1

concordou com denis 100%. Mas há uma maneira de contornar isso.

O problema com o uso da meta de postagem para que os valores sejam consultados é quando os valores são da matriz etc. Como este:

array(
'key1' => 'val 1',
'key2' => 'val 2'
);

Isso é armazenado no db como uma seqüência de caracteres serializada, que será algo parecido com isto:

{array["key1"]...{}...}

Portanto, quando você quiser consultar todas as postagens array['key2'] = 'val 2', o wp precisará extrair todas as meta-entradas chamadas array, descompactá-las, testá-las e passar para a próxima. Isso definitivamente derrubará seu servidor se seu site for bem-sucedido e tiver muitas postagens, páginas, postagens personalizadas etc.

A solução depende do projeto e você verá o porquê. Se você armazenar os dados como um var = valwp, poderá pesquisar sem ter o php para descompactar todos os testes. Para fazer isso no cenário acima, você usaria algum espaço para nome e armazenaria as meta chaves:

_array_key1 = 'val 1';
_array_key2 = 'val 2';

então, wp procurando a chave 2 com val 2 poderá puxá-la imediatamente. Este é um projeto dependendo, no entanto. Meu projeto atual conta com cerca de 20 tipos de dados diferentes para serem armazenados em cada postagem personalizada, para que o acima crie uma tabela enorme para pesquisa, visto que estamos esperando centenas de milhares de postagens. Portanto, nesse cenário, uma tabela personalizada é a única maneira.

Espero que isso ajude alguém


0

Para o meu site FarmVille :) fiz os dois, mas nunca o terminei porque o vendi:

  1. Eu li o farmville xml e joguei os dados em uma tabela personalizada
  2. No WordPress, eu tinha campos personalizados criados automaticamente para todos os campos dessa tabela (e alguns extras)
  3. Agora, preocupe-se com o que acontece se um valor mudar na tabela ou no outro lado: o campo personalizado, pois eles precisam estar continuamente sincronizados

Eu fiz isso porque, por um lado, queria que os usuários editassem o site wordpress inserindo novos dados de farmville, por exemplo, "uma vaca custa 10 moedas" MAS do lado da integração: se uma alteração no XML a vaca agora custa "20 moedas" (por meio do plug-in de edição do front-end) que seria fornecido como opção depois dele: para que o XML OU o usuário estivesse certo (tipo de sistema wiki).

Então, aqui está um exemplo ao usar os dois.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.