Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

получение имен таблиц из SQL запроса (Rin)
Author Message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Tue Dec 19, 2006 6:36 pm ()
   Post subject:
Reply with quote


М

Выделено из темы «DbSimple v2.x: лаконичная работа с различными СУБД»,
расположенной в форуме Конструктор (20 Декабря 2006, 23:07).
Back to top
View user's profile Send private message Send e-mail
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 184
   поощрить/наказать

Location: Москва

PostPosted: Tue Dec 19, 2006 6:36 pm (спустя 1 секунду; написано за 6 минут 48 секунд)
   Post subject: получение имен таблиц из SQL запроса
Reply with quote

Константин Жинько [tIT] wrote:
Rin wrote:
Зачем вообще нужно указывать время кеширования?
Отвечаю на Ваш вопрос: затем, что не все базы данных спроектированы с возможностью получать этот самый modified - либо такого поля просто нет, либо нет доступа и т.д и т.п.
Поле `modified` можно создать (тип Timestamp) ручками.
Все таки не ясно, зачем удалять кеш по истечению времени жизни, если данные в БД не изменились.
В MySQL-4.1.x и выше кеш запросов уже есть.

Last edited by Rin on Thu Dec 21, 2006 10:46 am; edited 2 times in total
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Wed Dec 20, 2006 12:00 am (спустя 5 часов 23 минуты; написано за 33 секунды)
   Post subject:
Reply with quote

Не хотите удалять - поставьте время жизни равным 100 лет.
Давайте закончим пустые споры. Время жизни нужно, и точка.
Back to top
View user's profile Send private message Send e-mail
Андрей Анатольич
Guest





Карма: 388
   поощрить/наказать


PostPosted: Wed Dec 20, 2006 1:30 pm (спустя 13 часов 30 минут; написано за 5 минут 16 секунд)
   Post subject:
Reply with quote

А что если сделать кэширование следующим образом:
Code (php): скопировать код в буфер обмена
$Db->startCache();
$Db->select("SELECT * FROM `table1` AS t1 INNER JOIN `table2` AS t2 ON (t1.id = t2.key)");
$Db->endCache();
Результаты запроса сохраняется в файл вида table1-table2@<MD5_ХЭШ_SQL_ЗАПРОСА>
Затем, когда выполняются запросы типа INSERT, UPDATE, DELETE, TRUNCATE и прочие, для таблиц table1 и table2, то мы
просто очищаем кэш этих таблиц.

Таким образом, нам не нужно будет выставлять время хранения кэша, все будет делаться автоматически при обновлении таблицы.
Что скажете?
Back to top
Андрей Анатольич
Guest





Карма: 388
   поощрить/наказать


PostPosted: Wed Dec 20, 2006 1:37 pm (спустя 7 минут; написано за 1 минуту 12 секунд)
   Post subject:
Reply with quote

[off]
Кстати, не зарегистрированный пользователь, почему мне в ссылку на имени поставился какой-то левый УРЛ (www.whatisthematrix.com/). Баг?
[/off]
Back to top
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Wed Dec 20, 2006 3:11 pm (спустя 1 час 33 минуты; написано за 1 минуту 23 секунды)
   Post subject:
Reply with quote

Андрей Анатольич wrote:
А что если сделать кэширование
Кэширование уже сделано. Не надо его еще раз "сделать".
Андрей Анатольич wrote:
когда выполняются запросы типа INSERT, UPDATE, DELETE, TRUNCATE и прочие, для таблиц table1 и table2, то мы
просто очищаем кэш этих таблиц
В принципе, эту логику можно было бы реализовать, если бы не одно "но": выдрать из SELECT-а список таблиц, которые он использует, нельзя, не будущи при этом SQL-сервером. Кроме того, теряется возможность изменять БД сторонними программами, не использующими DbSimple.
Back to top
View user's profile Send private message Send e-mail
Константин Жинько [tIT]
Сотрудник «Лаборатории»



Joined: 12 Jun 2004
Posts: 2264
Карма: 106
   поощрить/наказать

Location: Москва

PostPosted: Wed Dec 20, 2006 4:51 pm (спустя 1 час 40 минут; написано за 1 минуту 9 секунд)
   Post subject:
Reply with quote

Дмитрий Котеров wrote:
Кроме того, теряется возможность изменять БД сторонними программами, не использующими DbSimple.
Возможность то остается. Только на очистку кэша стороннее изменение не повлияет - это главный аргумент против.
Дмитрий Котеров wrote:
Кэширование уже сделано. Не надо его еще раз "сделать".
=)))))
Back to top
View user's profile Send private message
Андрей Анатольич
Guest





Карма: 388
   поощрить/наказать


PostPosted: Wed Dec 20, 2006 7:09 pm (спустя 2 часа 18 минут; написано за 4 минуты 17 секунд)
   Post subject:
Reply with quote

Дмитрий Котеров Почему нельзя выдрать список таблиц из селекта? Это же довольно просто парсится. Или я где-то ошибаюсь?
В своей реализации класса для работы с БД MySql я сделал именно такое кэширование, и оно работало без глюков. Но, конечно, на каких-нибудь экзотических селектах мое кэширование может и сломается.

Кстати, можно ли с помощью встроенного в DbSimple кэширования, кэшировать список последних обновленных тем с форума? Тут же мы не знаем, какой expires выставлять для кэша, так как список тем может обновиться в любой момент.
Back to top
Константин Жинько [tIT]
Сотрудник «Лаборатории»



Joined: 12 Jun 2004
Posts: 2264
Карма: 106
   поощрить/наказать

Location: Москва

PostPosted: Wed Dec 20, 2006 7:36 pm (спустя 26 минут; написано за 12 минут 25 секунд)
   Post subject:
Reply with quote

Андрей Анатольич wrote:
Это же довольно просто парсится.
Ну попробуйте распарсить это:
Code (SQL): скопировать код в буфер обмена
SELECT
  ds.*,
  u.id AS author_id,
  u.name AS author_name,
  u.mail AS author_mail,
  (SELECT COUNT(*) FROM bug_list bl2 WHERE bl2.user_id=u.id) AS author_bug_cnt
FROM (
  SELECT
    b.id,
    b.level,
    b.sys_id,
    bl.user_id,
    b.name,
    b.description,
    i.data AS image,
    f.data AS script_source,
    (SELECT COUNT(*) FROM comments c WHERE c.id=b.id) AS comments_cnt
  FROM bug_list bl, bug b
    LEFT JOIN attach a ON a.id=b.attach_id
    LEFT JOIN images i ON a.image_id=i.id
    LEFT JOIN files f ON a.file_id=f.id
  WHERE bl.id=b.id
  ORDER BY b.post_date DESC) ds, user u
WHERE u.id=ds.user_id
ORDER BY ds.level ASC
Back to top
View user's profile Send private message
WingedFox
Профессионал



Joined: 29 Apr 2003
Posts: 4064
Карма: 269
   поощрить/наказать

Location: Питер

PostPosted: Wed Dec 20, 2006 9:08 pm (спустя 1 час 32 минуты; написано за 16 секунд)
   Post subject:
Reply with quote

Code (any language): скопировать код в буфер обмена
<textarea id="aaa">SELECT
  ds.*,
  u.id AS author_id,
  u.name AS author_name,
  u.mail AS author_mail,
  (SELECT COUNT(*) FROM bug_list bl2, aa asdf WHERE bl2.user_id=u.id) AS author_bug_cnt
FROM (
  SELECT
    b.id,
    b.level,
    b.sys_id,
    bl.user_id,
    b.name,
    b.description,
    i.data AS image,
    f.data AS script_source,
    (SELECT COUNT(*) FROM comments c WHERE c.id=b.id) AS comments_cnt
  FROM bug_list bl, bug b
    LEFT JOIN attach a ON a.id=b.attach_id
    LEFT JOIN images i ON a.image_id=i.id
    LEFT JOIN files f ON a.file_id=f.id
  WHERE bl.id=b.id
  ORDER BY b.post_date DESC) ds, user u
WHERE u.id=ds.user_id
ORDER BY ds.level ASC</textarea>
<script>
var a = document.getElementById('aaa').value
   ,b
   ,c = []
   ,r = /(?:FROM\s+(.*?)\s+WHERE|JOIN\s+(.*?)\s+ON)/;

while (b = a.match(r)) {
  a = a.replace(r,"");
  var tmp = (b[1]||b[2]).split(",");
  for (var i=0;i<tmp.length;i++) {
    c[c.length] = tmp[i].replace(/^\s*|\s*$/,"").split(" ")[0].replace(/\s/,"");
  }
}
alert(c.join("\n"));
</script>
Back to top
View user's profile Send private message
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 184
   поощрить/наказать

Location: Москва

PostPosted: Wed Dec 20, 2006 9:31 pm (спустя 22 минуты; написано за 1 минуту)
   Post subject:
Reply with quote

Шустрый, однако.
Еще нужно добавить обработку строк ("test", 'test') и backticks (`test`).
Back to top
View user's profile Send private message Send e-mail
WingedFox
Профессионал



Joined: 29 Apr 2003
Posts: 4064
Карма: 269
   поощрить/наказать

Location: Питер

PostPosted: Wed Dec 20, 2006 10:41 pm (спустя 1 час 9 минут; написано за 23 секунды)
   Post subject:
Reply with quote

Rin
В смысле - сделать им trim("\"'`")?
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Wed Dec 20, 2006 11:05 pm (спустя 23 минуты; написано за 23 секунды)
   Post subject:
Reply with quote

Ню-ню.
Code (SQL): скопировать код в буфер обмена
SELECT 'SELECT 1 FROM tbl' AS TABLE
Back to top
View user's profile Send private message Send e-mail
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 184
   поощрить/наказать

Location: Москва

PostPosted: Thu Dec 21, 2006 10:42 am (спустя 11 часов 37 минут; написано за 1 минуту)
   Post subject:
Reply with quote

Вообще-то я не создавал эту тему, да Андрей Анатольич?! :)
Back to top
View user's profile Send private message Send e-mail
Андрей Анатольич
Guest





Карма: 388
   поощрить/наказать


PostPosted: Thu Dec 21, 2006 4:58 pm (спустя 6 часов 15 минут; написано за 1 минуту 37 секунд)
   Post subject:
Reply with quote

Так то да, если имя таблицы заранее неизвестно, а генерируется SQL запросом то тут уж его не выдернуть. Надо быть SQL сервером, ага.
Я просто не встречал до сегодняшнего дня таких запросов, которые берут имена таблиц из SQL запроса ). Так бы сразу и объяснили )
Back to top
Андрей Анатольич
Guest





Карма: 388
   поощрить/наказать


PostPosted: Thu Dec 21, 2006 5:32 pm (спустя 34 минуты; написано за 4 минуты 6 секунд)
   Post subject:
Reply with quote

Как прикол:
Если мы определяем, что имя таблицы заранее неизвестно (preg_match('/FROM\s+(\s*SELECT\+/i', $query)), то не кэшируем этот запрос и выдаем ворнинг )

----------------
Из официальной документации:
Quote:
Здесь (dklab.ru/lib/DbSimple/#list42) предполагается, что в таблице forum имеется столбец с именем modified, хранящий дату последнего изменения записи (аналогично и с таблицей topic). Как только в указанных таблицах появляется новая запись, библиотека это обнаруживает, делая запрос SELECT MAX(forum.modified) FROM forum, и очищает кэш.
Я что-то не понимаю, или, если мы применяем встроенное в DbSimple кэширование, то нам тоже обязательно нужно знать имя каждой таблицы, используемой в запросе, для корректной инвалидации кэша?
Back to top
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 184
   поощрить/наказать

Location: Москва

PostPosted: Fri Dec 22, 2006 12:38 pm (спустя 19 часов 5 минут; написано за 48 секунд)
   Post subject:
Reply with quote

Перечисление таблиц является необязательным дополнительным условием.
Back to top
View user's profile Send private message Send e-mail
Константин Жинько [tIT]
Сотрудник «Лаборатории»



Joined: 12 Jun 2004
Posts: 2264
Карма: 106
   поощрить/наказать

Location: Москва

PostPosted: Fri Dec 22, 2006 1:21 pm (спустя 43 минуты; написано за 25 секунд)
   Post subject:
Reply with quote

Rin wrote:
Перечисление таблиц является необязательным дополнительным условием.
И не таблиц, а их полей (-;
Вскоре будет добавлена возможность задавать собственные валидаторы.
Back to top
View user's profile Send private message
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 184
   поощрить/наказать

Location: Москва

PostPosted: Sat Dec 23, 2006 2:19 pm (спустя 1 день 58 минут; написано за 11 минут 43 секунды)
   Post subject:
Reply with quote

А, ну да, если быть точным, имя_таблицы.имя_поля. :)

Ради интереса, я написал достаточно надежную функцию для получения имен таблиц из сложного "SELECT..." запроса, которая, к тому же, работает довольно быстро (менее 0.01 секунды).

Вышеприведенный SQL запрос обрабатывается без проблем.
Хотел бы еще протестировать как следует.
Прошу покидать сюда немного SQL запросов (2-3 шт.), можно изощренных синтетических.
Особенно интересуют запросы в диалекте Ibase и Postgre.
Чуть позже выложу исходники.

А разработчикам DBSimple это интересно? :)
Back to top
View user's profile Send private message Send e-mail
Андрей Анатольич
Guest





Карма: 388
   поощрить/наказать


PostPosted: Sat Dec 23, 2006 3:06 pm (спустя 46 минут; написано за 22 секунды)
   Post subject:
Reply with quote

Rin
Ваша функция выдирает подзапрос из SQL запроса, и получает имя таблицы?
Back to top
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 184
   поощрить/наказать

Location: Москва

PostPosted: Mon Dec 25, 2006 3:59 pm (спустя 2 дня 53 минуты; написано за 1 минуту 27 секунд)
   Post subject:
Reply with quote

А вот и функция:

sql_tables: возвращает имена таблиц, используемых в SQL запросе (forum.dklab.ru/viewtopic.php?p=126322)
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML