CftClub.ru
Клуб специалистов ЦФТ-Банк

Родительские и дочерние таблицы
На страницу 1, 2, 3  След.
 
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Разработка в PL/PLUS. Оптимизация запросов Oracle
Предыдущая тема :: Следующая тема  
Автор Сообщение
yaffil
Профи


Вступление в Клуб: 18.08.2011
СообщениеЧт Янв 17, 2013 17:04   Родительские и дочерние таблицы Ответить с цитатой
Полезность: Нет оценки
Есть задача ежедневного импорта множества различных данных по клиентам, например Клиент, депозит, счета ...
Которые надо перелить в другую Оракловую базу посредством множества файлов с определённой структурой, например, Клиент.txt, депозит.txt, счета.txt ...
Общее у них - id Клиента.

Решил использовать структуру:
1. Родительский тип в нем 1 реквизит id Клиента
2. Дочерние типы Клиент, депозит, счета ... + темповая FIS_EXPORT в которой будет определяться необходимость выгрузки той или иной таблицы (т.к. нужны только клиенты с изм. данными) с реквизитами которые нужны для выгрузки

Я могу так это дело использовать? А то мне компилятор на
Код:
 delete x in ::[FIS_EXPORT];

Предупреждает - возможно неконсистентное удаление.
Что это?
Я правильно понимаю, что такая структура равнозначна созданию отдельных таблиц в каждой из которых будет реквизит id Клиента?
Или лучше всё таки отдельными таблицами независимыми?

З.Ы. такой способ выбран из за красоты визуального восприятия в словаре данных. Т.к. открываешь + и видишь какие у тебя таблицы используются для этого проекта т.е. сгруппированы. И ЦФТ не сильно пугается видя 1 справочник, а не 41 Very Happy
Alexsey
Эксперт


Вступление в Клуб: 06.09.2007
СообщениеЧт Янв 17, 2013 18:30    Ответить с цитатой
Полезность: Нет оценки
В случае дочерних таблиц получится список независимых таблиц объединенных в таблице CLASSES полем PARENT_ID. В Администраторе словаря это будет выглядеть как набор ТБП с общим реквизитом ID Клиента. По сути, для красоты можно справочники сгруппировать, тогда они будут выглядеть красиво еще и в навигатре Smile Получается, что в таблице FIS_EXPORT будет так же реквизит ID Клиента.
У меня возник вопрос, насколько необходима эта временная таблица для определения выгрузки? Не проще будет инициализировать в памяти таблицу записей или какой-либо другой механизм аля переменная типа логика?
_________________
всегда есть как минимум 2 выхода
Alkov
Профи


Вступление в Клуб: 23.09.2010
СообщениеПт Янв 18, 2013 03:37    Ответить с цитатой
Полезность: Нет оценки
1.А та другая база Oracle имеет такую же структуру ?
2.Почему не использовать dblink , без выгрузки в файлы ?
yaffil
Профи


Вступление в Клуб: 18.08.2011
СообщениеПт Янв 18, 2013 08:12    Ответить с цитатой
Полезность: Нет оценки
Alkov пишет:
1.А та другая база Oracle имеет такую же структуру ?
2.Почему не использовать dblink , без выгрузки в файлы ?


1. Такую же, т.к. они предоставили форматы, а я делаю 41 файл под их форматы.
2. Я бы, с удовольствием, но ЦФТ находится на аутсорте в Новосибе и никакой вариант с ДБлинками они не разрешат. Остается только файлообмен.
yaffil
Профи


Вступление в Клуб: 18.08.2011
СообщениеПт Янв 18, 2013 08:24    Ответить с цитатой
Полезность: Нет оценки
Alexsey пишет:

У меня возник вопрос, насколько необходима эта временная таблица для определения выгрузки? Не проще будет инициализировать в памяти таблицу записей или какой-либо другой механизм аля переменная типа логика?


Я думал, как можно попроще извратиться, но тут система дурацкая, есть 41 таблица с разным набором полей. Необходимо заливать только те, где было хоть какое то изменение. При этом чтобы залить дочернюю таблицу, надо сначала залить её родителей. При этом там есть параметр LOAD_ID который должен присутствовать во всех таблицах по одному клиенту одинаковый, но есть исключения (примерно 10 таблиц должны быть с другим одинаковым ID). Т.е. по одному клиенту используется 2 ID.
Поэтому я ничего не придумал как использовать базовый набор 41 таблицы для самой выгрузки и сверкой изменения значения в АБС, а временну использую как счетчик по таблицам, надо или не надо её выгружать.
Т.е. первый цикл бежит по всем клиентам в АБС, сверяет её с данными в 41 таблице и если есть изменения апдейтит соответствующую таблицу + по временной таблице меняет реквизит (boolean) с аналогичным названием таблицы на true.
Второй цикл бежит по временной таблице и по реквизитам со значением true выгружает соответствующую таблицу в файл.

На вскидку ничего другого не смог придумать Very Happy
yaffil
Профи


Вступление в Клуб: 18.08.2011
СообщениеПт Янв 18, 2013 08:28    Ответить с цитатой
Полезность: Нет оценки
Меня больше напрягает фраза-предупреждения компилятора
Код:
возможно неконсистентное удаление

Что это такое и где оно может бахнуть или не может?
vtar
Эксперт


Вступление в Клуб: 20.03.2009
СообщениеПт Янв 18, 2013 09:19    Ответить с цитатой
Полезность: Нет оценки
могу предположить, что это предупреждение о возможности частичного удаления связанных данных ( останутся ссылки на удаленные объекты).

Лучше спросить у фирмы производителя компилятора Smile
Alkov
Профи


Вступление в Клуб: 23.09.2010
СообщениеПт Янв 18, 2013 10:41    Ответить с цитатой
Полезность: Нет оценки
delete x in ::[FIS_EXPORT];
наверное надо было дописать в конце all

можно попробовать за основу взять операцию которую создать Генератором экспорта.
yaffil
Профи


Вступление в Клуб: 18.08.2011
СообщениеПт Янв 18, 2013 11:47    Ответить с цитатой
Полезность: Нет оценки
Нет, all тут ни при чём. Я же под ноль зачищаю эту временную таблицу.
Может оно имеется в виду, что тут всё грохнется, а в родительской ничего не потрётся и останутся значение общего реквизита т.е. ID клиента?
Ну собственно оно так и предполагается чтобы работало Very Happy

Кстати, как сравнить значения в наших таблицах для выгрузки с теми что в АБС (изменился ли реквизит с момента последней выгрузки). Тупо if по всем полям с соответствующими в АБС? Или есть более практичный способ?
Volod
Эксперт


Вступление в Клуб: 19.09.2007
СообщениеПт Янв 18, 2013 20:31    Ответить с цитатой
Полезность: Нет оценки
yaffil пишет:

Кстати, как сравнить значения в наших таблицах для выгрузки с теми что в АБС (изменился ли реквизит с момента последней выгрузки)?


Например так,

Код:
(select 1, 2, 3 from dual -- 1 база
union all
select 4, 5, 6 from dual
)
minus
(select 1, 2, 3 from dual -- 2 база
union all
select 5, 5, 6 from dual -- данные изменились
)
Random
Эксперт


Вступление в Клуб: 27.06.2011
СообщениеПн Янв 21, 2013 12:07   Re: Родительские и дочерние таблицы Ответить с цитатой
Полезность: Нет оценки
yaffil пишет:
Решил использовать структуру:
1. Родительский тип в нем 1 реквизит id Клиента
2. Дочерние типы Клиент, депозит, счета ... + темповая FIS_EXPORT в которой будет определяться необходимость выгрузки той или иной таблицы (т.к. нужны только клиенты с изм. данными) с реквизитами которые нужны для выгрузки


Не делай так Smile

1. в общей для всех структур таблице будут храниться все данные депозитов, клиентов, счетов, и т.д. Соответственнго, она будет очень длинная.
Любой индекс в ней будет очень большой.
Перестройка этого индекса будет очень медленной. Это удаление, вставка, изменение информации.
2. Для вставки данных в, например, счета, нужно делать два шага вместо одного.
3. удаление - аналогично.
4. Я недавно оптимизировал 133 форму. Проблема - все данные одной реализации (несколько десятков тысяч записей) вытаскиваются из таблицы 8 секунд. Связка reps_data и f_133_data. из одной таблицы - на порядок быстрее.
5. Группировать структуры можно, залепив в длинное имя с начала определённую приставку.

6. Кстати, ты уже задумался, что будет, если тебе предложат лить клиентов из двух разных мест? Если их потребуется "свести", то есть выкинуть одну запись, оставив другую?

yaffil пишет:
Предупреждает - возможно неконсистентное удаление.
Что это?

Это значит, что в родительской таблице ты данные удаляешь, а в дочерней - нет.
Если наоборот, то компилятор сам должен понять и вставить удаление из родительской тоже.
yaffil пишет:

Я правильно понимаю, что такая структура равнозначна созданию отдельных таблиц в каждой из которых будет реквизит id Клиента?

Нет.
Такая структура эквивалентна созданию n+1 таблицы, при этом:

CLIENTS
----------------
*id
... другие реквизиты клиентов

ACCOUNTS
----------------
*id
... другие реквизиты счетов
...


и ещё одна родительская
PARENT
---------------
*id
CLIENT_ID


При этом select id from z#PARENT даст те же самые значения, что и
select id from z#clients
union all
select id from z#accounts
union all
...

на поле id вешается foreign constraint, совершенно лишний, который будет замедлять удаление.

PS: Насколько понимаю, делаешь ХД?
yaffil
Профи


Вступление в Клуб: 18.08.2011
СообщениеПн Янв 21, 2013 16:30    Ответить с цитатой
Полезность: Нет оценки
Собственно засада, не знаю как побороть:

Код в операции тип "групповая":
Код:

for (select fis (fis.[KLIENT_ID] :C_KLI_ID, fis%id :C_ID) in ::[STR_FIS_EXPORT]all where fis.[NATURAL1]) loop
debug_pipe('FIS.[KLIENT_ID]: '||FIS.C_KLI_ID,0);
debug_pipe('FIS: '||FIS.C_ID,0);
end loop;


Выдаёт правильный C_ID, но пустой C_KLI_ID, хотя по завершении операции я в представлении вижу правильный ID и KLI_ID. Собственно проваливаюсь на нужного клиента.

Компилятор перевернул код вот так:

Код:
      declare
         cursor c_obj is
            select  a2.C_LOAD_ID C_KLI_ID, a1.ID C_ID
            from Z#STR_IMPORT_FIS a2, Z#STR_FIS_EXPORT a1
            where a1.id=a2.id
              and ((a1.C_NATURAL1 = '1'));
         FIS   c_obj%rowtype;
      begin
         for plp$c_obj in c_obj loop
            FIS := plp$c_obj;
--# 310,1
            RTL.DEBUG_PIPE('FIS.[KLIENT_ID]: '||FIS.C_KLI_ID,0);
            RTL.DEBUG_PIPE('FIS: '||FIS.C_ID,0);
         end loop;
      end;


Таблица Z#STR_IMPORT_FIS является родительской для Z#STR_FIS_EXPORT.

Где засада?

П.С. каким то волшебным образом компилятор переделывает реквизит на родительский (a2.C_LOAD_ID C_KLI_ID) и при чём совсем не тот который в PL+ написан (fis.[KLIENT_ID] :C_KLI_ID)


Последний раз редактировалось: yaffil (Пн Янв 21, 2013 17:07), всего редактировалось 1 раз
yaffil
Профи


Вступление в Клуб: 18.08.2011
СообщениеПн Янв 21, 2013 16:38   Re: Родительские и дочерние таблицы Ответить с цитатой
Полезность: Нет оценки
Random пишет:


Не делай так Smile

1. в общей для всех структур таблице будут храниться все данные депозитов, клиентов, счетов, и т.д. Соответственнго, она будет очень длинная.



