Про базы данных

ych-group.ru — Коллеги, покритикуйте, подскажите - вдруг что забыл? Вдруг что не так написал?
Новости, Компьютеры | Del 15:10 08.09.2014
89 комментариев | 75 за, 4 против |
#51 | 16:35 08.09.2014 | Кому: Del
> Подскажи мне, вдруг я чего-то не знаю - как выяснить с первого взгляда, на какую таблицу ссылается поле DERIVATIVE_ID, если нет таблицы DERIATIVE?

Что значит ссылается? Внешний ключ что-ли? В phpmyadmin видно.
#52 | 16:38 08.09.2014 | Кому: Del
> PostgreSQL. Это если из двух предложенных к сравнению.

А ничего, что СУБД определяется конкретной задачей? Это как вопрос, а что лучше Ил-72 или Як-40.
#53 | 16:43 08.09.2014 | Кому: N1kMZ
> Что значит ссылается? Внешний ключ что-ли?

Он самый

> В phpmyadmin видно.


Веб-поделками стараюсь не пользоваться.
В Toad for MySQL и в MySQL Workbench именно зависимостей не видно. FK - есть, можно глянуть. Но в том же IB Expert это сделано куда удобнее.
#54 | 16:45 08.09.2014 | Кому: Dliv227
Давайте создадим и тему по обсуждению лечения геморроя тут медиков тоже есть. ИМХО длай обсуждения профессиональных аспектов, есть специализированные места. Вообшем минус теме
#55 | 16:46 08.09.2014 | Кому: N1kMZ
> А ничего, что СУБД определяется конкретной задачей?

С этом спорить не буду.
Но изучать надо то, где порог вхождения выше. Это если начинаешь, а вопрос был именно об этом, если я правильно понял.
#56 | 16:47 08.09.2014 | Кому: Del
> Подскажи мне, вдруг я чего-то не знаю - как выяснить с первого взгляда, на какую таблицу ссылается поле DERIVATIVE_ID, если нет таблицы DERIATIVE?

[Оторопело смотрит]

Так. Запрос для справки:

select O.*, C.*, D.*
from ORDERS O
left join CUSTOMERS C on (O.CUSTOMER_ID = C.CUSTOMERS_ID) 
left join DERIVATIVE D on (O.DERIVATIVE_ID = D.DERIVATIVE_ID)


Объяснение уличной магии.

Все IDE показывают связи между таблицами исключительно по имеющимся в описании этих таблиц внешним ключам. Создан внешний ключ для поля ORDERS.DERIVATIVE_ID, указывающий на поле DERIVATIVE.DERIVATIVE_ID справочника DERIVATIVE, IDE покажет стрелочку на это поле. Если внешнего ключа нет - в схеме данных соответствующей стрелочки не будет. Если внешнего ключа нет - это явный косяк кодера, который забыл создать внешний ключ, или проектировщика, который эту связь в своей техдокументации не предусмотрел.

В случае отсутствия внешнего ключа есть только один выход. Придётся прошерстить все представления и запросы БД на предмет поиска отношений "=" с этим полем ORDERS.DERIVATIVE_ID и установить, с какими другими полями оно соотносится.

IDE может также не показывать стрелочки, если она не понимает конструкцию FOREIGN KEY. В этом случае следует искать эту команду вручную. Схему данных также придётся рисовать вручную на листе ватмана требуемых размеров, или в Rational Rose.
#57 | 16:49 08.09.2014 | Кому: eric.romanoff
[censored]

Как быть?
#58 | 16:55 08.09.2014 | Кому: dse
Камрад, сейчас уже после рабочего дня мозг плохо работает, так что предметно не отвечу, но твой коммент заценил (я про запрос). Зачем же так сервак грузить? :))))

А как работают IDE - в курсе.
Shtirliz
малолетний »
#59 | 16:58 08.09.2014 | Кому: gramsci
> А с чего лучше начать изучение с PostgreSQL или MySQL?

с SQL92 =)
#60 | 17:04 08.09.2014 | Кому: pavelat
>> Индексы по полям, по которым выполняется join, уже не помогают?

> Без них вообще страшно.


И что говорит план запроса? Может, каких-то нужных индексов нет, и где-то выполняется full scan?

У MS SQL Server, например, внизу окна с планом запроса в случае обнаружения оптимизатором full scan выводится предложение создать необходимый индекс для его устранения и приводится нужная команда по его созданию.

