Pull to refresh

Comments 20

В «теории» так делать можно. Однако, на практике это не более чем «костыль», призванный хоть чем-то сгладить «дефект проектировки», когда о структуре таблиц подумали, а о безопасности забыли.
Не могу согласиться. В модели данных, для которой выполнялся поиск решения, действительно отсутствует специализированные средства, которые бы были разработаны для предоставления доступа к строкам на уровне пользователя. Но проблема заключалась не в этом. Перечень необходимых расширений в виде триггеров, констрейнов, таблиц – для актуализации журнала доступа или нагромождение представлениями, не казались приемлемыми решениями.
Если вашу фразу "… модели данных, для которой выполнялся поиск решения ....." перевести на русския язык, то она будет звучать так:

Если вашу БД создавал «школьник», который с Oracle пытается работать «как с мускулем» (т.е. для которого такие штатные и проверенные решения как триггеры, констрейнты и «нагромождения представлений» не кажутся «приемлемыми решениями» в виду отсутствия опыта проектирования корпоративных систем), а за неделю до ввода системы в продакшен, ВНЕЗАПНО оказывается что доступ-то как-то все-таки разграничивать надо, то, действительно, ничего не поделаешь, придется привлекать DBA-я, для того, чтобы он вбил вышеописанный «костыль» ;)

Уверен, что лишь специалист с глубоким опытом проектирования корпоративных систем, никогда не поскупится на создание лишних триггеров и представлений дублирующих имеющиеся таблицы. И конечно же, запросто перепишет те из них, которые перестанут удовлетворять требованиям ограничения доступа — сразу на продуктивной системе.
Зря иронизируете, специалист проектирования корпоративных систем именно так и поступит. Ибо с нормальной корпоративной БД могут работать десятки независимых приложений, каждое которое работает со своим бизнес-функционалом и нарушение нормального функционирования которых это попадалово на огромное бабло (как вы думаете, на сколько порядков день простоя какого-нибудь филиала стоит дороже получаса работы даже высококвалифицированного разработчика).
Так что в нормальных корпоративных системах сама возможность «лазить грязными руками напрямую в таблицы» просто недопустима. Весь просмотр данных только через вью/функции и никак иначе. Вся модификация данных идет только через пакетные процедуры и никак иначе! Прикладное программное обеспечение работает только с фронтендом БД как с API. И разработчик может сто раз поменять схемы хранения структур данных без риска что-то сломать.

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

Признаки нормально спроектированной корпоративной БД:
* Уровень хранения данных должен быть независим от уровня представления бизнес-сущностей
* С клиентского уровня не должно в принципе быть способов вызвать изменение данных не предусмотренных бизес-логикой
* Security-логика существует независимо и прозрачно по отношению к Бизнес-логике.

А проектировать корпоративную БД из предположения что сней будет работать «только я и мой сраный php-скрипт», это извините, детский сад.

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

Вообще-то хинт NOCACHE имеет совершенно другое действие и тут совершенно лишний :)
Вообще, в прнципе не существует хинтов, которые могут влиять на результат выборки, разве что только на порядок строк или при использовании rownum, хотя и на это нельзя ни в коем случае нельзя закладываться в разработке :)
Вынужден согласиться. Из приведенного примера убрал.
В статье, конечно, еще очень много чего сильно режет глаз.

Например, в коде с созданием таблиц и вставкой в них пристутствует неявный commit, что не результат не влияет, но как-то некрасиво.

За создание объектов схеме sys руки надо отрывать сразу — хуже подлянки для dba не придумаешь. Представляете, что будет, если oracle захочет в 12-ой версии сделать своей объект с именем number_table?

Условие в таком виде upper(oracle_user) = upper(USER) не позволит использовать индексы.

Конструкция WHERE ud_user_id = ' || userid || ' приведет к парсингу и разростанию shared_pool из-за отсутствия параметризации.

При наличии достаточно большого кол-ва записей в таблице user_data и достаточного кол-ва сессий сервер ляжет по оперативке из-за массивов в памяти.

Ну и самое главное, что я пока не могу понять, почему нельзя в первом варианте просто заменить

select ua_id into userid from scott.user_allowed where upper(oracle_user) = upper(USER);return 'ud_id in (SELECT ud_id FROM scott.user_data WHERE ud_user_id = ' || userid || ')';

на

return 'ud_user_id in ( select ua_id from scott.user_allowed where upper(oracle_user) = upper(USER)';

Ну, или просто использовать обычный view, которые места и русурсов не занимают и как-то проще в администрировании, чем FGAC.
Я же указал в начале поста, о том, что привожу тестовый пример. В первом случае, выполнять этот подзапрос не имеет смысла, как впрочем, и во втором случае без него можно обойтись.
В таблицах отсутствует первичный ключ, триггер на его генерацию и создание сиквенса, не созданы индексы, и не даны рекомендации по наполнению тестовыми данными таблицы user_data. Используется пользователь SCOTT, явно из тестовый БД, которой на продуктивной, как правило, нет.
А что не так с commit? Создали таблицу, вставили данные, далее предполагается смена пользователя…
Простейший вопрос — в какой момент в скрипте происходит commit для первых двух insert в таблицу scott.user_allowed?
После создания таблицы user_data и вставки данных и туда.
Ну, вот, садитесь, 2 балла :)
В oracle любой DDL содержит неявный commit. Т.е. операция create table user_data также производит неявный commit двух предыдущих insert.
Я бы все же советовал Вам изучить хотя бы основы SQL, реляционных баз, ACID-теста, блокировок и т.п., прежде чем лезть в такие дебри, как FGAC.
Я, конечно, понимаю, что «не боги горшки обжигают», но тут уж слишком бросается в глаза непрофессионализм.
Тут я был не прав, подвох в вопросе чувствовался, но навскидку сразу не вспомнил.
Исходя из приведенных рекомендаций, я скорректировал пример.

Условие в таком виде upper(oracle_user) = upper(USER) не позволит использовать индексы.

Вы в этом уверены?
Можно использовать функиональный индекс, но лучше все же попытаться сделать так, чтобы значения в колонку oracle_user попадали уже в uppercase.
Хотя бы потому, что поведение команды drop index для обычного индекса и функционального имеет важные для production системы отличие. Сможете найти, какое? :)
Вообще, в прнципе не существует хинтов, которые могут влиять на результат выборки, разве что только на порядок строк или при использовании rownum, хотя и на это нельзя ни в коем случае нельзя закладываться в разработке :)
Эхъ, если бы… :) да и ладно для выборки… а для инсертов которые? :)
Я говорил про содержимое выборки, а не про скорость работы же :)
А чего там с insert — я, вроде, кроме append и parallel больше ничего не использую обычно.
И я про это же :) например кучи багов с трансформацией ансишных джойнов да ивообще с трансформацией. Про инсерт я про новые игноры дубликатов и тд
Ну баги, да, согласен… радует баги такого типа самые приоритетные для OSS и фиксятся в первую очередь, насколько я знаю.

Ох, да, спасибо. Почитал это:
guyharrison.squarespace.com/blog/2010/1/1/the-11gr2-ignore_row_on_dupkey_index-hint.html
Узнал для себя много нового. Очень надеюсь, что данный хинт разработчиками не буджет использоваться вовсе…
Sign up to leave a comment.

Articles