Давайте я вам лучше про русских раскажу?
Итак, невъ...нно "корпоративная платформа". Оракел, репликация, оперативный, бухгалтерский, табельный и прочие учеты, ынытрпрайз, все понты. Самописное _всё_
Заглядываем внутрь - 2800 таблиц, дофига представлений, документы, бизнес-процессы. Задача: развернуть сеть точек продаж (стол, стул, компутер, сканер штрихкодов, полка с товарами), а также центральный сервер, на котором будет видно движение товара по всем точкам, в условиях плохой связи.
Казалось бы, что может быть проще? Берем торговый терминал, на котором ведется десяток табличек (товары/цены/операции), ставим его на endpoint, настраиваем выгрузку операций продажи на центральный сервер (в пакетном режиме по шедулеру), и такую же пакетную загрузку данных с центрального сервера.
Но нет - это не ынтырпрайс. Поэтому делается "почти-копия" центрального сервера со всей его невъ...ной базой, и ставится на комп этого самого удаленного объекта(!). Причем структура баз уже ОТЛИЧАЕТСЯ. Вплоть до различия в длине полей (фак!). Соответственно вместо компактной надежной, в которой из движущихся частей только винт и вентилятор блока питания, водружается сервер об двухъядерном процессоре и двух гигах оперативки, с ораклом 10g. На него ставится ДВЕ версии оракла - 10.2 и 8.0.5(!!!!), и клиентское приложение, написанное на... в общем не важно на чем. Достаточно точной альтернативой будет "на MS Access".
Не буду вдаваться в детали этого приложения, скажу только "программу страшнее я видел только трижды", а я, среди прочего, являюсь преподавателем в университете, то есть регулярно вижу студенческие "курсовые", "семестровые" и "дипломные" работы - то есть можете представить ЧТО это такое.
Итак, продолжаем банкет. Настройки винды (сервер на винде, да-да), оракла (noarchivelog), файрвола (отключен) оставим в стороне, заглянем под крышку этмоу чуду.
Справочник номенклатуры. Под кажду разновидность товара - своя таблица (фак!), в которой есть краткое имя товара и егео полное наименование. Но поскольку ребята-разработчики слышали о ссылочной целостности, и захотели ее использовать, они ввели таблицу "все товары", в которой тоже есть поля "наименование" и "полное наименование". При вставке товара в нужную таблицу триггеры автоматом создают соответствующую запись в "сводной" таблице. Все документы внешними ключами естественно ссылаются на сводную таблицу. Как видно, до людей просто "не дошло", что можно было делать все наоборот - сделать основной тут таблицу, которая у них "сводная", а недостающие атрибуты о различных групп товара (ну там срок хранения, масса, объем, упаковка и прочее) вынести в дополнительные таблицы.
Ну и само собой, еще множество справочников имеет аналогичную структуру (ну например погрузочно-разгрузочные терминалы - есть таблица терминалов под каждый тип: водный, ЖД, автомобильный... и есть сводная таблица "вес терминалы" куда триггеры подкладывают копии записей). Ах да - не все документы ссылаются на сводную таблицу. Некоторые ссылаюстя на таблицу объектов конкретного типа.
Продолжаем банкет, исследуем базу. Находим таблицу "свойства товара", в которую можно записать всякие дополнительную информацию (ну например страна-производитель, цвет, размер - в общем что угодно). Организовано красиво - есть таблица свойств, есть таблица значений свойств - ссылка на товар, ссылка на свойство, значение свойства (строка) и дата начала действия данного значения свойства. Даты окончания действия этого значения тупо НЕТ. Rак в этой ситуации можно написать номральный запрос "по состоянию на конкретную дату"?!?! ХЗ. Ладно, хрен с вами. Переживем.
Начинаем работу, вводим товар, штрих-код (это такое свойство есть)... Что-то не то. То товар по штрих-коду не находится, то ошибка выскакивает, то еще что-то. На центральном сервере товар появляется, на серверах "на местах" - появляется но штри-код не вводится. Мля. Начинаем ковырять триггеры: оказывается, если кто-то пытается ввести занчение "штрих-код" для товара, то один из триггеров выкидывает такой фортель: если код (ID) свойства равен 10 то автоматически добавляется строка в специальную таблицу штрих-кодов! Причем этих триггеров существует два варианта - один на центральном сервере, другой на сервере точки продаж, причем дублирование штрих-кодов на центральном сервере возможно, а на сервере точки продаж на это специальной таблице стоит проверка на уникальность штрих-кода! На этом месте у меня начинается истерика, поскольку пользователи вводят товары на центральном сервере, где можно в результате получить дублирующиеся штрих-коды. И мы их получили. Обращаемся к разработчикам - они отказываются включать проверку на дублирование штрих-кода в базе центрального сервера. Проблема дублей их не волнует. Хрен с ними, пишу код сам, не трогая "аффтарские" чудачества.
В один день перестает работать репликация (точнее, она два раза в неделю ломается, но не будем заострять внимание). Результат разборок ужасает. Процесс репликации оказывается происходит так: каждое изменение, которое должно быть отреплицировано, записывается в специальную таблицу.
Потом с помощью ораклового exp данные этой таблицы выгружаются в дамп (бинарник) и этот дамп отправляется к местоназначению. На той стороне с помощью IMP данные вливаются в базу и потом специальная программка формирует SQL-запросы, которые накатывает в базу. Причем термина "порядок репликации" (типа сначала реплицируем справочники, потом документы которые на них ссылаются) нет. Программа тупо делает три попытки, и если обломалась - репликация помечается как "ошибочная".
В экзешник программы репликации зашиты имя и пароль юзера, под которыми она подключается к базе(!!!) Эта программа формирует и выполняет SQL-запросы по алгоритму
$sql = "insert into tablename(field1,field2) values ('" + $value1 + "','" + $value2 + "')";
exec_sql( $sql );
И что происходит если $value1 является строкой, содержащей апостроф?
Вот так вот бывает. А вы говорите "индусы", "быдлокодеры"...