Почему длинная? Смотрю на таблицу через арм админа, вижу, что она не затягивает в себя реквизиты дочерних таблиц.

Random пишет:

2. Для вставки данных в, например, счета, нужно делать два шага вместо одного.
3. удаление - аналогично.


Зачем 2 раза, родительская у меня только для связи всех дочерних таблиц одним ID клиента

Random пишет:

При этом select id from z#PARENT даст те же самые значения, что и
select id from z#clients
union all
select id from z#accounts
union all
...

Собственно оно так и предполагается. Предлагаешь делать всё независимыми справочниками?


Random пишет:

PS: Насколько понимаю, делаешь ХД?


Что такое ХД? Shocked А то у меня фантазия щаз разыграется.
Random
Эксперт


Вступление в Клуб: 27.06.2011
СообщениеВт Янв 22, 2013 08:11   Re: Родительские и дочерние таблицы Ответить с цитатой
Полезность: Нет оценки
yaffil пишет:
Random пишет:


Не делай так Smile

1. в общей для всех структур таблице будут храниться все данные депозитов, клиентов, счетов, и т.д. Соответственнго, она будет очень длинная.



Почему длинная? Смотрю на таблицу через арм админа, вижу, что она не затягивает в себя реквизиты дочерних таблиц.

Если б затягивала, была бы ещё и широкая
yaffil пишет:

Random пишет:

2. Для вставки данных в, например, счета, нужно делать два шага вместо одного.
3. удаление - аналогично.


Зачем 2 раза, родительская у меня только для связи всех дочерних таблиц одним ID клиента

А затем, что таково свойство родительских таблиц.
Говорю ж, в дочерней табличке есть констрейнт на родительскую.
Например, посмотри у клиентов.
Есть клиент. Абстрактный клиент, непонятно, банк или физик.
У банка не может быть ФИО, у клиента - SWIFT-кода. Но у того и другого есть дата заведения клиента в базе.
Физик и Банк - потомки одного родительского класса Клиенты. Идентификатор Физика (значение поля id таблицы z#cl_priv) должен присутствовать в поле id таблицы z#client согласно констрейнту FK_Z#CL_PRIV_ID. Должен и точка.

Соответсвенно, в дочернюю таблицу нельзя вставить данные, не вставив их предварительно в родительскую таблицу, и наоборот, удалить из родительской, не удалив из дочерней, нельзя.
Кроме того, если удалять данные только из дочерней, не удаляя из родительской, будет то самое "неконсистентное" удаление, за последствия такого действия... короче, я хз что случится. Как самое малое, системные вьюшки перестанут работать.

yaffil пишет:

Random пишет:

При этом select id from z#PARENT даст те же самые значения, что и
select id from z#clients
union all
select id from z#accounts
union all
...

Собственно оно так и предполагается. Предлагаешь делать всё независимыми справочниками?

Предлагаю.

yaffil пишет:

Random пишет:

PS: Насколько понимаю, делаешь ХД?


Что такое ХД? Shocked А то у меня фантазия щаз разыграется.


ХД = Хранилище Данных


Последний раз редактировалось: Random (Вт Янв 22, 2013 08:18), всего редактировалось 1 раз
Random
Эксперт


Вступление в Клуб: 27.06.2011
СообщениеВт Янв 22, 2013 08:15    Ответить с цитатой
Полезность: 1
yaffil пишет:
Собственно засада, не знаю как побороть:
...
П.С. каким то волшебным образом компилятор переделывает реквизит на родительский (a2.C_LOAD_ID C_KLI_ID) и при чём совсем не тот который в PL+ написан (fis.[KLIENT_ID] :C_KLI_ID)


Соответствие реквизитов модели и столбцов в таблице можно посмотреть на закладке "Таблица" при просмотре класса.

Переименовывал, наверное, реквизиты? Рекомендую перестроить обе таблицы, родительскую и дочернюю.
Показать сообщения:   
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Разработка в PL/PLUS. Оптимизация запросов Oracle Часовой пояс: GMT + 3
На страницу 1, 2, 3  След.
Страница 1 из 3

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Рейтинг@Mail.ru