powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Медленная работа Select
34 сообщений из 34, показаны все 2 страниц
Медленная работа Select
    #33400677
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемые коллеги!
Select отбирает данные порядка 10 секунд.

Код: plaintext
1.
2.
3.
4.
5.
6.
      SELECT *;
	  FROM pl;
   	  WHERE VAL(Pl.god)=VAL(FGOD) AND ;
		    VAL(Pl.mes) = fmes AND ;
		    Pl.sh == TB.sh AND ;
            Pl.idnompol# 0  and Pl.idnompl# 0  and Pl.shb = .T.;
	  INTO cursor tekpl
Таблица PL на сервере Novell по сетке 100мбит размером 26мбайт, 26000 записей. Открывается в режиме Shared. Работают 2-3 пользователя одновременно. Foxpro - 6 ка. Индексный файл составной по всем полям.

Не могу разобраться почему так долго выполняется Select, по идее он должен пулей пролетать.
Может у вас есть мысли по этому поводу.

P.S. Если будут вопросы к сожалению смогу ответить только в Понедельник (28.11.05)
...
Рейтинг: 0 / 0
Медленная работа Select
    #33400737
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Создать индексы

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
INDEX ON VAL(god) TAG god
INDEX ON VAL(mes) TAG mes
INDEX ON sh TAG sh
INDEX ON idnompol TAG idnompol 
INDEX ON shb TAG shb
INDEX ON idnompl TAG idnompl

*переписать запрос

      SELECT *;
	  FROM pl;
   	  WHERE VAL(Pl.god)=VAL(FGOD) AND ;
		    VAL(Pl.mes) = fmes AND ;
		    Pl.sh == TB.sh AND ;
            Pl.idnompol# 0  and Pl.idnompl# 0  and Pl.shb = .T.;
	  INTO cursor tekpl
...
Рейтинг: 0 / 0
Медленная работа Select
    #33400879
Фотография 1024
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
наверна функции по полям не надо использовать, т.е.

WHERE Pl.god=FGOD AND ;
Pl.mes = alltrim(str(fmes,10x,0)) AND ;
Pl.sh == TB.sh AND ;
Pl.idnompol#0 and Pl.idnompl#0 and Pl.shb = .T.;


Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Медленная работа Select
    #33401140
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за совет PaulWist . Попробую создать дополнительные Тэги специально для запроса. Но я как то экспереминтировал на таблице с 50000 записей(справочник автозапчастей). Так вот есть индексы или их нет скорость отличалась не очень сильно (точнее не скажу). Правда там таблица лежала локально и открывалась Эксклюзивно.
Для 1024 -> К сожалению изначально Where так и выглядел как вы написали. Переработка в приведенный мной вид быстродействие не увеличила.
PS - непонял что значит 10x в STR - может просто 10 наверно описка.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33402514
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что бы определить уровень оптимизации включи SYS(3054,11) - эта ф-ия покажет какие индексы используются для поиска, желательно добиться слова FULL, отсюда танцуй добиваясь оптимизации запроса
...
Рейтинг: 0 / 0
Медленная работа Select
    #33405327
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PaulWist Спасибо буду пробовать
...
Рейтинг: 0 / 0
Медленная работа Select
    #33405846
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PaulWist Спасибо теперь время обработки 0 секунд.
создал именно тэги как в запросе. Оптимизация FULL
...
Рейтинг: 0 / 0
Медленная работа Select
    #33405991
w3d
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PaulWistЧто бы определить уровень оптимизации включи SYS(3054,11) - эта ф-ия покажет какие индексы используются для поиска, желательно добиться слова FULL, отсюда танцуй добиваясь оптимизации запроса

А как его включить?
У меня на форму текст какой-то выводится...
...
Рейтинг: 0 / 0
Медленная работа Select
    #33406630
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
w3d PaulWistЧто бы определить уровень оптимизации включи SYS(3054,11) - эта ф-ия покажет какие индексы используются для поиска, желательно добиться слова FULL, отсюда танцуй добиваясь оптимизации запроса

А как его включить?
У меня на форму текст какой-то выводится...
Это выводится результат работы функции SYS(3054). Можно перенаправить его в текстовый файл.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
SET PRINTER TO FILE MyLog.txt
SET PRINTER ON
SYS( 3054 , 11 )

SELECT ...

SYS( 3054 , 0 )
SET PRINTER OFF
SET PRINTER TO

Потом смотрим текстовый файл MyLog.txt.

Хотя в версии VFP9 можно уже явно указать в функции SYS(3054) куда выводить результат анализа.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33407356
w3d
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, но там в любом случае выводится в переменную.
А можно перенаправить на экран, а не на форму?

