C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

стр.: (2) < [1] 2 >
Embedded Firebird || Access, Декартовы произведения
Konstantine
Отправлено: 31.05.2006, 16:48


Мастер участка

Группа: Модератор
Сообщений: 545



нужно перегнать мою базу из Access в FireBird. пишу простейшую утиль (заманался по инету рыскать — всё равно не подходит — 5 штук перепробовал sad.gif) ладна...
поставил компоненты (TIBDataBase, TIBTransaction, TIBQuery), соединил их и вручную(их немного) запросами создаю таблицы...
первая создалась нормально, а вторая — ругается
SQL
CREATE TABLE Race (
ID INTEGER NOT NULL,
rName VARCHAR(50),
RusName VARCHAR(50));

сообщение "unsuccessful metadata update RACE."
причём если сменить на тип INTEGER или TIME (другие не пробовал) — идёт в норме (ну данные естесно не подставятся потом)
а CHAR и VARCHAR — не хотят

база локальная
olegenty
Отправлено: 01.06.2006, 07:03


Ветеран

Группа: Модератор
Сообщений: 2412



качни IBDataPump, либо как Plugin к IBExpert, либо как отдельное приложение, и будет тебе счастье.
Konstantine
Отправлено: 01.06.2006, 08:23


Мастер участка

Группа: Модератор
Сообщений: 545



качалка — то хорошо, но всё-таки в чём сам прикол?
почему на строки так ругаеться?
Konstantine
Отправлено: 01.06.2006, 10:37


Мастер участка

Группа: Модератор
Сообщений: 545



создал таблицы IBExpert-ом, но в проге всё равно не могу текстовые поля заполнять:
"arithmetic exception, numeric overflow, or string truncation Implementation of text subtype 52 not located."
olegenty
Отправлено: 01.06.2006, 13:56


Ветеран

Группа: Модератор
Сообщений: 2412



выстави кодировку на клиенте верную NONE, WIN1251, CYRL или какая она там у тебя, в соответствии с кодировкой в БД.
Konstantine
Отправлено: 01.06.2006, 16:03


Мастер участка

Группа: Модератор
Сообщений: 545



при создании базы делал win1251
на компонентах — не могу найти ничего подобного
Konstantine
Отправлено: 02.06.2006, 09:59


Мастер участка

Группа: Модератор
Сообщений: 545



поставил в базе NONE — работает! cool.gif
всем пасибо smile.gif
olegenty
Отправлено: 05.06.2006, 11:03


Ветеран

Группа: Модератор
Сообщений: 2412



ты неправ с выставлением в базе, сортировки по строковым полям могут вести себя не так, как это принято в кодировке WIN1251. выставлять надо было на клиенте. lc_type (по-моему) параметр называется. lc_type=WIN1251 пишешь в параметрах БД, и всё.
Konstantine
Отправлено: 06.06.2006, 11:52


Мастер участка

Группа: Модератор
Сообщений: 545



я потом уже нашёл где это smile.gif, но переделывать не стал...
у меня в проге есть одно узкое место с сильным запросом, который долго выполняется. и по сравнению с Аксес — на FireBird-е он выполнялся в полтора раза дольше (один и тот-же комп, одинаковые входне параметры). поэтому к этой программе FireBird закрываю и продолжаю на Access
avc*
Отправлено: 06.06.2006, 12:34


Не зарегистрирован







QUOTE (Konstantine @ 06/06/2006, 11:52)

у меня в проге есть одно узкое место с сильным запросом, который долго выполняется. и по сравнению с Аксес — на FireBird-е он выполнялся в полтора раза дольше

Скорее всего плохо настроен сервер FB или не хватает индексов.
Konstantine
Отправлено: 06.06.2006, 13:09


Мастер участка

Группа: Модератор
Сообщений: 545



сервера нет — мне нужен вариант на локольной машине чтоб ничего не ставить дополнительно.
индексы есть, просто запрос перебирает большое количество вариантов (сотни тысяч) — это и есть узкое место которое необходимо оптимизировать, но пока не знаю даже с чего начать, но это уже другая тема smile.gif
olegenty
Отправлено: 06.06.2006, 13:54