Помнится, мне с коллегами, путем последовательного просмотра плана выполнения запроса и создания индексов по рекомендациям оптимизатора, удалось успешно снизить время выполнения сложного запроса с join'ом из, примерно, десятка таблиц с 5 мин до 10 с. Индексы создавались методом copy/paste инструкций CREATE INDEX с предлагаемыми параметрами. Процесс завершился за 5 ... 6 итераций.

И ведь ни один из нас не был SQL-программистом!
#61 | 17:07 08.09.2014 | Кому: Del
комрад, я например занимаюсь электричеством и мне кажется вот такого типа ссылка будет интересна не только узкому специалисту.
[censored]
В то же время если я захочу обсудить проблему переходных процессов в сетях с изолированной нейтралью, то на вотт.ру я точно не пойду за советом, хотя уверен, что коллеги тут есть и возможно даже завяжется дискуссия :)
#62 | 17:08 08.09.2014 | Кому: Del
> Зачем же так сервак грузить? :))))

Это пример! WHERE опущен!!!
#63 | 17:08 08.09.2014 | Кому: pavelat
> Нормальные формы эт конечно удобно и красиво. Но ждать выполнения запроса с 3-5 join'ами на таблицах с сотнями тысяч записей несколько грустно.

А какой смысл в таких массовых выборках?
#64 | 17:17 08.09.2014 | Кому: Del
> Обрати внимание на структуру тех двух таблиц, которые приведены в примере: LISTS содержит информацию, сходную по структуре, но разную по содержанию. Т.е., в LISTS могут содержаться как списочные данные об адресах, так и о породах кроликов в Новой Зеландии - всё зависит от LIST_TYPES_ID

А что не сразу всю базу в одну таблицу?
#65 | 17:18 08.09.2014 | Кому: Всем
Советы прочитал, несколько интересных моментов явно пригодятся, так что спасибо.

Спорные моменты:
1) Именно слово CAPTION как-то не очень - в переводе это "заголовок" или "подпись". Я бы предпочел "CODE" для сущностей с уникальным строковым идентификатором и "TITLE" - с неуникальным. Следует также иметь в виду, что данная БД может быть использована одновременно пользователями/программистами из разных стран и для малазийского кодера писать запрос вида "SELECT * FROM TABLE WHERE CAPTION = 'Киев'" - с кириллицей в условии - будет немного затруднительно).
2) В качестве имени таблицы лучше использовать множественное число, а не единственное. Естественнее выглядит запрос: SELECT ID FROM USERS WHERE CODE = 'Петро Гавнюк'.
3) Работа с таблицами исключительно через представления / хранимые процедуры логична, если вся бизнес-логика инкапсулирована в БД (т.е. имеем двухслойное приложение БД-клиент). Если же приложение трехслойное и бизнес-логика реализована отдельным (серверным) слоем, то БД - просто хранилище данных, а слой бизнес-логики в идеале должен реализовывать возможность автоматического создания нового хранилища выбранного типа "с нуля". Серьезные ORM (Hibernate/Nhibernate) это умеют для различных СУБД. В этом случае БД - набор таблиц и средств обеспечения целостности (ключи, условия на столбцы, триггеры), а хранимые процедуры особо и не нужны.
4) Совет из личного опыта про пару таблиц LIST_TYPES и LISTS, пмсм, вреден. Таблицы БД описывают сущности и взаимоотношения между ними, а данные в таблицах - экземпляры сущностей. Т.о. совет п.9.1. предлагает смешать сущности и их данные в одной куче. В общем случае, пмсм, лучше для каждой сущности создавать свою таблицу (Работы, Оборудование, Контрагенты, ...) и для всех справочных таблиц использовать одинаковый префикс при именовании (DIC_WORKTYPES, DIC_EQUPMENT, ...). Это, среди прочего, позволит избежать лишних условий в представлениях (а-ля SELECT ID, CAPTION FROM LISTS WHERE LIST_TYPES_ID = 12 // улицы).
Модель, когда наборы разных сущностей укладываются в две таблицы, очень удобна для ряда специфических случаев, а без особой потребности ее лучше избегать (см. выше). Пример такого случая: в приложении по учету домашних финансов нужно классифицировать покупки по категориям, причем категории могут содержать подкатегории (напр. еда - молокопродукты - сыры - твердые сыры), а пользователь добавляет категории в процессе работы. Заводить динамически отдельные таблицы для "еда", "молокопродукты" и т.п. тупо, модель из двух таблиц - самое то. Кстати, смешения сущностей и их содержания в этом случае не происходит - есть сущность "Покупка" и сущность "Категория покупки", описываемые соотв. таблицами БД.
#66 | 17:23 08.09.2014 | Кому: JohnSparrow
> Совет из личного опыта про пару таблиц LIST_TYPES и LISTS, пмсм, вреден. Таблицы БД описывают сущности и взаимоотношения между ними, а данные в таблицах - экземпляры сущностей. Т.о. совет п.9.1. предлагает смешать сущности и их данные в одной куче.

Пример из жизни - широко известный в узких кругах КЛАДР, как пример бестолкового проектирования. Используют очень многие программы, но даже те которые пользуются тем же dbf форматом переводят кладр в нормальный вид со справочниками.
#67 | 17:23 08.09.2014 | Кому: Котовод
> А что не сразу всю базу в одну таблицу?

А почему бы и нет? Денормализация доведённая до логического конца))
#68 | 17:24 08.09.2014 | Кому: Котовод
[Страшно кричит!]

