Форум » [x]Harbour » Посоветуйте странного... » Ответить

Посоветуйте странного...

finder: Доброго времени суток. Требуется совет по такому вопросу. Что лучше использовать для хранения символьных данных переменной длины в базе? 1. Огромное поле с ограничением по максимально возможной длине строки. 2. Несколько записей с умеренно большими полями и слиянием при чтении 3. Отдельная база с N записями и связкой на родительскую. 4. Мемо поле. 5. Отдельные текстовые файлы с привязкой к записи. 6. Ваш совет. Хотелось бы: 1. Максимальная скорость чтения. 2. Поиск по тексту. 3. Работа с LETODB (предпочтительно) или локальная база. 4. MySQL не предлагать. 5. *nix среда. 6. Избавиться необходимости отсекать концевые пробелы на программном уровне. Спасибо. Дополнение - объем полезных данных в поле может быть от сотен байт до десятков-сотен килобайт.

Ответов - 11

Dima: да надо поиграться как быстрее будет. но кажется мне что быстрее будет если все держать в одном поле.

finder: Поиграться можно, но возможно кто-то владеет информацией которую я упустил. Возможно я слишком пространно написал, попробую уточнить. Хотелось бы получить наиболее оптимальное хранилище. Скажем хранить в поле размером 64к данные 1к байт и заставлять отсекать пробелы при чтении или перемалывать пробелы при поиске создает неоправданную нагрузку - в обоих случая будут обрабатываться все символы поля. Сквозной поиск по файлам не особо удобен и при этом возрастает число файловых операций. Мемо поле - как себя будет чувствовать мемо файл при регулярных изменениях поля включая увеличение/уменьшение объема хранящихся в нем данных.

Dima: а каким видом поиска собираетесь пользоваться ? а для чего такое длинное поле ? это база чего если не секрет (автозапчасти или что другое) ? насчет перемалывания пробелов чес слово не понял...... можно привести короткий пример поиска при условии что данные хранятся в одном поле ?


Haz: finder пишет: MySQL не предлагать. А как насчет ADS с его FTS http://devzone.advantagedatabase.com/dz/webhelp/Advantage9.1/advantage_concepts/advantage_functionality/full_text_search.htm т.е. хранить индексированный текст в BLOB ( то же мемо в принципе ) поиск на сервере по индексу

finder: ок, добавляем вводные На текущий момент нет никакой базы, но это может быть любая база содержащая произвольную описательную информацию с одним или несколькими текстовыми полями произвольной длины, где надо найти первое вхождение для записи и сформировать список записей соответствующих запросу. Например возьмем форум, пусть даже этот. - каждое сообщение это текстовое поле, но они все совершенно разного размера - пробелы 1... rtrim() переберет все правые пробелы пока не доберется до символа отличного от пробела, что при размере поля 64к с фактически записанным 1к что выглядит как-то некрасиво, в отличие от варианта когда чтение поля дает переменную уже нужного размера, а если не дай бог понадобится чтобы в конце был(и) пробел(ы)... - пробелы 2... поиск... при переборе записей опять же либо отсекать пробелы потом искать вхождение либо сразу искать вхождение в любом случае перебор идет по длине поля для каждой записи. В случае OrdWildSeek опять же проход лишних пробелов, и не уверен что это будет работать по мемополю. Поиск хотелось бы полнотекстовый, примера пока нет, вот ищу/интересуюсь, хотелось бы что-то более эффективное чем locate, dbskip()/at()... Кстати какие варианты поиска текста по базе доступны в харборе (по маске, регистро(не)зависимый и т.п.), может я выдумываю велосипед... Возможно желания странные, понимаю, что хочу mysql, но все же такой вот интерес. Хотелось бы понять, действительно ли невозможно реализовать работу с базой эффективнее или хотя бы равнозначно по производительности/функционалу чем мускул, при клиент/серверном варианте? Ну нет получается у меня нормально подружиться с этой сссобакой мускульной, будь она неладна...

