Опублікувати мета проти окремих таблиць баз даних


29

Під час розробки плагінів, які потребують зберігання даних, які плюси та мінуси використання того чи іншого методу?

Пояснення в кодексі НЕ докладно:

Перш ніж зайти до цілої нової таблиці, однак, подумайте, чи зберігатиме дані вашого плагіна в «Мета мета WordPress» (він же - «Custom Fields»). Post Meta є кращим методом; використовувати його, коли це можливо / практично.


FYI: Спеціальна таблиця MB - це плагін, який може зберігати метадані в спеціальні таблиці замість постмета-таблиці WP.
Ань Тран

Відповіді:


30

Що ж, якщо я візьму шапку дитячого сценарію WP, моєю відповіддю буде: завжди використовуйте post_meta.

Однак мені здається, що я знаю щось про базу даних, тому моя відповідь: ніколи, ніколи, ніколи не використовуйте EAV (так само таблиця post_meta) для зберігання даних, які, можливо, знадобляться для запиту.

На передній панелі індексу в мета-таблицях практично нічого не варто використовувати. Отже, якщо ви зберігаєте дані типу XYZ і сподіваєтесь, що ви запитаєте всі повідомлення, у яких XYZ має значення 'abc', ну ... удачі. (Перегляньте всі квитки, пов’язані з користувачами / ролями / шапками, в трафіку WP, щоб дати вам уявлення про те, наскільки це може бути корисним.)

На фронті приєднання ви швидко врізаєтесь у межу, при якій оптимізатор вирішує використовувати загальний алгоритм замість аналізу запиту, коли існує кілька критеріїв приєднання.

Таким чином, ні, ні, ні, ні. Ніколи, ніколи, ніколи не використовуйте мета. Якщо те, що ви зберігаєте, не є косметичним і ніколи не буде частиною критеріїв запиту.

Він підходить до вашої програми. Якщо ви зберігаєте, скажімо, дату народження кінорежисера, ніж велика справа. Використовуйте мета все, що вам потрібно. Але якщо ви зберігаєте, скажімо, дату виходу фільму, вам буде гарно не використовувати окрему таблицю (або додавати стовпці до таблиці публікацій) і додати індекс до цього стовпця.


1
Так, плагіни, які я розробляю, обробляють користувальницькі дані, такі як події, новини, прес-релізи, пропозиції роботи ... Ззовні "WordPress World" використання таблиць насправді не є можливим. Але поради від WordPress Codex трохи заплутані. Як можна віддавати перевагу серіалізованим фрагментам даних перед нормалізованими / структурованими / індексованими даними?
Нассіф Бургуйг

1
Якщо ви запитаєте середнього розробника WP, він, ймовірно, відповість "використовувати мета" або "використовувати таксономію". І я погоджуюсь, до того моменту, коли вам потрібно зробити запит проти нього. Якщо так, і я вважаю, що це ваш випадок, моя єдина відповідь - додати поля до таблиці публікацій або створити повністю окрему таблицю. Крім того, ви маєте величезні проблеми щодо продуктивності, коли справа стосується запитів і, що ще важливіше, для списків вузлів, сортування вгорі n.
Дені де Бернарді

1
Денис, ти зможеш детальніше розібратися в цьому, я вважаю це дуже інформативним, але хотів би ще трохи даних, чи хтось робив тести ?, які саме основні недоліки та обмеження, дякую.
Вік

6
@Denis - Досить пристрасна пропаганда проти постмета, так? Ви знаєте, що ви рішуче проти православ'я і випадете з доброї милості первосвящеників церкви кодової поезії, якщо ви будете наполегливо говорити, чи не так? :-) Але серйозно ти не вважаєш, що ти трохи перестарався? Це дійсно залежить від того, чи буде десятки тисяч мета-записів чи ні. У багатьох випадках записів для занепокоєння просто не вистачає. Один складний сайт, який я розгортаю, містить близько 10 000 мета-записів із запланованими кількома новими записами, і це чудово (фій, це не блог.)
MikeSchinkel

1
@Denis - Дякую за коментарі. І не зрозумійте мене неправильно, я, мабуть, схиляюся набагато більше до вашої точки зору, але поєднання 1.) годинної дискусії з Меттом у WordCamp Birmingham щодо достоїнств полів, схожих на Pods, і 2.) простоти мета Подав у відставку, щоб зосередити свою увагу на інших питаннях, які я міг би змінити. У WCB я пішов, розуміючи, що поки Метт несе відповідальність, це не зміниться, тому що (я думаю, Метт так захоплений ідеєю меншої кількості таблиць, що не дозволить собі розпізнати нижню сторону індексації на 768 байт ключ. <sigh>
MikeSchinkel

5

Якщо ваш плагін матиме багато даних, то використовувати wp_postmetaНЕ хорошу ідею, як показано нижче:

Взявши за приклад WooCommerce, у магазині з ~ 30 000 продуктами в середньому буде, наприклад, ~ 40 метаданих (атрибутів та всього) на продукт, 5 зображень товару на продукт, а це означає, що буде ~ 4 мета зображення для кожного зображення:

30000 виробів х 40 мета кожен = 1 200 000 рядків wp_postmeta

+

30000 продуктів x 5 зображень кожен x 4 мета зображення для кожного = 600 000 рядків wp_postmeta

Тож із лише 30 000 продуктів ви шукаєте, що мають 1800000 рядків wp_postmeta.

Якщо ви додасте більше властивостей до своїх продуктів або зображенням товарів, це число збільшиться.

Проблема з цим двояка:

  • Самостійні приєднання є дуже дорогими для MySQL
  • wp_postmetaтаблиця не індексується, якщо ви не використовуєте пізніші версії mysql (тобто немає індексу FULLTEXT для meta_value)

Щоб навести приклад із фактичного випадку:

SELECT meta_value FROM wp_postmeta WHERE meta_key LIKE '_shipping_city'

Це вибирає місто доставки з усіх реквізитів замовлення, одержуючи колосальні ~ 3 секунди на спеціальному сервері початкового рівня, навіть якщо є 5-10 замовлень . Це пояснюється тим, що запит запускається з-поміж wp_postmetaтаблиці, у якій в реальній інсталяції розміщено ~ 3 мільйони рядків.

Навіть домашня сторінка виходить досить повільною, тому що тема тягне за собою різні елементи wp_postmeta- слайдери, кілька вставок для огляду, кілька інших мета. Загалом перелік продуктів дуже повільний, пошуки аналогічно повільні при переліку продуктів.

Ви не можете це виправити будь-якими звичайними засобами. Ви можете помістити Elastic Search на свій сервер і використовувати плагін Elastic Search в Wordpress, ви можете використовувати Redis / memcached, ви можете використовувати хороший плагін кешу сторінки, але врешті-решт фундаментальна проблема залишиться - отримання будь-якої кількості даних із роздутого wp_postmetaстіл буде повільним, коли це робиться. На сервері, де я тестував рішення, яке я реалізував нижче, усі вони були встановлені та налаштовані належним чином та оптимізовані, і сайт працював приємно ОК для не ввійшли користувачів та звичайно виконаних запитів з моменту запуску кешування плагінів.

Але в той момент, коли користувач, який увійшов у систему, намагався зробити щось, що зазвичай не робиться, або крони, кешування плагінів чи будь-яка інша утиліта хотіла отримати фактичні дані з db, щоб кешувати їх чи робити щось інше, все пішло повільно.

Тому я спробував щось інше:

Я зашифрував невеликий плагін, щоб перенести всі мета продукту (postmeta для продукту типу повідомлення ) до спеціальної таблиці, згенерованої за кодом. Цей плагін взяв усі мета для кожної публікації та створив таблицю, додавши кожен мета у вигляді стовпців та вставляючи значення у кожен рядок. Я перетворив формат EAV в горизонтальний, плоский реляційний формат. У мене також був плагін, щоб видалити постмета з усіх переміщених продуктів із wp_postmetaтаблиці.

Поки я перебуваю на цьому, я перемістив вкладений файл postmeta та мета інших типів публікацій у свої власні таблиці.

Потім я зачепився у get_(post_type)_metaфільтр, щоб замінити пошук метаданих, щоб подати їх з нових спеціальних таблиць.

Тепер той самий запит з попереднього часу, на який пішло ~ 3 секунди, wp_postmetaзаймає ~ 0,006 секунди. Зараз сайт поводиться так, ніби це була свіжа установка WP.

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

Природно, що робити речі Wordpress краще. Це фактично норма.

Однак також очевидно, що таблиця EAV дуже неефективна в масштабуванні. Вона нескінченно гнучка і дозволяє зберігати будь-які дані, але ціна, яку ви платите за це, - це продуктивність. Це фундаментальна компроміс.

У цьому контексті важко сказати тому, хто має намір мати купу даних і - не дай бог - запитувати / шукати ці дані, щоб wp_postmetaточно використовувати таблицю. Спектакль буде чудовим.

Використання власних таблиць дозволить вашим даним накопичуватися та залишатися досить швидкими.

Так само, як Піппін Вільямс, творець плагіна Easy Digital Downloads, згадав, що він буде використовувати власні таблиці, якщо він тільки починає кодувати свій плагін, якщо ви збираєтеся створити щось, що буде використовуватися протягом тривалого часу або накопичити багато даних, ефективніше використовувати власні таблиці, якщо ви їх добре розробили.

Ви повинні переконатися, що будь-який інший розробник плагінів / аддонів має засоби підключити ваш плагін, щоб маніпулювати вашими даними до і після отримання даних. Якщо ви це зробите, то ви досить тверді.


1
Цікаві речі! Слід уточнити, що згаданий фільтр "get_ (post_type) _meta" насправді називається "get_ (meta-type) _metadata", де мета-тип - це посада, коментар або користувач. Тому get_post_meta () пройде через фільтр get_post_metadata, незалежно від типу публікації. Повертальне значення фільтра - це те, яким ви хочете бути кінцевим мета-значенням.
Беренд

get_ (мета-тип) _metadata -> він дійсно працює з усіма типами публікацій, і кінцева функція, яку відвідують, - це get_post_metadata. Однак фільтр працює, коли ви все-таки використовуєте його.
єдність100

2

Це залежить від того, що ти робиш. Спосіб WP полягає у використанні існуючих таблиць, оскільки вони були розроблені досить гнучко, однак періодично ви отримуєте новий клас даних, який неможливо розмістити в існуючій таблиці, наприклад, якщо ви хотіли метадані категорії категорії. , ви можете створити таблицю wp_termsmeta.

Однак зазвичай ви можете зберігати свої дані досить зручно в різних таблицях, які існують, і де ви зберігаєте свої дані, залежить від того, що робить ваш плагін.

  • Для загальних налаштувань плагіна використовуйте виклик API get_option () - це також буде кешовано.
  • Для налаштувань плагіну для певної публікації використовуйте спеціальні метадані на кожну публікацію за допомогою get_post_meta () . Зазвичай це багато для того, що вам потрібно.

Кешування реалізовано в рамках WordPress, щоб також пришвидшити час відповіді.


1

погодився з денісом 100%. Але є спосіб її обійти.

Проблема з використанням мета meta для значень, що підлягають запиту, полягає в тому, коли значення є масивом тощо.

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

Це зберігається в db як серіалізований рядок, який буде виглядати приблизно так:

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

Отже, коли ви хочете запитувати всі повідомлення, array['key2'] = 'val 2'тоді wp повинен витягти кожен мета-запис, який називається масив, розпакуйте його, потім протестуйте його, а потім перейдіть до наступного. Це безумовно знищить ваш сервер, якщо ваш сайт успішний і має багато публікацій, сторінок, користувацьких публікацій тощо.

Рішення залежить від проекту, і ви побачите чому. Якщо ви зберігали дані як var = valтоді, wp зможе шукати, не маючи php, щоб розпакувати кожен тест. Для цього у вищезазначеному сценарії ви використовуєте деякий простір імен та зберігаєте мета-клавіші:

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

тоді wp, шукаючи ключ 2 з val 2, зможе витягнути його відразу. Це проект залежно від цього. Мій поточний проект покладається на приблизно 20 різних типів даних, які потрібно зберігати з кожною власною публікацією, тому вищезазначене просто створить масивну таблицю для пошуку, бачачи, як ми очікуємо 100 тисяч публікацій. Тож у такому сценарії користувацька таблиця - єдиний спосіб.

Сподіваюся, що це комусь допоможе


0

Для свого сайту FarmVille :) Я зробив і те, і ніколи не закінчив, тому що продав його:

  1. Я прочитав Farmville xml і скинув дані у користувацьку таблицю
  2. У WordPress у мене були автоматично створені спеціальні поля для кожного поля в цій таблиці (і деякі додаткові)
  3. Тепер турбуйтеся про те, що станеться, якщо значення зміниться або в таблиці, або з іншого боку: спеціальне поле, оскільки їм потрібно постійно синхронізувати

Я зробив це, тому що хотів, щоб, з одного боку, користувачі редагували сайт wordpress, вводячи нові дані Farmville, наприклад, "корова коштує 10 монет", АЛЕ з боку інтеграції: Якщо зміна xml ment корова тепер коштує "20 монет" (через плагін для редагування на передньому кінці), який буде наданий як варіант після нього: щоб або XML АБО користувач мав рацію (на зразок системи wiki).

Тож ось приклад, коли використовується обоє.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.