Здраствуйте уважаемые гуру и монстры парсера. Объясните пожалуйста несколько моментов с хешами кому не сложно... Раньше с ними как-то не работал, хватало таблиц, но сегодня решил разного рода данные хранящиеся в куки пихать не в таблицу, а в хеш. Прочитал документацию и честно говоря вошел в ступор, как то не укладывается у меня все в голове, поправьте если не прав... Если с обычным хешем все понятно, так как фактически это таблица из двух столбцов и обращение к любой записи происходит по принципу ^table.locate[столбец всегда тот который содержит ключи;ключ] причем выдаем значение не этого столбца, а соседнего. Но вот я наткнулся на такую конструкцию:
Если да, то как тут будет работать foreach? Просьба не кидать помидорами если спросил элементарную вещь, но лучше спросить чем чувствовать себя идиотом... Заранее спасибо за ответ.
Вы попробуйте сделать foreach и все станет понятно.
И хеш - это НЕ таблица из двух столбцов. Основное отличие состоит в том, что значение элемента хеша может быть любым парсеровским объектом (в том числе и другим хешем, что в примере и показано), а таблица может содержать исключительно строки.
Обязательно попробую, сейчас пока пытаюсь осознать сам принцип... Т.е. значением может быть и картинка и таблица и строка и любой пользовательский метод? Я правильно понял? Честно говоря пока вопросов больше чем ответов в хелпе... Заранее спасибо за ответ.
name_1, name_2 неизвестны к ним надо как-то обратиться foreach естественно дает ошибку :( Более того name_1 и name_2 необходимо использовать как значение переменной... Можно еще как то выкрутиться создав два хеша. В первом имена вложенных хешей второго, его перебирать и от него и адресоваться.
А если появится еще и name_3 который не хеш в хеше, а просто элемент хеша, причем и его ключ и значение используются в переменных, вообще не представляю что делать. Хотя может имеет смысл в таком случае использовать таблицу?
foreach естественно дает ошибку для foreach вовсе не естественно давать ошибку. ошибку может давать код, который согласно написанному, должен делать что-то странное (например "печатать" в output хэш). вы попробуйте в foreach выводить просто ключи.
кроме того, когда речь идёт про ошибки, тут принято приводить код, который к этим ошибкам привёл. без кода обсуждать совершенно нечего.
name_1, name_2 неизвестны к ним надо как-то обратиться вообще-то основное назначение хэшей -- быстро получить значение по ключу (это делается гораздо быстрее, чем через locate у таблицы). т.е. так:
$хэш.ключ1.ключ2.ключ3
значение ключа может быть в переменной:
$хэш.ключ1.[$переменная_с_именем_ключа2].ключ3
в вашем случае, вы похоже пытаетесь в лоб заменить таблицу на хэш, но я не понимаю, зачем вам это потребовалось. если таблицы вас устраивают, то хэши для решения _тех-же_ задач использовать незачем.
Сорри виноват, конечно тут нет экстрасенсов... И так задача: Есть корзина интернет магазина с разноплановым товаром, причем у товара кроме одинаковых полей типа id-модели, id-цвета, цены, количества, есть еще такие поля как например цвет, который может быть, а может и отсутствовать, или например количество у какого-то товара может быть в единицах, а может быть и например в квадратных метрах причем количество дробное, или как еще вариант комплект чего-то котрый состоит из нескольких единиц и т.д и т.п. Как использовать в данной ситуации таблицу я пока не придумал. А вот "разнородный" хеш вида:
Для этой задачи помоему наиболее подходящий вариант, так как таблица преполагает однородность данных. Возможно я конечно не прав, был бы крайне признателен за совет, может уже кто-то реализовывал такие задачи и есть более оптимальный путь, а я в силу неопытности опять все делаю далеко не самым простым способом. Да, спасибо за совет выводить просто ключи, так работает...
ваша задача всё равно не является той задачей, для которой действительно требуется применение хэша. попробую проиллюстрировать его использование на задаче вывода сообщения с тэгами.
сообщения, выводимые на страницы, находятся в таблице $tMessage (id, content) (это может быть и хэш, но мне, ввиду однородности данных, больше нравится таблица). теги -- в таблице $tTag (id, name).
а в таблице $tMessageToTag хранятся связи (message_id, tag_id). можно сразу доставать эти связи в виде хэша, но в этой демонстрации я буду использовать эти данные разными способами, поэтому для удобства демонстрации они в таблице.
для начала на основании таблицы $tMessageToTag формируем такой хэш:
тут ключ первого уровня -- message_id, ключ второго -- tag_id. значение -- просто чтоб было (можно с пустыми значениями, но тогда проверка ниже будет немного другой).
кстати подобную структуру в хэше бывает очень неудобно получать на основе данных, которые достаются из БД, поэтому иногда структуру хеша делают иной (с составным ключом):
тут первая часть ключа (до разделителя, который я выбрал в виде символа '=') -- message_id, вторая часть -- tag_id. подобный "плоский" хэш может быть получен из таблицы, полученной из БД с помощью единственной команды (будет получен хэш в котором более сложные значения, но на работоспособность подхода это не влияет):
код проверки наличия у сообщения определённого тэга меняется на следующий:
^if($hMessageToTag.[$tMessage.id=$tTag.id]){...}
но приведённый выше подход в общем случае плох. проблема в том, что у нас есть вложенный цикл с проверкой. если тэгов существенно больше, чем привязок, то внутренний цикл будет крутиться вхолостую, поэтому для устранения повторяющегося внутреннего холостого цикла лучше сделать [B]хэш таблиц[/B] с ключами message_id, а структуру с тэгами перевести в хэш (или сразу доставать из БД как хэш):
при помощи хеша хотел упростить проверку на наличие товара уже в корзине при попытке добавить второй раз одно и то же, и упростить процедуру удаления из корзины, т.е. банально хотел уйти от ^table.locate . Да и чего уж там греха таить хотел попробовать поработать с хешами т.к. раньше их не трогал... Но сейчас вижу что это была не самая лучшая идея, для этой задачи возможно лучше подходит таблица пусть с избыточным количеством полей...
Мне показалось, что корзину удобнее хранить на сервере (две простенькие таблички для самих корзин и товаров в них), а в куках только идентификатор. В это позволяет безболезненно снимать товары с продажи (просто перемещаем их в "отложенные"), хранить дополнительную статистику и стоимость корзины (чтобы не возиться с этим при каждом запросе) и т.д. и т.п. Опять же корзина может быть неплохим идентификатором клиента, поскольку мы специально сделали работу с заказами без регистрации. Опять же нет проблемы с ограничением на размер кук.
При 1000 посетителей в день, добавивших в корзину по одному товару, через месяц 30 тысяч записей... По какому принципу вы их удаляете если клиент не удалил их сам? Можно конечно удалять записи кроном через какое-то время, но я планирую там хранить и некоторые настройки, например региональные... Хотя возможно имеет смысл принять стратегическое решение что если клиент ничего не сделал за месяц то это потерянный клиент и хранить его данные не стоит...
Современные базы данных могут хранить в таблицах десятки и сотни миллионов записей совершенно без проблем. Кроме того, никто нам не мешает использовать технологии шардинга и денормализации данных, но до этого, даже при тысячах посетителей в день, дойдет не скоро.
Я понимаю что хранить можно, но зачем хранить в базе мусор, рано или поздно это приведет не к очень хорошей ситуации... Я помню как года три назад в базе данных паспортно-визовой службы краснодарского края закончился диапазон чисел для автоинкремента, была большая проблема... Кстатит а что такое технология шардинга и денормализация данных? И еще, поделитесь пожалуйста опытом по какому принципу реализован поиск по Вашему сайту. Заранее спасибо за ответ.
Он нисколько не уменьшится, если удалить записи. Если вдруг не будет хватать 4 млрд. значений int unsigned, то всегда можно использовать bigint unsigned в качестве ключа - это очень много для любого магазина (64 bit, max = 18446744073709551615). :) Если и этого не хватит, то можно перейти на uuid (128 бит).
Поиск я реализовал через , из Парсера обращаюсь к нему через .
...что такое технология шардинга и денормализация данных?
Думаю про это лучше спросить у Яндекса - тема очень обширная. :)
Вы знаете, я пару дней подумал и наверно воспользуюсь все-таки Вашим методом, т.е. буду хранить у пользователя только ключ... Если Вы не против я буду задавать вопросы в случае их возникновения...