Dima: finder Примерчик по поиску. [pre2] #include "dbinfo.ch" REQUEST DBFCDX function main(bld,rdd) FIELD F1 local nSec, cBlock, cRegex, cPattern rddsetdefault(iif(empty(rdd),"DBFCDX",rdd)) ? rddsetdefault() set delete on set exclusive off if empty(bld) aeval(directory("_tst.*"),{|x|ferase(x[1])}) dbCreate("_tst", {{"F1", "C", 20, 0}}) USE _tst while lastrec()<100000 dbappend() F1 := strzero(recno(),10)+chr(recno()%26+asc("A")) enddo INDEX ON F1 TAG T1 TO _tst dbcommit() else USE _tst SET INDEX TO _tst endif ordsetfocus(1) ? indexkey(), ordsetfocus() cBLock:={|key,rec|rec%501==0 .and. "Z"$key .and. !deleted()} nSec:=secondscpu() dbgotop() while !eof() if eval( cBlock, ordkeyval(), recno() ) qout( ordkeyval(), recno() ) endif dbskip() enddo nSec:=secondscpu()-nSec ? "SKIP:", nSec, "sec." nSec:=secondscpu() dbgotop() while !eof() if eval( cBlock, ordkeyval(), recno() ) qout( ordkeyval(), recno() ) endif dborderinfo(DBOI_SKIPEVAL,,,cBLock) enddo nSec:=secondscpu()-nSec ? "SKIPEVAL:", nSec, "sec." cBLock:={|key,rec|!deleted() .and. rec%501==0 .and. "Z"$key} nSec:=secondscpu() dbgotop() while !eof() if eval( cBlock, ordkeyval(), recno() ) qout( ordkeyval(), recno() ) endif dborderinfo(DBOI_SKIPEVAL,,,cBLock) enddo nSec:=secondscpu()-nSec ? "SKIPEVAL:", nSec, "sec." cRegex:=".*101.*A" cRegex:=HB_REGEXCOMP(cRegex) nSec:=secondscpu() dbgotop() while !eof() if hb_Regexhas(cRegEx,ordkeyval()) qout( ordkeyval(), recno() ) endif dborderinfo(DBOI_SKIPREGEX,,,cRegex) enddo nSec:=secondscpu()-nSec ? "SKIPREGEX:", nSec, "sec." cPattern:="*101*A" nSec:=secondscpu() dbgotop() if !eof() .and. ! WildMatch(cPattern, ordkeyval()) dborderinfo(DBOI_SKIPWILD,,,cPattern) endif while !eof() if WildMatch(cPattern, ordkeyval()) qout( ordkeyval(), recno() ) endif dborderinfo(DBOI_SKIPWILD,,,cPattern) enddo nSec:=secondscpu()-nSec ? "SKIPWILD:", nSec, "sec." return nil [/pre2]

finder: Dima пишет: Примерчик по поиску. За пример спасибо, но больше интересует поиск по полю без индекса при произвольном активном ключе. Кроме варианта skip+проверка вхождения, что-то более продвинутое в харборе для этого случая имеется? Да и не уверен я, что поля в единицы/десятки килобайт индексировать хорошая идея, хотя тестовый индекс создался, но насколько это будет надежно... Haz пишет: А как насчет ADS с его FTS http://devzone.advantagedatabase.com/dz/webhelp/Advantage9.1/advantage_concepts/advantage_functionality/full_text_search.htm т.е. хранить индексированный текст в BLOB ( то же мемо в принципе ) поиск на сервере по индексу ADS FTS хорошо, но подозреваю что сам ADS не очень бесплатный

Andrey: finder пишет: ADS FTS хорошо, но подозреваю что сам ADS не очень бесплатный Стандартный CDX драйвер тоже может создавать индекс по мемо полю. У меня так в программе строится условный индекс по нужным записям. Очень быстро строиться.... Может и по BLOB тоже можно, не проверял. Нужно тестировать. Прямой путь на LetoDB с такими требованиями. Без тестов ничего не узнаешь.

Dima: finder пишет: ADS FTS хорошо, но подозреваю что сам ADS не очень бесплатный Ну если нужна лицуха то да , если нет то 10 версию легко можно найти в инете.

finder: Andrey пишет: Стандартный CDX драйвер тоже может создавать индекс по мемо полю. У меня так в программе строится условный индекс по нужным записям. Очень быстро строиться.... Пример можно? Потому как если делаю так: #include "dbinfo.ch" REQUEST DBFCDX function main() FIELD F1 rddsetdefault("DBFCDX") ? rddsetdefault() set delete on set exclusive off aeval(directory("_tstm.*"),{|x|ferase(x[1])}) dbCreate("_tstm", {{"F1", "M", 10, 0}}) USE _tstm while lastrec()<100000 dbappend() F1 := strzero(recno(),10)+chr(recno()%26+asc("A")) enddo INDEX ON F1 TAG T1 TO _tst dbcommit() return nil получаю в результате это: Error DBFCDX/1026 Data width error Andrey пишет: Прямой путь на LetoDB с такими требованиями. Без тестов ничего не узнаешь. Собственно в его сторону и пытаюсь двигаться )

Haz: Andrey пишет: Стандартный CDX драйвер тоже может создавать индекс по мемо полю. при FTS это делается пословно (по каждому слову) на все значение поля. Делается один раз и в дальнейшем сервер сам оптимизирует поиск по ключам этого индекса ( т.е. не требуя просматривать все мемо на вхождение )



полная версия страницы