Ветеран

Группа: Модератор
Сообщений: 2412



не горячись уходить от Firebird. у него есть embedded версия — ничего не надо устанавливать, работает локально. просто когда однажды потребуется развить то, что ты сейчас пишешь, независимо от того, какая клиент-серверная СУБД будет выбрана, переход на неё с Firebird (или он останется) будет значительно проще, чем с Access.

Касаемо же оптимизации — создавай правильный целевой индекс. на моём опыте правильный индекс уменьшал время выборки с единиц часов до единиц-десятков секунд.

Отредактировано olegenty — 06/06/2006, 14:55
Konstantine
Отправлено: 07.06.2006, 10:48


Мастер участка

Группа: Модератор
Сообщений: 545



я как раз и юзал embedded smile.gif
а что касается индекса — у меня такой запрос:
SQL
SELECT T1.ID, T2.ID, T3.ID...
FROM T1,T2,T3...

вместо точек — продолжение...
да-да, именно с таблиц без связей (даже не таблиц а VIEW-сов) — чтоб выбрать ВСЕ комбинации.
это и есть долго.
а индексы — нужны-ли, если я ключевые поля выбираю, просто их много.
ну потом эта выборка упорядочивается по критериям и выбираются только несколько строк...

Отредактировано Konstantine — 07/06/2006, 10:51
AVC
Отправлено: 07.06.2006, 11:10


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE

да-да, именно с таблиц без связей

Декартово произведение ohmy.gif ohmy.gif ohmy.gif
Сколько лет работю, ни разу не понадобилось. Обычно появлеятся как результат ошибочной инструкции SQL.

QUOTE

ну потом эта выборка упорядочивается по критериям и выбираются только несколько строк...

Т.е. вы перегоняете к себе огромыыый набор данных и изображаете из себя сервер БД. Логичнее это поручить ему (серверу). Такой метод допустим cool.gif при работе с файловыми БД.
Gedeon
Отправлено: 07.06.2006, 11:34


Ветеран

Группа: Модератор
Сообщений: 1742



Да, совершенно верно, может опишешь задачу и придумаем правильный запрос?
Konstantine
Отправлено: 07.06.2006, 17:14


Мастер участка

Группа: Модератор
Сообщений: 545



ну попробую обяснить:
- имеются 12 выборок (view) из таблицы некоторых предметов. в каждой выборке ну порядка 20 записей
- каждый предмет имеет целый ряд некоторых свойств. причём набор свойств у всех предметов одинаков.
- необходимо выбрать 10 самых оптимальных вариантов (вариант — это комбинация предметов — по одному из каждой выборки) по критериям:
- несколько суммарных (сумма одинаковых i-х параметров в выборке) параметров (задаётся пользователем) должна быть в им же заданном диапазоне.
- один суммарный параметр — к максимуму.

это можно как в SQL так и в проге.
как временный вариант — построил на SQL тот сумасшедший запрос, но при этом кол-во выборок сделал 6 (если больше — то время выполнения очень долгое)...
Gedeon
Отправлено: 07.06.2006, 17:46


Ветеран

Группа: Модератор
Сообщений: 1742



Да, так конечно тяжело понять, а мож как-то примерчик таблиц кинь?
olegenty
Отправлено: 08.06.2006, 07:11


Ветеран

Группа: Модератор
Сообщений: 2412



если число выборок известное, то делай 12 UNION. вот ты проболтался про критерии. по ним и строй полезные индексы.
CODE

select ... from view1 where <conditions>

union

select ... from view2 where <conditions>

...

вот по < conditions> тебе нужен индекс

Отредактировано olegenty — 08/06/2006, 08:12
Konstantine
Отправлено: 08.06.2006, 08:17


Мастер участка

Группа: Модератор
Сообщений: 545



olegenty, этим я снова построю исходную таблицу.
вобщем у меня эти предметы хранятся в одной таблице:
ID, Type_, Name, Param1, Param2, Param3... Param30
Type_ указывает — в какую выборку будет помещаться предмет.
т.е. набор — это комбинация 12 предметов с разными Type_.
в наборе параметры всех предметов суммируются, и критерии прикладываются к суммарному параметру.

критерии могут быть по любому из параметров
AVC
Отправлено: 08.06.2006, 08:20


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE (Konstantine @ 07/06/2006, 16:14)
ну попробую обяснить:
- имеются 12 выборок (view) из таблицы некоторых предметов. в каждой выборке ну порядка 20 записей
- каждый предмет имеет целый ряд некоторых свойств. причём набор свойств у всех предметов одинаков.
- необходимо выбрать 10 самых оптимальных вариантов (вариант — это комбинация предметов — по одному из каждой выборки) по критериям:
- несколько суммарных (сумма одинаковых i-х параметров в выборке) параметров (задаётся пользователем) должна быть в им же заданном диапазоне.
- один суммарный параметр — к максимуму.

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

Не четко сформулирована постановка задачи.
Что есть строка в выборке — один предмет?
Свойста в дочерних таблицах?
Что значит 10 самых оптимальных по одному из каждой из 12 выборок (групп)? Т.е. выбрать оптимальные внутри группы, а, потом, из них отобрать 10 первых?
Просматривается сортировка по убыванию критерия и взятие первых N записей, но без обяъснения структуры и связей в базе ни чего более конкретного сказать нельзя.

Добавлено
Пишем одновременно. smile.gif
>Type_ указывает — в какую выборку будет помещаться предмет.
Это называется дискриминатор

>набор — это комбинация 12 предметов с разными Type_.
предмет это ID? Как формируется набор — первые встречные ID с одинаковыми Typ'ами?

>в наборе параметры всех предметов суммируются, и критерии прикладываются к суммарному параметру.
Group BY пробовали?


Отредактировано AVC — 08/06/2006, 07:28
Konstantine
Отправлено: 08.06.2006, 09:08


Мастер участка

Группа: Модератор
Сообщений: 545



Строка в выборке (как и в исходной таблице) — это один предмет.

все свойства всех предметов — записаны в одной таблице.

нужно найти по тем критериям не только САМЫЙ оптимальный вариант, но и ещё 9 менее оптимальных.

набор — это 12 предметов с разными типами (в наборе нет 2-х предметов одинакового типа)

группировка не подходит потому что Типы в группе — у всех предметов разные.

связи в базе немного есть, но данной задачи абсолютно не касаются.
эта задача идёт лишь в пределах одной таблицы.
AVC
Отправлено: 08.06.2006, 09:26


Ветеран

Группа: Модератор
Сообщений: 1583



>набор — это 12 предметов с разными типами (в наборе нет 2-х предметов одинакового типа)
Т.е. типов гарантированно больше 12 и предметов каждого типа гарантировано больше 10.

>группировка не подходит потому что Типы в группе — у всех предметов разные.
группировка для поиска 10 лучших в пределах одного типа

т.е. первый набор это
Select 12 первых записей
From (первая запись в группе сортировка критерий desc)
Order by критерий desc

второй набор это
Select 12 первых записей
From (вторая запись в группе сортировка критерий desc)
Order by критерий desc

и т.д.
(и все это в рамках FB)

Я правильно понял?

Отредактировано AVC — 08/06/2006, 08:27
Konstantine
Отправлено: 08.06.2006, 10:21


Мастер участка

Группа: Модератор
Сообщений: 545



ммм, боюсь что нет...
типов ровно 12.
предметов — может быть от 1 до 50 (не больше — точно, реально около 20)

>группировка для поиска 10 лучших в пределах одного типа
а что это даст?

>т.е. первый набор это...
не — это не то выберет...

вот именно потому у меня и построен был запрос (для упрощения пишу только на 3 типа):
SQL
SELECT TOP 10 T1.ID, T2.ID, T3.ID
FROM T1,T2,T3 WHERE (T1.Param1+T2.Param1+T3.Param1)>30 AND (T1.Param3+T2.Param3+T3.Param3)<50
ORDER BY (T1.Param2+T2.Param2+T3.Param2)

где T1 — это VIEW:
SQL
SELECT * FROM Things WHERE Type_=1