Вы ещё не видели выборки из объектно-ориентированных БД с 10-кратным уровнем наследования!
#69 | 17:25 08.09.2014 | Кому: N1kMZ
>> А что не сразу всю базу в одну таблицу?

> А почему бы и нет? Денормализация доведённая до логического конца))


Дисков не напасешься!
#70 | 17:26 08.09.2014 | Кому: N1kMZ
> А почему бы и нет? Денормализация доведённая до логического конца))

Почитал JohnSparrow и понял, что в принципе от задачи зависит. Просто личный опыт где денормализация размеры базы с сотен мегабайт до нескольких десятков гигабайт в легкую вытянет.
#71 | 17:29 08.09.2014 | Кому: dse
> Вы [все] ещё не видели выборки из объектно-ориентированных БД с 10-кратным уровнем наследования!

Если чо.
#72 | 17:33 08.09.2014 | Кому: dse
> Вы ещё не видели выборки из объектно-ориентированных БД с 10-кратным уровнем наследования!

Недавно вот надо было для импорта выгружать в плоском виде - 14 таблиц, только разбил по логике на 3 запроса с объединением результатов в один. А в среднем 5-6 таблиц. По скорости достаточно быстро, так как интерфейс как правило хотелки пользователя последовательно ограничивает.
Собственно у нас обычно программистов заставляют немного на собственной программе поработать на целевой машине, на оптимизацию влияет просто мистическим образом)
#73 | 17:46 08.09.2014 | Кому: Всем
> Собственно у нас обычно программистов заставляют немного на собственной программе поработать на целевой машине, на оптимизацию влияет просто мистическим образом)

Там у вас хорошо. А когда продукт уже куплен, как у меня, и его надо расширять, а документации по системе нет, поддержки нет, схемы данных нет - добиться мистической оптимизации невозможно. [Уныло грустит]. Самого заставили работать!!! [Грустит ещё сильнее]. Само собой, схема данных в нужном объёме была восстановлена, нужные запросы - написаны. Но осадочек-то остался!!! :)
#74 | 17:54 08.09.2014 | Кому: dse
> Там у вас хорошо.

Да лан - как всюду. Переделать велосипед в автобус на ходу - обычная задача)
#75 | 18:07 08.09.2014 | Кому: pavelat
Это уже специфика работы с большими объемами данных, и тут все зависит от конкретных задач.
#76 | 18:08 08.09.2014 | Кому: Всем
> 3. Не используй в наименованиях таблиц и полей ключевые слова любого из диалектов SQL - можно налететь на такие грабли, что мама не горюй.

Я вот все поля в кавычках пишу, всяких `date`, `name` навалом :) Видимо у меня другой срез аккуратности.
#77 | 00:10 09.09.2014 | Кому: dse
> И что говорит план запроса? Может, каких-то нужных индексов нет, и где-то выполняется full scan?

Индексы есть конечно. Вроде все, какие нужны. Поэтому всего лишь грустно :)
#78 | 00:10 09.09.2014 | Кому: Котовод
> А какой смысл в таких массовых выборках?

Ежедневный отчёт.
#79 | 00:14 09.09.2014 | Кому: Котовод
> Собственно у нас обычно программистов заставляют немного на собственной программе поработать на целевой машине, на оптимизацию влияет просто мистическим образом)

Это да. Полезная штука.
#80 | 00:16 09.09.2014 | Кому: Mellcorn
> Это уже специфика работы с большими объемами данных, и тут все зависит от конкретных задач.

Так точно, кэп!!!
#81 | 05:38 09.09.2014 | Кому: pavelat
> Индексы есть конечно. Вроде все, какие нужны. Поэтому всего лишь грустно :)