П.С. у меня 9.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33407868
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я не заморачивался - смотрел прямо на форме.
Все равно это надо только на время отладки.
потом просто вызов функции SYS закоментровал.
Она выдает список тегов которые использованы, и результат оптимизации SELECT.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33408080
w3d
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А как надо оптимизировать?
Вот выдало у меня partial, и что дальше делать?
...
Рейтинг: 0 / 0
Медленная работа Select
    #33408321
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Погляди перечень используемых тэгов,
погляди фильтр WHERE, что из фильтра where нет среди индексов?
по тем полям и создай индексы
например мой селект:

Код: plaintext
1.
2.
3.
4.
5.
6.
      SELECT *;
	  FROM pl;
   	  WHERE val(Pl.god)=val(FGOD) AND ;
		    val(Pl.mes)=fmes AND ;
		    alltrim(Pl.sh) == alltrim(TB.sh) AND ;
            Pl.idnompol# 0  and Pl.idnompl# 0  and Pl.shb = .T.;
	  INTO cursor tekpl

нужны следующие теги (индексы):
Код: plaintext
1.
2.
3.
4.
5.
6.
sele pl
index on val(god) tag valgod
index on val(mes) tag valmes
index on alltrim(sh) tag alsh
index on idnompol tag idnompol
index on idnompl tag idnompl
index on shb tag shb
и еще index on deleted() tag del - он также почемуто используется

после создания выдает full
...
Рейтинг: 0 / 0
Медленная работа Select
    #33408339
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот что выдает если точнее
...
Рейтинг: 0 / 0
Медленная работа Select
    #33411239
Urri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S866Погляди перечень используемых тэгов,
погляди фильтр WHERE, что из фильтра where нет среди индексов?
по тем полям и создай индексы
например мой селект:

Код: plaintext
1.
2.
3.
4.
5.
6.
      SELECT *;
	  FROM pl;
   	  WHERE val(Pl.god)=val(FGOD) AND ;
		    val(Pl.mes)=fmes AND ;
		    alltrim(Pl.sh) == alltrim(TB.sh) AND ;
            Pl.idnompol# 0  and Pl.idnompl# 0  and Pl.shb = .T.;
	  INTO cursor tekpl

нужны следующие теги (индексы):
Код: plaintext
1.
2.
3.
4.
5.
6.
sele pl
index on val(god) tag valgod
index on val(mes) tag valmes
index on alltrim(sh) tag alsh
index on idnompol tag idnompol
index on idnompl tag idnompl
index on shb tag shb
и еще index on deleted() tag del - он также почемуто используется

после создания выдает full
1. index on alltrim(sh) tag alsh - в корне неверно!
2. index on alltrim(sh) tag alsh - не поможет, так как == не оптимизируется.
3. index on shb tag shb - может не ускорить, а даже замедлить (зависит от селективности).
4. index on val(god) tag valgod и index on val(mes) tag valmes - как я понял, дата хранится в pl частями, да еще и в строковом формате. Почему бы не хранить дату именно как дату (pl.date), проиндексировать по этому полю, а в запросе не использовать конструкцию where pl.date between start_date and end_date?
...
Рейтинг: 0 / 0
Медленная работа Select
    #33411746
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для URRI
Понимаете ли - в таблице 26000 записей с платежками за 4 года работы (прогу я писал 4 года назад) - mes & god - месяц и год бух учета. тогда мне показалось верным god -4 байта mes - два байта что бы 01,02,...10,11,12 и в тексте - для удобства (т.е. мне тогда было удобно именно так). И переделывать таблицу я естественно теперь не буду т.к. и другой работы по горло и данные ценные и программу всю надо перебирать.
а смысл топика - просто Юзеров задолбала медленная работа программы - Я выяснил что этот SELECT в одной процедуре у меня висит - процедуре согласования данных по базам. (тогда я делал похоже как в DOS FOXе).
и эта процедура вызывается при открытии и закрытии программы , ну и еще в паре мест.

Может индексы теоритически и не правильные - но теперь процедура выполняется не 10 секунд а 0 (точнее не мерял) и меня и пользователей это вполне устраивает.
а без них выполнялось долго - недопустимо долго. Я это замерял и врать мне нет никакой надобности.
кстати там файлик был прикрепленный с листингом экрана - там видно что при SELECTe используются именно эти индексы.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33412161
Urri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По mes & god есть отдельные индексы? (1)
Или один по god+mes? (2)

