Лучшее из двух миров
Если реализовать многомерную модель с использованием представлений (и индексов и сводных таблиц) поверх модели 3NF, то вы сможете получить быстроту выполнения и удобство "подготовленных" запросов и много средств, изолирующих пользователей от базовых таблиц и нудной работы (и ошибок) на SQL. Кроме того, вы сможете получить гибкость в расширении модели почти в любом направлении для включения преобретенных или других новых данных. При использовании модели 3NF физическая модель является логической моделью; преобразования очень просты и прямолинейны. Вы можете создать представления, позволяющие инструментальным средствам демонстрировать пользователю многомерную модель, облегчая понимаемость и упрощая использование. Наконец, вы можете обеспечить прямой доступ к нормализованной модели с помощью таких реляционных средств как BI/Query компании Hummingbird Communication Ltd. (www.hummingbird.com), или умудренные пользователи и профессионалы IT могут написать собственный SQL-код.
Имеются все основания использовать преимущества других подходов к моделированию, если они представляют какую-то ценность. Например, псевдоключи (идея, заимствованная из многомерного моделирования) при корректном использовании упрощают пользовательский доступ, повышают эффективность выполнения запросов и снижают уровень требований к общей нагрузке системы.
В Teradata используется этот гибрид физической модели 3NF и многомерных представлений, поскольку система очень хорошо обрабатывает соединения и обладает зрелым и надежным оптимизатором. Представления в Teradata не материализуются до выполнения соответствующих запросов, что делает возможным отражать в плане запроса с соединением потребности каждого индивидуального запроса, минимизировать объем данных, которые требуется перераспределять или дублицировать. Хэширование на первичном индексе упрощает разделение, и распределение памяти происходит только на уровне базы данных, а не на основе принципа таблица-раздел и индекс-раздел. В оптимизаторе Teradata используется пересечение индексов, что обеспечивает эффективность почти такого же уровня, который дают битовые индексы, без потребности в накладных расходах для их поддержки.
Это означает, что Teradata нуждается в создании меньшего числа индексов, что приводит к дальнейшему сокращению требуемых объемов памяти и времени для поддержки индексов. Наличие возможности синхронного сканирования (sync scan) позволяет использовать время, требуемое для сканирования больших таблиц, для выполнения нескольких (и даже сотен и тысяч) параллельно выполняемых запросов, делающих одну и ту же работу, что повышает пропускную способность системы на несколько порядков. Это всего лишь несколько причин (к ним следует добавить параллелизм системы), благодаря которым Teradata минимизирует зависимость от сводных таблиц.
Однако реальное преимущество Teradata происходит от фактического устранения избыточных многомерных моделей и вероятного уменьшения чрезмерных требований к аппаратуре, поддерживающей многочисленные лавки данных (data marts). Вследствие простого размещения данных на основе хэширования Teradata делает возможной реализацию практически всех комбинаций подходов 3NF и звезднообразных схем. Если для поддержки бизнеса требуются расширение возможностей и ренормализация, можно переключиться со звезднообразной схемы на 3NF.
Оптимизация соединений малой и большой таблиц. Когда в 1988 г. Teradata впервые начала обслуживать сверхбольшие базы данных, обнаружились некоторые странные проблемы. Даже при использовании подхода с отказом от общих ресурсов (shared-nothing) для обработки и сканирования больших таблиц требуется большое время. В результате инженеры (включая меня) разработали методы, заставляющие оптимизатор сначала обрабатывать малые таблицы измерений, соединяя из с целью создания первичного индекса для большой таблицы фактов и сокращая тем самым время ответа для многих запросов. Эти методы были включены в оптимизатор Teradata выпуска 1990 г. Как показывает рис. 1, у большой таблицы (Sales) имеется составной первичный индекс, составленный из внешних ключей таблиц измерений Stores, Items и Weeks. В звезднообразной схеме все четыре таблицы логически (а иногда и физически) объединяются.
На рисунке представлена физическая модель 3NF, и запрос, представленный на листинге 1, позволяет произвести выборку из Stores, Items и Weeks с пересечением с указанными данными из Sales. В частности, здесь мы хотим узнать общий объем продаж всех телевизоров в некоторой группе штатов (скажем Colorado и Minnesota) в течение двух недель перед Super Bowl, и мы хотим видеть это в соответствии с размером экрана телевизора и в лексикографическом порядке названий магазинов. Указанное представление эмулирует звезнообразную схему, в запросе не принимается во внимание базовая физическая модель, и запрос очень прост. (Особенности модели скрываются представлением.)
SELECT store, SUM(sales$), SUM(salesQty), Substr(itemdesc, 1, 3) Named screensize, itemdesc FROM SalesStar WHERE weeknbr BETWEEN 9805 AND 9806 AND state IN ('CO', 'MN') AND subdept = 'Television' ORDER BY Sales$ Desc, store GROUP BY screensize;
View: CREATE VIEW SalesStar AS SELECT (*) FROM SALES B, STORES S, ITEMS I, WEEKS W WHERE B.STORE_NBR = S.STORE_NBR AND B.ITEM_NBR = I..ITEM_NBR AND B.WEEK = W.WEEK;
Листинг 1. Запрос к таблице Sales
Рис. 1. Таблица Sales со звезднообразной схемой и составным первичным индексом
Оптимизатор Teradata знает, что таблица Weeks содержит меньше всего строк, поэтому он выбирает только те недели, которые нас интересуют. Затем он копирует эти две строки в каждое виртуальное AMP (параллельное устройство Teradate), помещая их в кэш. Поскольку оптимизатор знает, что таблица Stores не содержит много строк, и имеется индекс на столбце state, он выбирает около 30 строк для указанных штатов, соединяет их с двумя строками уже в основной памяти и копирует результат в каждое AMP. Оптимизатор не знает, что нам требуется только немногая часть товаров из таблицы Item, содержащей два миллиона строк, пока не пройдет по индексу на столбце subdepartment и не выберет телевизоры.
Теперь оптимизатор получает, скажем, 2433032 строк. Он перераспределяет эти строки с помощью хэширования (таким же образом, что и таблицу Sales) в соответствующие AMP, по ходу дела сортируя строки.
Наконец, оптимизатор сопоставляет хэш-коды полученной промежуточной таблицы и таблицы Sales -- выполняя соединение слиянием -- и возвращает результат в отсортированном порядке, производя их агрегацию по store. На листинге 2 приведено перефразированное объяснение плана соединения.
- Каждое AMP производит выборку из таблицы Weeks по условию <Week selection criteria>. Промежуточный результат (Spool) дублируется на всех AMP.
- Все AMP производят выборку из таблицы Stores по условию <Store selection criteria>. Выполняется соединение со Spool по фиктивному условию (). Spool дублируется на всех AMP.
- Все AMP производят выборку из таблицы Items по условию <Item selection condition>. Выполняется соединение со Spool по фиктивному условию. Результат перераспределяется между всеми AMP и сортируется.
- На всех AMP выполняется соединение Sales и Spool с использованием MERGE JOIN (сканирование строк с сопоставлением хэш-кодов).
Пользовательские представления. Когда разработчики Teradata работали над методами, влияющими на планы соединений, они формализовали и реализовали их с использованием представлений. Хотя теперь оптимизатор стал умнее, чем восемь лет назад, представления остаются полезными в обеспечении инструментальных средств и людей возможностью не заботиться обо всех базовых таблицах.
Нежелательно заставлять людей, которые думают в терминах фиксированных измерений, реконструировать эти измерения для каждого нового запроса. Пользовательские представления упрощают жизнь пользователей, поддерживая в то же время согласованность применяемых бизнес-правил.
Новый индекс соединения. Индекс соединения, появившийся в Teradata V2R2.1, может комбинировать таблицы детальных данных (фактов) и связанные таблицы в одной индексной структуре, избавляя от потребности соединять таблицы во время выполнения. Можно рассматривать индекс соединения как комбинацию таблицы фактов и некоторого числа таблиц измерений, если внести в этот индекс достаточно выразительные данные. Teradata автоматически распространяет изменения в базовых таблицах в индекс соединения, так что дополнительные расходы на поддержку минимальны.
Оптимизатор автоматически опознает наличие индекса соединения и использует его, включая подмножества и надмножества.
Сводные таблицы. Использование нормализованной модели не может удовлетворить все потребности. Для некоторых приложений имеет смысл создавать отдельные сводные структуры внутри среды склада данных. Для облегчения поддержки среды начните с обобщения таблиц на физической машине, где размещается склад данных. Иногда это обобщение все равно не сможет обеспечить требуемую производительности (например, для систем обработки телефонных звонков). В таких экстремальных случаях может быть оправдано размещение приложения на физически отдельной платформе.
Teradata допускает и поощряет использование сводных таблиц, когда это имеет смысл если они обеспечивают существенное улучшение реактивности для большого числа запросов с малыми накладными расходами на сопровождение. Но при использовании Teradata сводные таблицы не требуются слишком часто по причине наличия развитых возможностей оптимизатора и параллельной обработки. Поэтому не планируйте использование сводных таблиц, пока вы не знаете, какие запросы будут задавать пользователи и как часто они будут это делать. Проанализируйте доходы и расходы прежде, чем потратить множество усилий для построения и поддержки сводных таблиц.