Статьи

Питон и звездная схема

Звездная схема представляет данные в виде таблицы фактов (измеримых значений), которые связаны с различными измерениями факта. Общие измерения включают время, географию, организацию, продукт и тому подобное. Я работаю с некоторыми людьми, чьи факты представляют собой совокупность результатов медицинских тестов, а размеры включают пациента, дату и учреждение, в котором проводились тесты.

Я получил электронное письмо со следующей ситуацией: « Клиент, который ежедневно обрабатывает концерты входящих фактов и использует для обработки входящих фактов множество C / C ++, Perl, мэйнфреймов и других инструментов, и я серьезно подумал о том, чтобы Питон в своей организации .

Вот мои мысли об использовании Python для хранилищ данных, когда вы ежедневно получаете Gb данных.

Малые размеры

Подход на чистом Python работает только тогда, когда ваше измерение удобно помещается в памяти — не очень большая проблема с большинством измерений.

В частности, он не подходит для тех измерений, которые настолько огромны, что размерная модель становится снежинкой, а не простой звездой. При работе с большим количеством людей (коммунальные службы, банки, медицинское управление и т. Д.) Измерение «клиент» (или «пациент») становится слишком большим, чтобы уместиться в память. Необходимо использовать специальные методы бридж-таблиц. Я не думаю, что Python был бы идеален для этого, так как это включает в себя перебор большого количества данных по одной записи за раз.

Тем не менее, Python значительно быстрее, чем PL / SQL. Я не знаю, как это соотносится с Perl. Любой язык программирования будет быстрее, чем любая процедура SQL, потому что нет никаких затрат на СУБД.

Для всех небольших размеров . Загрузите значения измерений из РСУБД в файл с одним запросом. Читать все записи исходных данных (в идеале из плоского файла); согласовать размерность, отслеживать изменения; записать запись результата с информацией FK измерения в плоский файл.

Перебирайте словарь измерений и сохраняйте изменения измерений. Детали меняются в зависимости от используемых вами правил медленно изменяющегося измерения ( SCD ).

Алгоритм соответствия по сути следующий:

row= Dimension(...)
ident= ( row.field, row.field, row.field, ... )
dimension.setdefault( ident, row )

В некоторых случаях (например, Django ORM) это называется запросом get-or-create.

Размерный автобус

Для БОЛЬШИХ измерений, я думаю, вам все еще нужно реализовать «шину измерений», описанную в The Warehouse Toolkit. Чтобы сделать это в Python, вам, вероятно, следует создать что-то похожее на следующее.

Для любых больших размеров . Используйте внешнюю утилиту сортировки-слияния. Шутки в сторону. Они очень быстры для наборов данных, слишком больших для размещения в памяти. Используйте файлы формата CSV и полученная программа очень аккуратная. План выглядит следующим образом:

Сначала отсортируйте файл исходных данных по порядку, указав идентифицирующие поля большого измерения (номер клиента, номер пациента и т. Д.).

Во-вторых, запросите большое измерение в файле данных и отсортируйте его в том же порядке, что и исходный файл. (Использование SQL ORDER BY может быть медленнее, чем внешняя сортировка; только измерения могут определить, что быстрее.)

В-третьих, сделайте «сопоставление слиянием», чтобы найти различия между измерением и источником. Не используйте утилиту типа diff, она слишком медленная. Это простое совпадение ключей между двумя файлами. Цикл match-merge выглядит примерно так.

src= sourceFile.next()
dim= dimensionFile.next()
try:
while True:
src_key = ( src['field'], src['field'], ... )
dim_key= ( dim['field'], dim['field'], ... )
if src_key < dim_key:
# missing some dimension values
update_dimension( src )
src= sourceFile.next()
elif dim_key < src_key:
# extra dimension values
dim= dimensionFile.next()
else: # src and dim keys match
# check non-key attributes for dimension change.
src= sourceFile.next()
except StopIteration, e:
# if source is at end-of-file, that's good, we're done.
# if dim is at end of file, all remaining src rows are dimension updates.
for src in sourceFile:
update_dimension( src )

В конце этого этапа вы накапливаете файл добавлений и изменений измерения клиента, который затем сохраняется в фактическом измерении клиента в базе данных. Этот проход также будет писать новые исходные записи с клиентом FK. Вы также можете обрабатывать демографические или промежуточные таблицы в это время.

Загрузка фактов

Первый шаг в загрузке DW — соответствие размеров. С некоторой сообразительностью вышеуказанная обработка может выполняться параллельно, потребляя много ресурсов процессора. Чтобы сделать это параллельно, каждый алгоритм соответствия является частью большого конвейера уровня ОС. Исходный файл должен быть переформатирован, чтобы оставить пустые столбцы для ссылки FK каждого измерения. Каждый процесс соответствия считывает исходный файл и записывает один и тот же файл формата с одним заполненным FK измерения. Если все эти алгоритмы соответствия образуют простой канал ОС, они все работают параллельно. Это выглядит примерно так.

src2cvs source | conform1 | conform2 | conform3 | load

В конце вы используете массовый загрузчик СУБД (или пишете свой собственный в Python, это просто), чтобы выбрать фактические значения фактов и измерения FK из исходных записей, которые полностью заполнены всеми измерениями FK, и загрузить их в факт стол.

Я написал обработку соответствия в Java (которая быстрее, чем Python), и мне пришлось отказаться от соответствия на основе SQL для больших измерений. Вместо этого мы применили приведенный выше алгоритм плоского файла для объединения больших измерений. Убийца — не скорость языка, а издержки СУБД. Как только вы вышли из базы данных, все вспыхнуло. Действительно, такие продукты, как сортировка данных syncsort, могут выполнять части соответствия измерения с удивительной скоростью для больших наборов данных.

Ручная отжим

«Но, — говорят отжиматели, — разве вы не побеждаете ценность СУБД, работая вне ее?» Ответ — нет. Мы не делаем здесь инкрементную транзакционную обработку. На складе нет нескольких транзакций обновления. Есть запросы и есть массовые грузы. Подготовка к массовой загрузке вне базы данных просто более эффективна. Нам не нужны блокировки, сегменты отката, управление памятью, многопоточность, параллелизм, правила ACID или что-то еще. Нам просто нужно сопоставить большое измерение и поступающие факты.