Тогда измените в запросе
Код: plaintext
1.
WHERE VAL(Pl.god)=VAL(FGOD) AND ;
VAL(Pl.mes) = fmes AND ;
на:
для (1)
Код: plaintext
1.
WHERE Pl.god=str(FGOD, 4 ) AND ;
Pl.mes = chrtran(str,fmes, 2 ),' ','0') AND ;
,для (2)
Код: plaintext
WHERE Pl.god+Pl.mes=str(FGOD, 4 )+chrtran(str,fmes, 2 ),' ','0') AND ;
- и получайте удовольствие от наступившего ускорения ;-)
...
Рейтинг: 0 / 0
Медленная работа Select
    #33412296
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Urri
1. index on alltrim(sh) tag alsh - в корне неверно!

Не совсем. Такой индекс эквивалентен отбрасыванию ведущих пробелов.

Т.е. конструкция допустима, но FoxPro сам, автоматически, после отсечения ведущих и концевых пробелов добавит концевые пробелы в выражение ключа до количества символов в поле sh.

Идеологически, да, неверно. Но в описанной ситуации вполне уместен. Дело в том, что замена на "простой" индекс по полю sh означает серьезную переделку всей программы. Если стоит задача поставить "заплатку", то сойдет и так.

Urri
2. index on alltrim(sh) tag alsh - не поможет, так как == не оптимизируется.

Оптимизируется. Не надо забывать, что сравнение символьных строк в "обычных" командах FoxPro и внутри команды Select-SQL работает немного по разному.

Внутри команды Select-SQL оператор тождественного равенства вего-лишь означает, что сравнение будет закончено по истечении длины самого короткого выражения в операторе сравнения. При этом не важно с какой стороны этого оператора он стоит.

Т.е. это "локальное" применение настройки SET ANSI ON. На факт оптимизиации никак не влияет.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33412616
Urri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, ВладимирМ, всю жизнь не знал.

В FPD alltrim в индексе был не разрешен, это я хорошо помню.
И == вроде как тоже не оптимизировалось (даже в доке так написано было).

Прогресс.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33412644
w3d
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S866Но я как то экспереминтировал на таблице с 50000 записей(справочник автозапчастей).
А не поделитесь таким справочником?
...
Рейтинг: 0 / 0
Медленная работа Select
    #33412733
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для URRI - Да индексы по god mes и god+mes есть - надо было делать так как вы написали
для (1)
Код: plaintext
1.
WHERE Pl.god=str(FGOD, 4 ) AND ;
Pl.mes = chrtran(str,fmes, 2 ),' ','0') AND ;

,для (2)
Код: plaintext
WHERE Pl.god+Pl.mes=str(FGOD, 4 )+chrtran(str,fmes, 2 ),' ','0') AND ;

просто перобразование к числу - это както надежнее а то еще вылезет что
"1"="11" => .T. а вот "1"=="11" =>.F.
с другой стороны создание дополнительных индексов по таблице - 2 минуты эксклюзивного доступа к ней. так что я не особо напрягся.
И еще не знаю какой фокс у вас - у меня fox 2.5 rus for dos там
Код: plaintext
index on alltrim(...) tag ...
идет без проблем. Наверно кто как привык тот так и программирует кто использует Val() а кто и STR() , я например редко пользуюсь chrtran и transform.
Для W3d - Поделюсь конечно без проблем Если вам нужен именно справочник автозапчастей то вот как я его получил:
1. идете на сайт www.avia3n.ru
2. качаете их прайс в формате excel (6 МБ).
3. открываете его в excel и сохраняете нужный вам лист (а он со списком запчастей там один вроде) в формате DBF ("сохранить как")
4. создаете нужные вам индексы и вобще делаете все что угодно с ним (там тысяч 65 наименований)
P.S. Всем спасибо за помощь - почерпнул для себя много нового.
отдельное спасибо ВладимирМ за поддержку и теорию.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33413370
Urri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S866И еще не знаю какой фокс у вас - у меня fox 2.5 rus for dos там
Код: plaintext
index on alltrim(...) tag ...
идет без проблем. Наверно кто как привык тот так и программирует кто использует Val() а кто и STR() , я например редко пользуюсь chrtran и transform.Ну, давайте рассуждать так: длина строки индексного вырожения должна быть постоянной от записи к записи для всех записей таблицы.
alltrim дает разные длины строк. Вероятно, фокс все-таки умеет корректно отрабатывать подобные ситуации, но когда я его осваивал, в похожей ситуации при использовании alltrim у меня возникли проблемы.
С тех пор я:
1. При ручном вводе всегда проверяю строковые поля на отсутствие лидирующих пробелов. Т.е. в моих таблицах наличие таковых - табу.
2. Если нужно задавить концевые пробельные символы, я, конечно, использую trim(). Но если это индекс, то тут я всегда использую padr().
...
Рейтинг: 0 / 0
Медленная работа Select
    #33413554
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Аналогично - Я при сохранении из переменной в таблицу всегда делаю alltrim
Вполне с вами согласен - ваши рассуждения вполне логичны. И правильны.
Спасибо за помощь!
Вобще сейчас я все поля что можно - делаю числовыми или integer.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33413634
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМНе совсем. Такой индекс эквивалентен отбрасыванию ведущих пробелов.

