Pós meta vs tabelas de banco de dados separadas

25

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

A explicação dada no códice não é detalhada:

  

Antes de entrar com um novo   tabela, no entanto, considere se armazenar   os dados do seu plugin no WordPress 'Post   Meta (também conhecido como Custom Fields)   trabalhos. Post Meta é o preferido   método; usá-lo quando   possível / prático.

    
por Nassif Bourguig 03.12.2010 / 20:04
fonte

5 respostas

26

Bem, se eu pegar o chapéu de um script infantil WP, minha resposta seria: use post_meta, sempre.

No entanto, por acaso 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 você possa precisar consultar.

Na frente do índice, basicamente não vale a pena usar em tabelas meta. Então, se você está armazenando o tipo de dados XYZ e espera que você consulte todos os posts que têm XYZ com um valor de 'abc' , bem ... boa sorte. (Veja todos os tickets relacionados a users / roles / caps no WP trac para ter uma idéia de como ele pode ficar sangrento.)

Na linha de junção, você rapidamente colide com o limite no qual 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, alguma vez 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 é dividido em seu aplicativo. Se você está armazenando, digamos, a data de nascimento de um diretor de cinema, que grande coisa. Use uma meta que você quiser. Mas se você está armazenando, digamos, a data de lançamento de um filme, seria um saco não usar uma tabela separada (ou adicionar colunas à tabela de posts) e adicionar um índice a essa coluna.

    
por Denis de Bernardy 03.12.2010 / 22:13
fonte
3

Se o seu plugin tiver MUITOS dados, usar o wp_postmeta NÃO é uma boa ideia, conforme demonstrado abaixo:

Tomando o Woocommerce como exemplo,

Em uma loja com ~ 30.000 produtos, digamos que haverá uma média de ~ 40 pós 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

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

Se você adicionar mais propriedades aos seus produtos ou às imagens do produto, esse número será multiplicado.

O problema com isso é duplo:

  • As auto-associações são muito caras com o MySQL
  • A tabela wp_postmeta não é indexada a menos que você esteja usando versões mais recentes do mysql (ou seja, nenhum índice FULLTEXT para meta_value)

Para dar um exemplo de um caso real:

SELECT meta_value FROM wp_postmeta ONDE meta_key LIKE '_shipping_city'

A consulta

, que seleciona a cidade de envio a partir de todos os detalhes do pedido chega a impressionantes ~ 3 segundos em um servidor dedicado de nível de entrada, mesmo que haja de 5 a 10 pedidos . Isso ocorre porque a consulta é executada entre uma tabela wp_postmeta que possui ~ 3 milhões de linhas na instalação ativa.

Até mesmo a página inicial é bastante lenta, porque o tema puxa vários elementos de wp_postmeta - sliders, algumas inserções de revisão, alguns outros meta. Em geral, as listagens de produtos são muito lentas; as pesquisas também são 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 plugin do Elastic Search no Wordpress, você pode usar o redis / memcached, você pode usar um bom plugin de cache de página, mas no final a questão fundamental permanecerá - buscar qualquer quantidade de dados de um inchado A tabela wp_postmeta será lenta, sempre que for feita. No servidor em que testei a solução que implementei abaixo, todas elas foram instaladas e configuradas corretamente e otimizadas, e o site funcionou agradavelmente ok para usuários que não efetuaram login ou consultas comumente feitas desde o início dos plugins de cache.

Mas no momento em que um usuário logado tentava fazer algo que não era comumente feito, ou os crons, plugins de cache ou qualquer outro utilitário queria buscar dados reais do db para armazená-los em cache ou fazer qualquer outra coisa, as coisas ficaram lentas. / p>

Então eu tentei outra coisa:

Codifiquei um pequeno plug-in para levar toda meta de produto (postmeta para produto do tipo post) a uma tabela personalizada gerada por código. Este plugin pegou todas as meta para cada post e criou uma tabela adicionando cada meta como colunas e inserindo os valores em cada linha. Então, eu transformei o formato EAV em um formato relacional horizontal e plano. Eu também tinha o plugin para apagar postmeta de todos os produtos movidos da tabela wp_postmeta.

