Заигравка с функции за низове в MySQL
Обикновено при разработването на галерия от изображения, се налага да имаме поне две изображения - умалено (thumb-nail) и с нормален размер. Един от начините е посредством функциите на графичната библиотека да генерираме умаленото изображение(начин консумиращ известно количество памет, често надвишаващо стойността на memory_limit директивата в PHP.INI), като в базата от данни пазим само името на оригиналното а умаленото именуваме с някаква наставка (примерно _thumb). Разбира се съществуват и други начини, като съхраняване на цялото изображение в поле от таблицата, но тук става дума само за първия.
Нека приемем, че имаме следната структура на таблица “picture”
CREATE TABLE `picture` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`url` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Също така, нека приемем, че уеб сървърът е доста натоварен и искаме да го освободим от малко работа, която така или иначе може да свърши(а и в повечето случаи е по-добре да свърши) и MySQL сървъра. Принципно въпросното количество работа в общия случай се върши по-бързо от MySQL сървъра.
Т.е. в текущия случай, целта на задачата, е посредством функциите на MySQL за работа с низове да изградим името на умаленото изображение, което после да използваме директно като част от стойността на атрибута src на IMG елемента.
Ето един вариант как може да се реализира това.
SELECT
url as image,
CONCAT(SUBSTRING(url, 1, LENGTH(url)-LOCATE(".", REVERSE(url))), "_thumb", RIGHT(url,LOCATE(".", REVERSE(url)))) as thumb
FROM
picture;
И естествено резултата от изпълнението на SQL заявката:
+----------------------------+----------------------------------+
| image | thumb |
+----------------------------+----------------------------------+
| testasdas.adasd.asdasd.jpg | testasdas.adasd.asdasd_thumb.jpg |
| test.jpg | test_thumb.jpg |
+----------------------------+----------------------------------+
2 rows in set (0.02 sec)
Убеден съм, че въпреки ограничения брой на функциите на MySQL за работа с низове (известна част от които са псевдоними) тази задачка може да се реши по няколко различни начина.
Решавал съм този проблем(задачка) с PHP функцията strrpos, но в MySQL няма функция, която връща последната поява на низ в друг низ и въпреки, че не съм религиозен се сетих за онези думи от евангелието “Последните ще станат първи” и за функцията REVERSE() на MySQL, която ми помогна да изпълня божиите слова.
Извода е: Натоварaвйте MySQL сървъра, той “носи на бой” ![]()
Data too long for column
Твърде рано се зарадвах на новия MySQL. Веднага след инсталацията импортирах базите от данни от стария сървър, тествах няколко от приложенията си за които знам, че са с по-сложнички заявки, тествах дали данните на кирилица са се импортирали добре и останах доволен. Какво обаче се случи с един от проектите върху които работя…
След опит да се вмъкне текст в поле на кирилица, ако е над определени символи (доста под зададените при дефиницията на полето), MySQL ми връща грешка:
Data too long for column 'subject' at row 1
Мдаа… кофти работа. Набързо правя преглед на наборите от знаци:
SHOW VARIABLES LIKE 'char%';
Всичко ОК, и в phpMyAdmin, и от уеб приложението:
character_set_client utf8
character_set_connection utf8
character_set_database utf8
character_set_filesystem binary
character_set_results utf8
character_set_server utf8
character_set_system utf8
Преглеждам набързо наборите от знаци на базата от данни, на таблиците, на полетата - всичко ОК (utf8_general_ci).
Точно заради подобни мизерийки винаги си пускам по една заявка
SET NAMES 'utf8'
Реших, че явно проблема не е толкова тривиален потърсих в google:
http://bugs.mysql.com/bug.php?id=13139
http://bugs.mysql.com/bug.php?id=16209
http://bugs.mysql.com/bug.php?id=17872
http://bugs.mysql.com/bug.php?id=18908
Мда… още по-кофти е от колкото предполагах. Явно не съм сам. За съжаление твърде късно ми хрумна идеята да вкарам запис от phpMyAdmin-а. Стана. Явно проблема беше в моя телевизор.
Та започнах да си гледам телевизора, като беше ясно, че проблема е или в Модела или в Контролера (MVC Архитектура). Погледнах в Модела заявката, която се генерира - текста счупен. Погледнах в Контролера - там текста ок. Значи предава Контролера данните на Модела и той ги скапва.
След кратък анализ се оказа, че проблема е във htmlentities и по-специално факта, че не съм предал като трети параметър ‘UTF-8′. Интересното тук е, че никога не ми се е налагало да правя това, но сега това се оказа “препъни камъка” в цялата тази овертюра при търсенето на виновника.
Въпросът ще трябва да се проучи допълнително!
Ъпгрейд на MySQL и phpMyAdmin
След като по разни причини не успях да отида до Враца с едната група ентусиасти (на палатки или в хотел) и не успях да отида на палатки (с велосипеди) край с. Бесарбово с другата група не по-малки ентусиасти, реших, че е крайно време да си обновя стария MySQL 4.1.11 до 5.0.24. Прехода мина изключително плавно.
mysqldump --opt --all-databases -uroot -p > server.sql
и после
mysql -uroot -p < server.sql
Отдавна не бях обновявал превода на phpMyAdmin а сега ми се отдава възможност благодарение на MySQL 5, да видя известно количество низове, които при 4-ката не се появяваха. Доста е трудно да се превеждат низовете на потребителски интерфейс на софтуер, без да го виждаш и без да знаеш в какъв контекст се използват съответните изрази.
Изтеглих си най-актуалния phpMyAdmin (2.8.2.2), последната версия на езиковия файл от CVS-а и започнах. Забелязах, че отново на разни места липсват низове, не знам каква е причината, но е гадно когато видиш поле за отметка без текст, особено при експортиране. Открих ги, добавих променливките от английската версия, попреведох някой друг низ, прегледах и старите неща които съм превеждал - винаги се намира по някое и друго низче което не звучи много ясно и еднозначно. Естествено появиха се и интересни термини за превод като “plugin” “приставка” - звучи добре.
Като се поосвободя, пак. Ако някой (надали някой ми чете бозите, но все пак) намери проблем при превода да свирка. Знам колко е дразнещо, когато при интрфейс на български нещо не е преведено добре.