Т.е. конструкция допустима, но FoxPro сам, автоматически, после отсечения ведущих и концевых пробелов добавит концевые пробелы в выражение ключа до количества символов в поле sh.

Идеологически, да, неверно .

Господа, маленькое замечание по поводу ALLTRIM() в индексе, все рассуждения строятся на том основании, что данные будут заносится и использоваться исключительно в Ваших программах, НО ни кто не рассматривает того варианта, что другой софт, стороннего разработчика может общаться с Вашими данными, и о том, что "я всегда убираю начальные пробелы" этот софт может и не знать, поэтому ALLTRIM() является общим решением для индекса, а LEFT, PADR - это частные решения для Вашей задачи.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33413794
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PaulWist ВладимирМНе совсем. Такой индекс эквивалентен отбрасыванию ведущих пробелов.

Т.е. конструкция допустима, но FoxPro сам, автоматически, после отсечения ведущих и концевых пробелов добавит концевые пробелы в выражение ключа до количества символов в поле sh.

Идеологически, да, неверно .

Господа, маленькое замечание по поводу ALLTRIM() в индексе, все рассуждения строятся на том основании, что данные будут заносится и использоваться исключительно в Ваших программах, НО ни кто не рассматривает того варианта, что другой софт, стороннего разработчика может общаться с Вашими данными, и о том, что "я всегда убираю начальные пробелы" этот софт может и не знать, поэтому ALLTRIM() является общим решением для индекса, а LEFT, PADR - это частные решения для Вашей задачи.
Маленькое замечание по замечанию.

База данных - это не просто набор таблиц, никак не связанных между собой. Это нечто, являющееся единым целым. Т.е., в общем случае, невозможно где-то, что-то подправить так, чтобы это не затронуло всего остального.

Отбрасывание ведущих пробелов в момент записи информации в таблицу (если этого не делать, то как раз и нужен индекс по AllTrim()) - это всего-лишь один из множества разнообразных контролей процесса записи информации.

То, что кто-то будет обращаться к таблицам напрямую и, предположительно, модифицировать данные, означает, что есть серьезный риск нарушить вообще всю целостность базы данных. Появление ведущих пробелов - будет всего-лишь признаком того, что кто-то влез в эту базу со стороны.

Есть еще ряд проблем такого "стороннего" вмешательства. В общем случае, это не проблема автора программы, а проблема того, кто влез в базу данных используя сторонние программы.

С другой стороны, наличие ведущих пробелов (если это не обусловлено спецификой данных) - это довольно значительная проблема организации поиска данных и неоправданное усложение программы. Т.е. использование индекса по AllTrim() - это признак "кривизны" контроля целостности базы данных.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33413903
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ
ВладимирМБаза данных - это не просто набор таблиц, никак не связанных между собой. Это нечто, являющееся единым целым. Т.е., в общем случае, невозможно где-то, что-то подправить так, чтобы это не затронуло всего остального

С этим утверждением согласен, только до слов - "что-то где-то", для этого существует механизм ограничений (PK/FK/CK, CHECK, TRIGGER), если наши подправления нарушают эти ограничения, то вот это "что-то где-то" не пройдёт, а если пройдёт, то это сам понимаешь на чьи руки надо пенять. (не имею ввиду уважаемое собрание)

ВладимирМОтбрасывание ведущих пробелов в момент записи информации в таблицу (если этого не делать, то как раз и нужен индекс по AllTrim()) - это всего-лишь один из множества разнообразных контролей процесса записи информации.

Тогда обьясни как ты будешь отбрасывать ведущие пробелы для записей модифицируемых сторонним софтом на все CHAR поля писать RULE

Код: plaintext
CHECK IIF(ASC(MyField) =  32 ,.F.,.T.)

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

Надо ли это понимать, что НЕЛЬЗЯ использовать данные созданные в наших программах другим софтом, потому что другая прога не знает о наших допущениях (это мне напоминает фразу - если программа работает не так как надо, то отразим это в документации)

ВладимирМЕсть еще ряд проблем такого "стороннего" вмешательства. В общем случае, это не проблема автора программы, а проблема того, кто влез в базу данных используя сторонние программы.

У меня Дежа вю, какое-то на цитаты.

