Хранение задаваемых полей и немного об индексах MySQL
Иногда возникает задача хранить какие-то свойства большого количества разнородных объектов, которые никогда не будут участвовать в условиях выборки или сортировке, но которые могут добавляться/исчезать по мере развития сайта. Например, к таким свойствам относятся задаваемые поля профиля пользователя на форуме, настройки сайта в целом, какие-то опции отдельных страниц этого сайта.
В такой ситуации можно использовать универсальную таблиц для всех настроек, которая будет иметь следющую структуру:
type : enum(’user’,'page’,’site’) (признак, кому принадлежит данная настройка: сайту, пользователю или странице, вместо типа enum можно использовать tinyint, чтобы не изменять структуру таблицы, если появятся новые типы объектов),
id : int (идентификатор пользователя или страницы)
name: varchar(24) (название опции)
value: varchar(255) (значение опции).
Выборка всех свойств какого-либо объекта из такой таблицы осуществляется запросом вида SELECT name, value FROM options WHERE id=”идентификатор_объекта” AND type=”тип_объекта”. Если число свойств у каждого конкретного объекта не очень велико (не более четырех-пяти десятков), имеет смысл выбирать все свойства данного объекта, и запоминать их на стороне скрипта. Это не сильно увеличит нагрузку на БД при первом запросе, зато потом позволит избежать повторных запросов при чтении других свойств объекта.
Пример такой процедуры на PHP:
function get_opt($name,$id=0,$type='site') {
$result=false;
static $cache; // статическая переменная, в которой кешируются свойства
if (!isset($cache[$type.$id])) {
$sql='SELECT name, value FROM options WHERE type="'.$type.'" AND id='.intval($id);
$res=mysql_query($sql);
while ($data=mysql_fetch_row($res)) $cache[$type.$id][$data[0]]=$data[1];
}
return $cache[$type.$id][$name];
}
При этом для эффективной работы такой таблицы нужно учесть одну тонкость: PRIMARY KEY должен иметь вид (id,type,name), а не (type,id,name), как может показаться на первый взгляд. Для тех типов объектов, для которых id не предусмотрен (например, настройки сайта в целом) следует писать в этот столбец какое-то фиксированное значение, например, ноль, и указывать его в явном виде в условии при выборке свойств (т.е. WHERE id=”0″ AND type=”site”). В этом случае PRIMARY KEY будет задействован при любой выборке. В других же ситуациях (например, без условия id=”0″ PRIMARY KEY вида (id,type,name) при выборке объектов с type=”site” задействоваться не будет вообще, а PRIMARY KEY вида (type,id,name) может быть отброшен как неэффективный в том случае, если объектов какого-то типа будет более 30%, что вполне вероятно).
Если требуется обновить или добавить несколько свойств какого-либо объекта в такой таблице (и не известно, были ли такие свойства заданы ранее), имеет смысл производить это следующим образом:
DELETE FROM options WHERE type=”тип” AND id=”ид_объекта” AND name IN (”свойство1″,”свойство2″,…)
INSERT INTO (type,id,name,value) VALUES (”тип”,”ид”,”свойство1″,”значение1″),(”тип”,”ид”,”свойство2″,”значение2″),….
Таким образом, всего двумя запросами можно обновить или добавить любое количество свойств объекта.
29 апреля 2010 в 11:21
Слесарь-сантехник…
Слесарь-сантехник …
8 октября 2011 в 13:20
only@srzub6.fresh” rel=”nofollow”>.…tnanks for information :o…
9 октября 2011 в 12:28
…
спс 8O…