Enquanto estou nisso, eu também movi o anexo postmeta e todas as outras meta do tipo post para suas próprias tabelas.

Em seguida, conectei-me ao filtro get_ (post_type) _meta para substituir a recuperação de metadados para atendê-los a partir de novas tabelas personalizadas.

Agora, a mesma consulta anterior, que levou ~ 3 segundos para buscar a partir de wp_postmeta, leva ~ 0.006 segundos. O site agora se comporta como se fosse uma nova instalação do WP.

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

Naturalmente, fazer as coisas do jeito Wordpress é melhor. Na verdade, é a norma.

No entanto , também é óbvio que a tabela EAV é muito ineficiente na escala. É infinitamente flexível e permite armazenar quaisquer dados, mas o preço que você paga por isso é o desempenho. É um trade-off fundamental.

Nesse contexto, é difícil dizer a alguém que está pretendendo ter uma tonelada de dados e - deus proíbione - consultar / pesquisar esses dados para usar a tabela wp_postmeta com certeza. O sucesso no desempenho será ótimo.

O uso de suas tabelas personalizadas permitirá que seus dados se acumulem e permaneçam rápidos o suficiente.

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

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

    
por unity100 20.02.2017 / 10:55
fonte
2

Depende do que você está fazendo. O modo WP é usar as tabelas existentes, já que elas foram projetadas para serem flexíveis o suficiente, no entanto, ocasionalmente, você alcançará uma nova classe de dados que não podem ser colocados em uma tabela existente, por exemplo, Se você quisesse meta-dados de categoria, poderia escolher criar uma tabela wp_termsmeta.

No entanto, normalmente você pode armazenar seus dados confortavelmente nas diferentes tabelas que existem, e onde você armazena seus dados depende do que o seu plugin faz.

  • Para configurações gerais do plug-in, use a get_option () chamada da API - isso também será armazenado em cache.
  • Para as configurações de plug-in de um particular 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 o seu tempo de resposta também.

    
por Dan Smart 03.12.2010 / 22:21
fonte
1

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

O problema com o uso da meta-meta para valores a serem consultados é quando os valores são da matriz, etc. Assim:

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

Isso é armazenado no banco de dados como uma string serializada, que será algo assim:

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

Então, quando você quiser consultar todos os posts com array['key2'] = 'val 2' , então o wp tem que puxar cada meta entrada chamada array, descompactá-la, depois testá-la, depois ir para a próxima. Isto irá derrubar definitivamente o seu servidor se o seu site for bem sucedido e tiver muitos posts, páginas, posts personalizados, etc.

A solução depende do projeto e você verá por quê. Se você fosse armazenar os dados como var = val , então o wp seria capaz de pesquisar sem ter o php para desempacotar todos os testes. Para fazer isso no cenário acima, você usaria algum namespace e armazenaria as chaves meta:

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

então wp procurando a chave 2 com val 2 será capaz de puxá-la imediatamente. Isso é projeto dependendo embora. Meu projeto atual conta com cerca de 20 dataTypes diferentes a serem armazene com cada postagem personalizada, para que o acima apenas crie uma tabela massiva para pesquisar, já que esperamos centenas de milhares de postagens. Então, nesse cenário, uma tabela personalizada é a única maneira.

Espero que isso ajude alguém

    
por Daithí 03.12.2011 / 12:25
fonte
0

Para o meu site FarmVille :) Eu fiz as duas coisas, mas nunca terminei porque vendi:

  1. Eu li o xml farmville e joguei os dados em uma tabela personalizada
  2. No WordPress, eu tinha campos personalizados feitos automaticamente para cada campo nessa 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 sincronizados continuamente

Eu fiz isso porque queria que, por um lado, 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 mudança no xml ment a vaca agora custa "20 moedas" (via o plugin de edição de front-end) que seria dada como opção depois dela: XML OU o usuário estava certo (tipo de sistema wiki).

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

    
por edelwater 04.12.2010 / 17:58
fonte