Ну, если оптимизатор больше не предлагает построить индексы, есть ещё один вариант: выполнение запроса в несколько этапов с сохранением промежуточных результатов во временных таблицах и/или использование аналитических функций.
#82 | 07:31 09.09.2014 | Кому: dse
> Ну, если оптимизатор больше не предлагает построить индексы, есть ещё один вариант: выполнение запроса в несколько этапов с сохранением промежуточных результатов во временных таблицах и/или использование аналитических функций.

К сожалению, оптимизатор не всегда может точно предугадать наиболее оптимальный индекс. Особенно, когда база на этапе проектирования, и там ещё не особо много данных, а какие там данные будут можно только предполагать. Самые правильные индексы можно строить только вручную, основываясь на знании того, какие реально данные есть в таблице и на основании этого выбирать правильный порядок полей в индексе и множество включаемых полей. Правда, в итоге получается обычно covering индекс :).

Кстати, на небольших выборках я вообще предпочитаю использовать Common table expressions (в MS SQL есть, в Firebird вроде тоже было, когда я с ним работал), эти запросы работают гораздо быстрее, чем сохранение промежуточных результатов во временные таблицы или табличные переменные. Во всяком случае, запросы типа: а верни мне первое ID записи с максимальной суммой работают только в путь :).
#83 | 10:30 09.09.2014 | Кому: dse
> Ну, если оптимизатор больше не предлагает построить индексы, есть ещё один вариант: выполнение запроса в несколько этапов с сохранением промежуточных результатов во временных таблицах и/или использование аналитических функций.

Грустно - это 3-5-10 секунд. Для основного списка пришлось продублировать часть информации прямо в документе.
#84 | 15:04 09.09.2014 | Кому: pavelat
> Грустно - это 3-5-10 секунд.

Ну, всё способы оптимизации запросов, которые я знал, я уже изложил :) . Добавить мне, особо, нечего, извини. Могу, разве что, предложить выполнять запрос асинхронно, сохранять его результат в постоянном хранилище, а клиентам отдавать данные уже из этого хранилища.

Способы организации этого хранилища варьируются в зависимости от СУБД. В самом общем случае это отдельная таблица + триггер для её обновления. В ORACLE и PostgreSQL, вроде, есть MATERIALIZED VIEW. Тонкостей не знаю, сам не пользовался. Про остальные СУБД подсказать ничего не могу, не знаю.

Ну и, это, мы явно съехали с обсуждаемой темы :)
#85 | 15:10 09.09.2014 | Кому: pavelat
> Грустно - это 3-5-10 секунд. Для основного списка пришлось продублировать часть информации прямо в документе.

наш клиент решил подобную проблему переносом базы на ссд рейд :)
#86 | 10:08 10.09.2014 | Кому: Utgart
> наш клиент решил подобную проблему переносом базы на ссд рейд :)

Это неспортивно !!!
#87 | 10:33 10.09.2014 | Кому: dse
> Это неспортивно !!!

ну, на таблице с 120+ млн записей другого выбора не было. Кстати, ради пёрфоманса, пршилось всё пихать в одну таблицу мега денормализованную, ибо джойны на таких количествах тоже офигевали.
#88 | 13:25 10.09.2014 | Кому: Utgart
> пршилось всё пихать в одну таблицу мега денормализованную,

[Хитро прищуривается]

Да тыж, небось, нас обмануть хочешь!!! У этиого клиента, надо полагать, какая-нибудь специфическая информационная система, которая обновляется раз в неделю, а всё остальное время 24/7 отвечает клиентам на один и тот же запрос с точностью до параметров!

Ну и я уже писал в #84 про этот трюк с предварительной подготовкой результата выполнения сложного запроса с сохранением его в таблицу и выдачей клиентам ответов уже из неё.
#89 | 13:37 10.09.2014 | Кому: dse
> Да тыж, небось, нас обмануть хочешь!!! У этиого клиента, надо полагать, какая-нибудь специфическая информационная система, которая обновляется раз в неделю, а всё остальное время 24/7 отвечает клиентам на один и тот же запрос с точностью до параметров!

система специализированная, да, только наполняется 24/7 и отвечает клиентам 24/7, причём запросы на чтение от клиентов могут идти произвольные, все что только можно кэшируется на стороне вебсайта, но всё равно нагрузка на базу ого-го. Мейнтенс окно 1 час, все индексы приходится ребилдить в онлайне, чтобы обновление 24/7 было (МС СКЛ фича), а ещё эту таблицу надо успеть почистить от устаревших записей(привет, фрагментация индексов) и сгенерировать данные для таблиц промежуточных, ну тех, о которых ты говоришь, некоторые данные таки можно приготовить. А некоторые - нет, нужно выдавать свежие :).

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