|
|
|
Прошу совета, помощи
|
|||
|---|---|---|---|
|
#18+
Всем привет. Столкнулся я со следующей ситуацией. Может кто чего посоветует. В наследство досталась база с довольно необычной для воспроиятия структурой. Крутится она на Оракле. Абстрактно это выглядит так: |Table1| -------- id_1 name ...... |Table2| ------- id_1 (ссылка на id1 из Table1) id_2 name ........ |Table3| ------- id_1 (ссылка на id1 из Table2) id_2 (ссылка на id2 из Table2) id_3 name ......... Ну и так далее. При этом набор id_x - это составной первичный ключ в соотв. таблице. Естесственно, в таблице есть и связи М:М. В некоторых ситуациях таблицы замыкаются в кольцо, ну и т.п. Просто я как-то привык за время своей небольшой и еще малоопытной жизни к немного другой структуре. Когда в качестве Первичного ключа выбирается идентификатор, а связь 1:М или М:1 реализуется через внешний ключ. В таблице, которая организует связь М:М в качестве первичного ключа выступает составной ключ из внешних ключей на связываемые таблицы. При структуре, которая описана выше есть свои плюсы, безусловно: 1. Из самых глубоких таблиц можно быстро получить доступ к самым верхним за счет того, что в глубокой таблице полностью лежит первичный ключ верхней таблицы 2. Появляется возможность своего рода контроля. Например, когда организуется связь М:М необходимо, чтобы у связываемых записей была одна и та же запись-родитель в верхней таблице. Типа: |Table1| .... first1 ..... ________ ......... Таблицы, связанные 1:М ......... ________ |Table1N| .... first1N ..... Та же |Table1| .... first1 ..... ________ ......... Таблицы, связанные 1:М ......... ________ |Table2N| .... first2N ..... first1N ссылается на first1 и first2N ссылается на first1.Требуется организовать связь между first1N и first2N через соотв. таблицу связку. Но есть ограничения предметной области, что эту связь возможно организовать ТОЛЬКО при условии, что и first1N, и first2N ссылаются (может и через другие таблицы) на first1. Если использовать предложенную структуру, то в таблице, организующей связь между Table1N и Table2N в составном ключе используется только одно поле id_1, которое одновременно ссылается на одноименное поле в Table1N и в Table2N Может были еще какие-то плюсы такой организации, но уже не помню. Минусы тоже вроде как очевидны. Для связи таблиц, находящихся достаточно глубоко в иерархии, приходится ставить в соответствие большое количество полей (первичный ключ на нижних уровнях иерархии при такой организации может достигать 6-7 составных полей). Ну и для того, чтобы получить какие-нибудь данные из непосредственно связанной таблицы надо писать условие из 5-6 равенств. Не знаю, как Оракл, но, мне кажется, для БД очень трудоёмко поддерживать такой вот составной первичный ключ. Да и на сколько падает при этом скорость объединения ьаблиц в запросах - я не знаю :-( ......................................... Если же реорганизовать структуру БД более стандартным способом, то плюсом будет то, что писать запросы станет гораздо легче, первичный ключ будет состоять из 1, максимум 2 полей. Минусы: 1) Для того, чтобы получить данные из верхней таблицы, придется писать запрос со связью 4-5 таблиц, а не 2, как это делается сейчас. 2) (Скажите, так или не так, потому как сам не знаю) Если создать View на основе 2 варианта структуры БД, при чем View будут структуры, подобной структуре таблиц 1 варианта, то вроде как это начнет сильно тормозить систему. Например, SELECT, выбирающий данные из View работает гораздо медленне, чем SELECT, выбирающий данные из Table. А если учесть желание получить подобную в 1 вложенность всех ключей из вышестоящих таблиц, то надо либо создавать View на основе объединения 4-6 таблиц, либо эти view писать тоже матрешкой. В смысле, каждое последующее, будет получать данные изх своей таблицы + из view, написанного до него. Соответственно скорость работы с подобной орагнизацией данных упадет. Не тестировал - не знаю. Может вы подскажите 3) Пропадет контроль, описанный в п.2 выше. Предложение написать Триггеры, обрабатывающее условие пренадлежности одной записи, отвергается. Говорят, что триггеры работают медленнее, чем ссылочная целостность в Оракл. Типа уж лучше будет составной первичный ключ и проверка будет по ссылочной целостности, чем будет работать долгая процедура Триггера. 4) Система, помино написанного пользовательского интерфейса зачастую пополняется большими массивами данных из вне, которые заносить через интерфейс очень трудоемко. Для этой цели данные загружаются в БД посредством написанных ad hoc (специально под каждый конкретный случай) INSERT'ов и UPDATE'ов. Соответственно, когда в таблице хранится такой составной ключик, то самому пользователю будет сложнее ошибиться при написании таких вот вставок, чем если в таблице будет содержаться только внешний ключик на первичный ключ вышестоящей таблицы. (Уж не знаю, почему в системе не разработана система Импорта данных... или это на столько трудноформализуемо и труднореализуемо) Что скажете Вы. Понятно, что 1 вариант имеет право на жизнь и даже есть вполне обоснованная логика. Но я не сталкивался с подобной структурой и не могу предугадать, к чему это может в дальнейшем привести. Сейчас эта структура функционирует. Но ее планируется расширять. С какими серьезными проблемами можно столкнуться в дальнейшем? С нетерпением жду ответа или ссылок на интересные материалы. Заранее спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.04.2006, 14:38 |
|
||
|
Прошу совета, помощи
|
|||
|---|---|---|---|
|
#18+
авторНе знаю, как Оракл, но, мне кажется, для БД очень трудоёмко поддерживать такой вот составной первичный ключ. Да и на сколько падает при этом скорость объединения ьаблиц в запросах - я не знаю :-( А вы попробуйте, что будет работать быстрее, запрос в котором 2 таблицы джойнятся или 3. вопросы сами собой отпадут. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.04.2006, 15:23 |
|
||
|
Прошу совета, помощи
|
|||
|---|---|---|---|
|
#18+
Скажем так, первый вариант иногда удобен, но повсеместное его применение напоминает пословицу про "лоб разобьет". Он действительно имеет преимущество при осуществлении "далеких" join-ов и помогает поддержать целостность при сложных связях "многие ко многим", но крайне осложняет разработку и, если говорить об учетных системах, OLTP, дает существенную дополнительную нагрузку. Полагаю, вариант, когда такая структура данных уместна - некая "БД для аналитика", некое относительно нормализованное хранилище данных, используемое пользователем-экспертом для копания, свободного поиска, неформализованных запросов с использованием подходящего инструмента (построителя запросов). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.04.2006, 18:23 |
|
||
|
Прошу совета, помощи
|
|||
|---|---|---|---|
|
#18+
gardenmanА вы попробуйте, что будет работать быстрее, запрос в котором 2 таблицы джойнятся или 3. вопросы сами собой отпадут. А есть какие-то другие средства тестирования быстродействия? А то на самом деле так получается, что всё зависит от случая: У меня то один, то другой запрос быстрее выполняется... И от чего это зависит - не совсем понятно. Пытался найти где-нибудь - пока не получилось. Зависит ли скорость возвращения результата запроса от того, используется ли в качестве источника View или Table? Тестирование - аналогично: то быстрее, то медленнее, то одинаково. При чем не зависимо от того - выполняется это Клиентом Оракла или через собственноручно написанную прогу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:27 |
|
||
|
Прошу совета, помощи
|
|||
|---|---|---|---|
|
#18+
Тут вопрос в том, сколько страниц нужно поднимать с диска в кэш. Имеется в виду, когда таблицы полностью в кэш не помещаются. С каждым лишним джойном количество будет возрастать. Имейте это в виду. Можно даже рассмотреть эту ситуацию подробнее. если есть таблица t1(pk1),t2(fk1,pk2),t3(fk2,pk3),t4(fk3,pk4) Чтобы добраться от t1 до t4 нужно будет поднять не только страницы нидексов, но и страницы данных всех промежуточных таблиц. А во втором случае можно поднимать только страницы индексов и данных второй таблицы. Та же самая ситуация когда идем от t4 к t1. В любом случае при нормализации нужно знать меру. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:47 |
|
||
|
Прошу совета, помощи
|
|||
|---|---|---|---|
|
#18+
gardenmanВ любом случае при нормализации нужно знать меру. И что имеется в виду? Что значит нужно знать меру? Каким образом тогда представлять данные? На каком этапе нормализации остановиться? gardenmanесли есть таблица t1(pk1),t2(fk1,pk2),t3(fk2,pk3),t4(fk3,pk4) А если есть View на основе t1(pk1),t2(fk1,pk2),t3(fk2,pk3) в виде V(pk1,pk2,pk3) То ускорит это работу объединения t1 и t4? На сколько замедляют работу составные первичные ключи? На сколько медленнее работает объединение по таким составным ключам? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 12:44 |
|
||
|
Прошу совета, помощи
|
|||
|---|---|---|---|
|
#18+
Smile #8) И что имеется в виду? Что значит нужно знать меру? Каким образом тогда представлять данные? На каком этапе нормализации остановиться? Это зависит от специфики задачи. Вы архитектор - вы и решайте. Просто следите чтоб не было аномалий. Smile #8) А если есть View на основе t1(pk1),t2(fk1,pk2),t3(fk2,pk3) в виде V(pk1,pk2,pk3) То ускорит это работу объединения t1 и t4? С какой представления должны что-то ускорять? Воспринимайте предстваления как макроподскановку. Да и еще запоните истину view+view+view=смерть производительности. Не знаю что у вас за оптимизатор и как он обработает представления, но обычно возникают лишние шаги и телодвижения - следовательно лишние затраты ресурсов. Smile #8) На сколько замедляют работу составные первичные ключи? На сколько медленнее работает объединение по таким составным ключам? Основной ресурс, который тормозит все - это IO. Чем меньше IO - тем лучше. Второй ресурс - это блокировки. Смортите что блокируете, и насколько долго. Изучайте планы запросов которые юзаете. Уменьшайте количество таблиц и индексов в модели (опять же с умом, чтобы не получить сканирований таблиц где не надо, не получить аномалий, и чтобы иметь возможность index-only access там где это возможно). Тащите на клиента только те данные, которые нужно. Если вы меня спросите что лучше иметь десять простых индексов на таблице или пять составных - я всегда скажу что лучше 5 составных. Потому что, что некоторые запросы можно обрабатывать только по одному единственному индексу не поднимая с диска сами данные. Короче вывод: экспериментируйте. с опытом придет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 13:05 |
|
||
|
Прошу совета, помощи
|
|||
|---|---|---|---|
|
#18+
А можно ли добиться возможности непосредственного соединения двух дальних таблиц, обходя промежуточные не на основе составного первичного ключа? Или в данной ситуации это лучший выход? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 14:14 |
|
||
|
Прошу совета, помощи
|
|||
|---|---|---|---|
|
#18+
Smile #8)А можно ли добиться возможности непосредственного соединения двух дальних таблиц, обходя промежуточные не на основе составного первичного ключа? Или в данной ситуации это лучший выход? Я к тому, нельзя ли добиться, чтобы объединение двух соседних таблиц сожержало поменьше условий, нежели равенство каждой из частей составного первичного ключа? Всё-таки в БД используются последовательности и по сути своей уникальность обеспечивается не всем составным ключом, а уже только одним собственным ID.... Может, например, первичным ключом сделать только ID, а это составное чудо уникальным индексом.... Даст ли это что-нибудь или будет только мешать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 14:21 |
|
||
|
Прошу совета, помощи
|
|||
|---|---|---|---|
|
#18+
Smile #8)А можно ли добиться возможности непосредственного соединения двух дальних таблиц, обходя промежуточные не на основе составного первичного ключа? Или в данной ситуации это лучший выход? Для каждого случая нужно решение принимать индивидуально. Я видел людей, которые любую базу раскладывают на сущности за пять минут с простыми первичными ключами. А потом резко пишут приложение которое шустро работает па небольшом количестве записей. А потом по мере роста базы данных добавляют индексы, добавляют поля в таблицы. Короче все то, что называется "нормализацией" идет на.... Ну и в результате получается монстр, который едва ворочается. Просто помните, что когда вы проектируете таблички, то вы закладываете 90% производительности в систему. 5% даст вам настройка сервера и 5% - подход при написании морды. Хотя это все мое ИМХО. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 14:29 |
|
||
|
Прошу совета, помощи
|
|||
|---|---|---|---|
|
#18+
Спасибо за помощь и советы, gardenman. А есть еще кто-нибудь, кто может высказать СВОЁ мнение по этому вопросу? Просто основываться только на мнении одного человека как-то опасно... Неужели никто больше припроектировании БД не сталкивался с подобными проблемами? Или это единственная панацея для быстродействия системы? Почему-то о таких подходах проектирования слышу впервые :-( Может есть еще какие-то идеи?... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 14:53 |
|
||
|
Прошу совета, помощи
|
|||
|---|---|---|---|
|
#18+
Smile #8)Может, например, первичным ключом сделать только ID, а это составное чудо уникальным индексом.... Даст ли это что-нибудь или будет только мешать?На составные ключи, включающие ID, можно повесить ограничения целостности - внешние ключи , не выразимые через единственный ID. Составные ключи, не включающие ID, могут выражать предметные ограничения уникальности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 15:33 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=33691830&tid=1545295]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
145ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
52ms |
get tp. blocked users: |
1ms |
| others: | 235ms |
| total: | 470ms |

| 0 / 0 |