Ошибок не бывает вообще, есть ситуации для которых программист не предусмотрел проверки (с) Лес Пинтер

ВладимирМС другой стороны, наличие ведущих пробелов (если это не обусловлено спецификой данных) - это довольно значительная проблема организации поиска данных и неоправданное усложение программы. Т.е. использование индекса по AllTrim() - это признак "кривизны" контроля целостности базы данных.

Вот про кривизну контроля целостности по подробнее, если можно пример.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33414307
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 PaulWist

Код: plaintext
Ошибок не бывает вообще, есть ситуации для которых программист не предусмотрел проверки (с) Лес Пинтер

Супер!
...
Рейтинг: 0 / 0
Медленная работа Select
    #33414672
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ

Ну вообщем сам привожу примеры для разных случаев.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
* пример когда проходит занесение значащих значений при PADR()
CREATE CURSOR test (cText c( 5 ))
INDEX ON PADR(cText, 5 ) TAG cText candidat

INSERT INTO test (cText) VALUES ('1')
INSERT INTO test (cText) VALUES (SPACE( 1 ) + '1')

* Те же яйца только с ALLTRIM() - здесь уже нельзя добавить значащиеся символы
CREATE CURSOR testAll (cText c( 5 ))
INDEX ON ALLTRIM(cText) TAG cText candidat

INSERT INTO testAll (cText) VALUES ('1')
INSERT INTO testAll (cText) VALUES (' 1')

* Пример с "уборкой" пробелов
CREATE CURSOR testCheck (cText c( 5 ) CHECK SpaceFunc())
INDEX ON PADR(cText, 5 ) TAG cText candidat

INSERT INTO testCheck (cText) VALUES ('1')
INSERT INTO testCheck (cText) VALUES (' 1')

FUNCTION SpaceFunc

IF ASC(cText) =  32 
	replace cText with ALLTRIM(cText)
ENDIF 
ENDFUNC 

В любом случае есть ещё проблемы с SELECT-SQL, не зависимо от выражения индекса (PADR/ALLTRIM) в WHERE условии надо повторить этот синтаксис.

Ладно, оставим этот разговор, а то он у нас случается раз в полгода.

Хотя если у тебя есть пояснения готов выслушать с большим вниманием. :))
...
Рейтинг: 0 / 0
Медленная работа Select
    #33415048
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PaulWist
С этим утверждением согласен, только до слов - "что-то где-то", для этого существует механизм ограничений (PK/FK/CK, CHECK, TRIGGER), если наши подправления нарушают эти ограничения, то вот это "что-то где-то" не пройдёт, а если пройдёт, то это сам понимаешь на чьи руки надо пенять. (не имею ввиду уважаемое собрание)
Это утверждение предполагает, что ВСЯ бизнеслогика, в том, что касается целостности базы данных, вынесена на уровень триггеров. Как минимум, в хранимые процедуры. В идеале так и должно быть. Но, как правило, от этого правила отступают. Слишком громоздко получается...

PaulWist
ВладимирМОтбрасывание ведущих пробелов в момент записи информации в таблицу (если этого не делать, то как раз и нужен индекс по AllTrim()) - это всего-лишь один из множества разнообразных контролей процесса записи информации.

Тогда обьясни как ты будешь отбрасывать ведущие пробелы для записей модифицируемых сторонним софтом на все CHAR поля писать RULE
Ну, это-то просто...

1) FORMAT="T" - в свойствах поля.

Поскольку эта настройка может быть перекрыта в формах, то добавляю безусловный контроль

2) RULE-уровня записи

Код: plaintext
REPLACE MyField WITH LTRIM(MyField)

PaulWist
ВладимирМТо, что кто-то будет обращаться к таблицам напрямую и, предположительно, модифицировать данные, означает, что есть серьезный риск нарушить вообще всю целостность базы данных. Появление ведущих пробелов - будет всего-лишь признаком того, что кто-то влез в эту базу со стороны.

Надо ли это понимать, что НЕЛЬЗЯ использовать данные созданные в наших программах другим софтом, потому что другая прога не знает о наших допущениях (это мне напоминает фразу - если программа работает не так как надо, то отразим это в документации)
Нельзя (по крайней мере очень не желательно) модифицировать данные при помощи другого софта. А использовать (в смысле на просмотр), конечно можно.

Ты рассмотрел только вопрос ведущих пробелов. А ведь вариантов модификации базы данных, когда это делается напрямую, минуя прогу, огромное количество. Далеко не все возможные проблемы можно решить через правила и тригера.

В "родной" программе огромное количество проблем просто не возникает из-за того, что у пользователя нет инструмента прямой модификации базы данных. Если это правило нарушается, то уровень сложности контроля целостности базы данных подскакивает до небес.

PaulWist
ВладимирМЕсть еще ряд проблем такого "стороннего" вмешательства. В общем случае, это не проблема автора программы, а проблема того, кто влез в базу данных используя сторонние программы.

У меня Дежа вю, какое-то на цитаты.

Ошибок не бывает вообще, есть ситуации для которых программист не предусмотрел проверки (с) Лес Пинтер
"И это правильно!" (с)

PaulWist
ВладимирМС другой стороны, наличие ведущих пробелов (если это не обусловлено спецификой данных) - это довольно значительная проблема организации поиска данных и неоправданное усложение программы. Т.е. использование индекса по AllTrim() - это признак "кривизны" контроля целостности базы данных.

Вот про кривизну контроля целостности по подробнее, если можно пример.
Индекс по AllTrim() - это предположение, что данные не корректны! Их нельзя использовать напрямую. Без предварительного преобразования. Тогда встает вопрос почему только AllTrim(). А где UPPER(), а где CHRTRAN() для отсечения "лишних" символов? Почему только ведущие пробелы? А если пробел в середине слова? И т.д. и т.п.

Если для работы с данными требуется их преобразование в обязательном порядке , то возникает серьезное сомнение в достоверности самих данных.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33415107
Urri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А я, вообще-то, не пускаю сторонние программы напрямую работать с таблицами собственно моей БД. Только через специальные интерфейсные таблицы ввода-вывода, причем ввод - только с проверками.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33417057
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ PaulWist

С этим утверждением согласен, только до слов - "что-то где-то", для этого существует механизм ограничений (PK/FK/CK, CHECK, TRIGGER), если наши подправления нарушают эти ограничения, то вот это "что-то где-то" не пройдёт, а если пройдёт, то это сам понимаешь на чьи руки надо пенять. (не имею ввиду уважаемое собрание)

Это утверждение предполагает, что ВСЯ бизнеслогика, в том, что касается целостности базы данных, вынесена на уровень триггеров. Как минимум, в хранимые процедуры. В идеале так и должно быть. Но, как правило, от этого правила отступают. Слишком громоздко получается...

Я бы разделил бизнес логику на две составляющих

1. Поддержание ссылочной целостности (PK/FK), ограничений (CK/RULE)
2. Собственно занесение/модификация данных

Так вот думаю, что определение ссылочной целостности и правил должно быть вседа, иначе - это не база данных, а просто набор таблиц.

Теперь по модификации данных - согласен, что в большинстве случаев мы в коде приложения получаем PK для Мастер-таблицы и ручками его прописываем в Детали-таблицу, но это идеологически не правильно и я прекрасно понимаю, что такие наши действия - это наследие FPD.

Поэтому если отбросить п.2, то ничего сложного для поддержания БД мне кажется нет.

ВладимирМНу, это-то просто...

1) FORMAT="T" - в свойствах поля.

Поскольку эта настройка может быть перекрыта в формах, то добавляю безусловный контроль

2) RULE-уровня записи

Принято.

ВладимирМНельзя (по крайней мере очень не желательно) модифицировать данные при помощи другого софта. А использовать (в смысле на просмотр), конечно можно.

Конечно имелось в виду, модифицировать. Даже не знаю, что сказать.

Приведу пример - у Вас есть некий купленный софт, который что-то делает, у этого софта есть справочники. Предположим, что мы написали программу использующую справочники этого стороннего софта (ну не вести же, те же справочники ещё в одном месте).

Пользователи тебе говорят, слушай мы работаем в твоей проге и время от времени надо, например в справочниках стороннего софта(или в документах), что-то править, ну не удобно нам переключаться из одного в другое, сделай так что бы мы могли из твоей программы модифицировать данные в стороннем софте.
Каков будет твой ответ - нет ребята нельзя или да запросто, только разберусь со структурой данных, думаю второе.
Таким образом мы убиваем несколько зайцев и главный из них - это создание корпоративной БД, а не набор проектов реализующий ту или иную функциональность.

ВладимирМТы рассмотрел только вопрос ведущих пробелов. А ведь вариантов модификации базы данных, когда это делается напрямую, минуя прогу, огромное количество. Далеко не все возможные проблемы можно решить через правила и тригера

ВладимирМИндекс по AllTrim() - это предположение, что данные не корректны! Их нельзя использовать напрямую. Без предварительного преобразования. Тогда встает вопрос почему только AllTrim().

Отвечу твоей же цитатой, которую мы приняли

ВладимирМС другой стороны, наличие ведущих пробелов ( если это не обусловлено спецификой данных )

Те, другими словами нас не интересуют пробелы, а интересуют значащие символы отличные от пробелов.

