{
"firstName": "Иван",
"lastName": "Иванов",
"address": {
"streetAddress": "Московское ш., 101, кв.101",
"city": "Ленинград",
"postalCode": 101101
},
"phoneNumbers": [5-
"812 123-1234",
"916 123-4567"
]
}
XML-формат менее распространен, чем JSON, в нем любят хранить конфигурации параметров каких-либо систем. Этот формат конкурент JSON. Для данных я бы все-таки предпочел JSON, он легче и проще. В XML-формате, например, интернет магазины передают информацию о товарах: структуру их каталога, цены, названия, атрибуты товаров.
<person>
<firstName>Иван</firstName>
<lastName>Иванов</lastName>
<address>
<streetAddress>Московское ш., 101, кв.101</streetAddress>
<city>Ленинград</city>
<postalCode>101101</postalCode>
</address>
<phoneNumbers>
<phoneNumber>812 123-1234</phoneNumber>
<phoneNumber>916 123-4567</phoneNumber>
</phoneNumbers>
</person>
Есть гораздо более экзотические форматы, с которыми вы можете столкнуться на практике:
pkl бинарные объекты Python, прочитав которые с помощью этого языка программирования вы получите в памяти сразу нужную структуру данных, не заморачиваясь с парсингом.
hdf иерархический формат структуры данных. В этот формат можно поместить разнородные данные, например товарный каталог магазина, продажи и т. д. В файле содержится метаинформация: названия, типы данных и т. д. Лично я с такими файлами никогда не работал, но они могут быть удобны, когда нужно передать данные сложного проекта другой команде или опубликовать в интернете.
parquet, avro это уже форматы, заточенные для больших данных. Как правило, они содержат схему данных (метаинформацию) о типе и названии полей и оптимизированы для использования в таких системах, как Hadoop. Оба формата примеры бинарного хранения данных, хотя avro может опираться на JSON.
Что еще полезно знать о файлах хранения? Как они хранят метаинформацию. Если кто-то захочет передать файл с данными, то, скорее всего, в CSV-файле в первой строке будут названия полей, но информацию о типе (это число, текст, дата и т. д.) вы не получите, нужно будет дополнительно передать описание полей с файлом, иначе вам придется самим строить предположения. Если же вам передадут JSON или XML, то там уже лучше с типами данных, в этом плане они удобнее.
Базы данных обсудим в главе про хранилища.
Способы получения данных
Есть три основных способа получить данные:
прочитать файлы (обсуждали выше);
сделать запрос к API;
сделать запрос к базе данных.
Прочитать файл это самый простой способ: если это CSV-файл, его можно открыть в Microsoft Excel, Google Spreadsheet, OpenOffice и т. д. Все пакеты анализа данных, библиотеки любых языков программирования поддерживают данный формат. Он очень прост и удобен. С JSON и XML придется повозиться и, скорее всего, даже написать небольшой код (маленькая программа) по извлечению нужных вам данных.
Второй способ сделать запрос к сетевому API (Application Programming Interface). Вы пишете запрос в требуемом API формате, на выходе вам приходит, как правило, JSON, который вы можете обработать, сохранить в файл и т. д. Это требует кодирования, зато работать с такими интерфейсами бывает очень интересно.
Третий способ базы данных через использование языка программирования SQL. Для разных систем баз данных существуют свои диалекты этого языка. Обычно это связано с оптимизациями и расширением стандартного языка. Чтобы получить данные из БД, необходимо к ней подключиться через драйвер API по сети, написать запрос SQL, и если все хорошо получить данные на выходе. В какой бы компании я ни работал везде писал на SQL. Настоятельно рекомендую ознакомиться с этим языком программирования или хотя бы с его азами.
Глава 6
Хранилища данных
Зачем нужны хранилища данных
Хранилище данных содержит копию всех данных, необходимых для функционирования аналитической системы. Несколько лет назад появился модный термин Data Lakes (озеро данных) это метод хранения данных системой или репозиторием в натуральном виде, то есть в формате, который предполагает одновременное хранение данных в различных схемах и форматах. Данные хранятся в том виде, в котором созданы: видеофайлы, изображения, документы, дампы таблиц из баз данных, CSV-файлы. Мое определение хранилища, которое я дал выше, очень сильно пересекается с озером данных. Также на кластере мы держали скачанные картинки, сырые и обработанные данные. Читателям я предлагаю меньше фокусироваться на терминах и не заморачиваться с ними, никто не даст вам четких инструкций, как хранить ваши данные. Это будет ваше решение, оно будет зависеть от ваших задач, которые предстоит решать именно вам.
Сейчас у хранилища данных гораздо больше функций, чем просто хранение данных для отчетов, например, оно может выступать источником данных для обучения ML-моделей. Данные можно хранить не только в базе данных, но и в виде файлов, как делает Hadoop.
С моей точки зрения, хранилища данных:
1) являются цифровым архивом компании;
2) являются копией данных в источнике;
3) не изменяемы;
4) хранятся в виде, максимально приближенном к данным в источнике;
5) позволяют объединят данные из разных источников.
Относитесь к хранилищу как к архиву компании [34], ведь там хранятся данные с момента ее создания. Часть данных вы уже нигде не найдете, так как источники периодически чистятся. В Retail Rocket, например, мы периодически архивируем все данные: товарные базы интернет-магазинов (они изменяются со временем), их структуры каталога, сами рекомендации. Ни в каких источниках их уже нет, но они есть в нашем хранилище и помогают решать важные задачи: искать причины проблем и моделировать новые алгоритмы рекомендаций.
Напрямую с источником данных не стоит работать по двум основным причинам. Во-первых, запросы к данным на чтение оказывают очень большую нагрузку на диски и увеличивают время ответа рабочих машин, и клиенты получают ответы ваших систем с задержкой. Во-вторых, может быть нарушена конфиденциальность данных, хранящихся в источниках. Не все данные нужно забирать оттуда в исходном виде, чувствительную информацию клиентов лучше не трогать или шифровать при загрузке в хранилище. Само хранилище проводит незримую границу между вашей рабочей системой, которая должна работать надежно, и данными, которые будут использованы для анализа. В Ozon.ru у меня был один раз случай, когда мой сотрудник, обращаясь напрямую к источнику данных, повредил данные клиента разработчики тогда очень разозлились.
Неизменяемость уже загруженных данных в хранилище гарантирует, что ваши аналитические отчеты не будут меняться. Я буду лукавить, если скажу, что так не бывает. Бывает, но обычно из-за технических ошибок или расширения перечня хранимых данных. Такие инциденты нужно минимизировать по двум причинам. Во-первых, перезагрузка данных бывает очень длительной и блокирующей аналитическую систему. Например, у нас в Retail Rocket такая операция между Hadoop и Clickhouse могла занимать дни и даже недели. Во-вторых, доверие пользователей к вашей системе будет подорвано из-за изменения данных, а значит, отчетов и решений, которые были сделаны на их основе. Легко ли вам будет доверять данным, которые изменяются задним числом?
Я всегда стараюсь хранить данные в том виде, в котором они хранятся в источнике. Есть другой подход делать преобразование данных при их копировании в хранилище. С моей точки зрения, второй подход имеет существенный недостаток: никто не может гарантировать, что преобразование или фильтрация пройдут без ошибок. Как минимум, данные в источнике изменятся, и преобразование «устареет». В какой-то момент вы заметите, что данные расходятся. Вам придется лезть в источник, возможно, скачивать их (а их может быть очень много) и построчно сравнивать. Такие ошибки крайне сложно искать. Поэтому удобно, когда исходные данные хранятся в сыром виде. Безусловно, преобразования нужны, но хранить измененные данные лучше в отдельных таблицах или файлах (в отдельном слое хранилища). Тогда сверка с источником будет заключаться лишь в сравнении числа строк между таблицами, а ошибки преобразований легко отыщутся внутри самого хранилища, так как исходники у вас имеются. Этот вывод был сделан мной на основе инцидентов по исправлению данных во всех компаниях, на которые я работал. Да, данных в хранилище может стать чуть ли не в два раза больше, но, учитывая сегодняшнюю низкую стоимость хранения и принцип «много данных не бывает», это все окупится.
В главе 5 я уже писал про связность данных, что самые интересные инсайты находятся на стыке их разных источников. Данные объединяются через ключи. Сама операция называется соединением данных (join). Она очень ресурсоемкая, разработчики баз данных постоянно работают над ее ускорением. На одной из лекций в компании Microsoft я услышал, что для больших данных количество таких операций нужно минимизировать, а для этого нужно сразу соединить данные в хранилище и в таком виде хранить. Это было около десяти лет назад. Сейчас уже есть системы, которые это могут делать лучше традиционных баз данных, об этом позже в этой главе.