T2 — это VIEW:
SQL
SELECT * FROM Things WHERE Type_=2

T3 — это VIEW:
SQL
SELECT * FROM Things WHERE Type_=3

т.е. критерийи:
- Param1 в наборе>30
- Param3 в наборе <50
- максимальный Param2

вот так на 3 — проходит хорошо, на 6 — с трудом, а больше — вообще нереально (ну 20^12 = очень много комбинаций)

Отредактировано Konstantine — 08/06/2006, 10:25
olegenty
Отправлено: 08.06.2006, 11:23


Ветеран

Группа: Модератор
Сообщений: 2412



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

в этому случае быстрее всего сработал бы вариант с использованием временной таблицы.
1. во временную таблицу записать это декартово произведение
2. создать по ней целевой индекс
3. сделать выборку
4. дропнуть временную таблицу

Firebird 1.5 не поддерживает временных таблиц.
Firebird 2.0 по-моему уже поддерживает, но он всего лишь RC2
olegenty
Отправлено: 08.06.2006, 11:35


Ветеран

Группа: Модератор
Сообщений: 2412



пардонте, ещё уточнение. записи, которые могут быть отрезаны по величине одной штучки (например, T1.Param3 = 50) для указанного примера, должны быть отсечены ДО попадания в декартово произведение (при наличие индексов по параметрам — будет ускорение).

и тогда во временную таблицу надо помещать декартово произведение сабселектов, а не вьюх.
Konstantine
Отправлено: 08.06.2006, 11:45


Мастер участка

Группа: Модератор
Сообщений: 545



ну вот — получается что сама таблица будет очень долго создаваться (правда проверял на Access).
при 6 типах — получаются миллионы записей, а на 12 — я уже названия таких чисел забыл smile.gif
и плюс индекс создать — на него же тоже время надо.

>записи, которые могут быть отрезаны по величине одной штучки (например, T1.Param3 = 50) для указанного примера, должны быть отсечены ДО попадания в декартово произведение
а как? ведь у меня 50 — это параметр набора, а его я узнаю лишь сложив параметры предметов в наборе. а это — лишь после произведения...
или я не понял мысли?
Konstantine
Отправлено: 08.06.2006, 11:48


Мастер участка

Группа: Модератор
Сообщений: 545



также ещё остаётся открытым вопрос — это елать лучше в
Embedded FireBird или Access — оба меня устраивают, но Access немного лучше пока себя показывает
olegenty
Отправлено: 08.06.2006, 12:05


Ветеран

Группа: Модератор
Сообщений: 2412



неправильно понял. если ОДИН из параметров записи ОДНОГО типа НЕ подходит под ЦЕЛЕВОЕ условие, запись не должна попадать в декартово произведение. у тебя условие < 50. Но ты видишь, что запись из View1 имеет значение параметра = 50. значит сумма параметров всех View будет> 50. так зачем запись в выборке.
вспоминать комбинаторику надо и приходить к результату по шагам.
например, сначала декартово произведение по первым двум вьюхам. там уже может произойти отсев. затем, декартово произведение результата и третьей вьюхи — там тоже отсев. затем — декартово произведение результата и четвертой вьюхи... получается вполне линейная штучка... просто думай, как ты смог бы это реализовать. на MSSQL — легко. Firebird ниже 2.0 существенно слабее...
Gedeon
Отправлено: 08.06.2006, 13:34


Ветеран

Группа: Модератор
Сообщений: 1742



QUOTE (olegenty @ 08/06/2006, 11:23)
в этому случае быстрее всего сработал бы вариант с использованием временной таблицы.
1. во временную таблицу записать это декартово произведение
2. создать по ней целевой индекс
3. сделать выборку
4. дропнуть временную таблицу

Да боюсь не особо поможет, там как раз основное время и тратится на создание этого декартового набора.
olegenty
Отправлено: 08.06.2006, 13:40


Ветеран

Группа: Модератор
Сообщений: 2412



2 Gedeon — читай мой предыдущий пост. я уже передумал и исправился smile.gif
стр.: (2) < [1] 2 >
Вернуться в Работа с базами данных в C++Builder