Владимир, напомню с чего началось

ВладимирМНе совсем. Такой индекс эквивалентен отбрасыванию ведущих пробелов.

Т.е. конструкция допустима, но FoxPro сам, автоматически, после отсечения ведущих и концевых пробелов добавит концевые пробелы в выражение ключа до количества символов в поле sh.

Идеологически, да, неверно .

Из этого следует, что использование ALLTRIM() идеологически неверно, а
PADR() определялось как правильное решение (таких слов от тебя не было написано, но и о том, что PADR() или др ф-ию не хорошо использовать тоже не прозвучало ).

ВладимирМЕсли для работы с данными требуется их преобразование в обязательном порядке, то возникает серьезное сомнение в достоверности самих данных.

Ну, думаю ты здесь малёк переборщил - данные они и есть данные, независимо надо их преобразовывать или нет - это как обьективная реальность данная нам в ощущения. А то что мы их можем преобразовать на этапе модификации или на этапе использования - это зависит, как правило от задачи, а не от данных.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33418158
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PaulWistПользователи тебе говорят, слушай мы работаем в твоей проге и время от времени надо, например в справочниках стороннего софта(или в документах), что-то править, ну не удобно нам переключаться из одного в другое, сделай так что бы мы могли из твоей программы модифицировать данные в стороннем софте.
Каков будет твой ответ - нет ребята нельзя или да запросто, только разберусь со структурой данных , думаю второе.
Ключевой момент - это именно разбор структуры данных. Сам понимаешь, что просто так взять и вставить куда-то данные нельзя. Надо проследить всю цепочку взаимодействий и убедиться, что твоя модификация не повредит целостности базы данных.

Т.е. ты сам предполагаешь, что не весь контроль ссылочной целостности вынесен в триггера и правила. Что-то, где-то не учли (специально или случайно - другой вопрос)

PaulWistТаким образом мы убиваем несколько зайцев и главный из них - это создание корпоративной БД, а не набор проектов реализующий ту или иную функциональность.
Теоретически. Практически, такая конструкция долго не живет. Это кончается либо приобритением, либо написанием единой ERP-системы. Слишком тяжело сопровождать систему слепленную из массы разнородных модулей.

PaulWistВладимир, напомню с чего началось

ВладимирМНе совсем. Такой индекс эквивалентен отбрасыванию ведущих пробелов.

Т.е. конструкция допустима, но FoxPro сам, автоматически, после отсечения ведущих и концевых пробелов добавит концевые пробелы в выражение ключа до количества символов в поле sh.

Идеологически, да, неверно .

Из этого следует, что использование ALLTRIM() идеологически неверно, а
PADR() определялось как правильное решение (таких слов от тебя не было написано, но и о том, что PADR() или др ф-ию не хорошо использовать тоже не прозвучало ).
На самом деле началось чуть раньше. В исходном запросе конструкция с AllTrim() явно использовалась для связки PK-FK. Это идеолгоически неверно при любом раскладе. PK вообще не должен никак преобразовываться. На то он и PK. Индекс по PK - это всего-лишь инструмент ускорения поиска нужного значения.

Идеологически верно, с моей точки зрения, это контролировать модификацию данных так, чтобы вообще не возникало необходимости в отсечении ведущих пробелов. Опять же, если это не обусловлено самими данными. Но, поскольку в данном примере речь идет о PK-FK, то данными это не может быть никак обусловлено.

Под фразой "обусловлено самими данными" я понимаю то, что ведущие пробелы - это некие значимые символы. Т.е. не просто "рука дрогнула", а именно что необходимы ведущие пробелы.

PaulWist
ВладимирМЕсли для работы с данными требуется их преобразование в обязательном порядке, то возникает серьезное сомнение в достоверности самих данных.

Ну, думаю ты здесь малёк переборщил - данные они и есть данные, независимо надо их преобразовывать или нет - это как обьективная реальность данная нам в ощущения. А то что мы их можем преобразовать на этапе модификации или на этапе использования - это зависит, как правило от задачи, а не от данных.
Да. Согласен. Если говорить "вообще". Просто я опять высказался в контексте данного вопроса, когда преобразование использовалось для связки PK-FK в данной постановке . В данной задаче - это недоработка разработчика.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33418717
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМКлючевой момент - это именно разбор структуры данных. Сам понимаешь, что просто так взять и вставить куда-то данные нельзя. Надо проследить всю цепочку взаимодействий и убедиться, что твоя модификация не повредит целостности базы данных.

Т.е. ты сам предполагаешь, что не весь контроль ссылочной целостности вынесен в триггера и правила. Что-то, где-то не учли (специально или случайно - другой вопрос)

Да, конечно, при разнородных источниках данных просто невозможно используя внутренние механизмы Fox-a поддерживать ссылочную целостность, для этого приходится использовать либо собственное творчество реализованное в триггерах, либо софт стороннего производителя, но это не значит, что этого не надо делать. Да это трудоёмко и на первый взгляд не очевидно, но в дальнейшем решает массу проблем.

ВладимирМ PaulWistТаким образом мы убиваем несколько зайцев и главный из них - это создание корпоративной БД, а не набор проектов реализующий ту или иную функциональность.

Теоретически. Практически, такая конструкция долго не живет. Это кончается либо приобритением, либо написанием единой ERP-системы. Слишком тяжело сопровождать систему слепленную из массы разнородных модулей.

У меня мнение другое, с точностью до наоборот. Теоретически, хорошо бы иметь одну систему, а практически это не реально, первый аргумент - это мнение генерала, который говорит - "я и так затратил кучу денег, а ты мне предлагаешь опять раскошелиться", а второй аргумент - ну купили ERP - систему, через какое-то время возникает необходимость в CRM системе, причем разработка её под ERP составит круглую сумму, а покупка готового решения даже с доделками/настройками обойдется 1000-2000$ на рабочее место. Через какое-то время выяснится, что ещё что-то нужно, и сам понимаешь колробочный софт будет на порядок дешевле разработки.

Где-то года два назад, я у себя в конторе пытался подсчитать - какое кол-во прикладного софта используется - когда дошел до цифры в 80 программ, бросил.
Это я к чему ни одна система не может обеспечит всего функционала хозяйственной деятельности предприятия, да ещё если оно развивается.

Ну давай вернемся к нашим баранам, а то действительно понесло в философию.

ВладимирМ В исходном запросе конструкция с AllTrim() явно использовалась для связки PK-FK. Это идеолгоически неверно при любом раскладе. PK вообще не должен никак преобразовываться. На то он и PK.

Что ж, в данном конкретном случае когда простой тэг по полю является PK, преобразование поля через ф-ию излишне (в том случае если мы позаботились об отсечении пробелов), но сам понимаешь тэг PK может быть составным и без ф-ий здесь никак не обойтись, можно возразить - вот именно здесь проявляется "кривизна" данных, отвечу не всегда, поэтому, поскольку наши посты читают другие ребята, отметим этот аспект, а то у них может сложиться привратное впечатление.

ВладимирМИндекс по PK - это всего-лишь инструмент ускорения поиска нужного значения.

Думаю, здесь ты не дописал, что ускорение поиска это побочный (хотя не мало важный) эффект, а основное его предназначение создание не протеворечивости данных, поскольку вряд ли PK может участвовать в задании критерия поиска.

ВладимирМИдеологически верно, с моей точки зрения, это контролировать модификацию данных так, чтобы вообще не возникало необходимости в отсечении ведущих пробелов. Опять же, если это не обусловлено самими данными.

Давай вернемся к FORMAT = "T"

Что-то я засомневался в таком подходе отсечения ведущих пробелов.

Проверим.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE DATABASE TestChar

CREATE TABLE TestCh (ID c( 10 ) NOT NULL, PRIMARY KEY ID TAG ID)

DBSETPROP('TESTCH.ID', 'Field', 'Format', "T")

INSERT INTO testCh (ID) VALUES ('1')
INSERT INTO testCh (ID) VALUES (SPACE( 1 ) + '1')
INSERT INTO testCh (ID) VALUES (SPACE( 2 ) + '1')

BROWSE LAST

Пожалуй, только RULE остается.
...
Рейтинг: 0 / 0
Медленная работа Select
    #33419025
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насчет Format = "T".

Эта штука работает только при "ручном" вводе данных. Т.е. при программном вводе - игнорируется. Однако это уже проблемы программста, почему он при программном вводе не озаботился отсечением ведущих пробелов.

Кроме того, эта настройка может быть перекрыта настройками в объектах формы. Т.е. если в настройках TextBox, у которого в качестве ControlSource указано такое поле просто очистить настройку Format, то она действительно не будет использоваться в данном объекте. Но это опять вопрос к программисту - а зачем ты это сделал?

RULE- действительно надежно. Но опять же - это избыточная настройка, если предполагается, что работа будет вестись только из данной проги.

Совместимость разнородного софта - это огромная проблема. Но это тема отдельного разговора.

PS: я бы тут еще порассуждал на отвелеченные темы, но времени маловато. Иногда и работать надо
...
Рейтинг: 0 / 0
34 сообщений из 34, показаны все 2 страниц
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Медленная работа Select
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]