Сохраните результаты запросов Hive в таблицы ORC

Биг датаBeginner
Практиковаться сейчас

Введение

Запрос, показанный в терминале, полезен один раз. Отчёту, который будут повторно использовать другие запросы, нужен сохранённый результат. Вы превратите запрос ежедневных оплаченных продаж компании в небольшую таблицу Hive и безопасно перестроите её при повторном запросе того же отчёта.

Источник — читаемый текст CSV. ORC, Optimized Row Columnar, — двоичный столбцовый формат хранения: он организует значения по столбцам внутри структуры файла и может поддерживать эффективное аналитическое чтение. Это не другой язык SQL и не замена схемы таблицы. Маленький пример демонстрирует правильное хранение и повторное использование, а не доказывает прирост скорости.

Для работы независимо подготовлены шесть чистых заказов во внешней текстовой таблице. Hive готов. Вам следует понимать внешние таблицы, SELECT, агрегацию оплаченных продаж и группировку по датам. Операторы записи результатов вы изучите здесь на явно нетранзакционных таблицах, поддерживаемых подготовленной средой. Программирование, установка и файлы предыдущих работ не требуются. Используйте терминал.

Определите типизированную таблицу отчёта ORC

На этом шаге вы создадите пустое назначение со схемой, соответствующей нужному отчёту. Как и источник CSV, назначение — явно внешняя таблица с известным расположением HDFS. Её формат — ORC вместо текста. Внешняя таблица описывает связь метаданных с файлами; это не означает, что она доступна только для чтения. Hive может записать в неё результат SELECT. Расположение результата отделено от источника, поэтому перестроение отчёта не заменит исходные заказы.

Начните в рабочем каталоге:

cd /home/labex/project

В каждой выходной строке одна дата, одно количество и один денежный итог. COUNT(*) даёт количество типа BIGINT. DECIMAL(14,2) предусматривает четырнадцать десятичных цифр всего, две после точки; для этого небольшого отчёта достаточно. Явная схема помогает избежать случайного хранения сумм как текста.

Сохраните и выполните определение. Here-документ буквально записывает SQL между маркерами; -f Beeline запускает файл на подготовленной службе:

cat > /home/labex/project/queries/create-orc-report.sql <<'SQL'
CREATE EXTERNAL TABLE IF NOT EXISTS retail_orc.daily_sales (
  order_date DATE,
  paid_orders BIGINT,
  revenue DECIMAL(14,2)
)
STORED AS ORC
LOCATION 'hdfs://localhost:9000/warehouse/external/retail_orc.db/daily_sales'
TBLPROPERTIES ('transactional'='false', 'external.table.purge'='false');
SQL
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -f /home/labex/project/queries/create-orc-report.sql

STORED AS ORC выбирает формат. LOCATION задаёт новый каталог результата внутри подготовленного доступного для записи складского каталога базы данных. external.table.purge=false сохраняет файлы при удалении внешнего определения; это не мешает явной перезаписи заменить строки отчёта. transactional=false запрашивает нетранзакционную таблицу. Hive может не показывать это свойство false в метаданных; лишь значение true отметило бы таблицу транзакционной. Работа не обучает обновлениям и удалениям ACID. Изучите метаданные и нулевое число строк:

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "DESCRIBE FORMATTED retail_orc.daily_sales;" > /home/labex/project/output/orc-definition.txt
cat /home/labex/project/output/orc-definition.txt
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT COUNT(*) FROM retail_orc.daily_sales;" > /home/labex/project/output/empty-report.tsv
cat /home/labex/project/output/empty-report.tsv

Найдите три типа столбцов, тип внешней таблицы и имена входного и выходного форматов ORC. Ожидается 0 строк: определение назначения ещё не выполнило расчёт продаж и не скопировало данные CSV. Далее вы заполните его явно.

Запишите и прочитайте ежедневный отчёт

На этом шаге вы выполните SELECT оплаченных продаж и сохраните его вывод. INSERT OVERWRITE TABLE заменяет текущее содержимое таблицы назначения результатом SELECT. Команда не перезаписывает читаемую внешнюю таблицу заказов. Выбранные значения назначаются столбцам назначения по порядку: дата, количество, выручка.

Сохраните полный скрипт перестроения. CREATE TABLE IF NOT EXISTS допускает повторное определение, когда правильно определённая таблица уже существует; неверную схему он не исправляет. Следующий INSERT выполняет само построение отчёта:

cat > /home/labex/project/queries/build-sales-report.sql <<'SQL'
CREATE EXTERNAL TABLE IF NOT EXISTS retail_orc.daily_sales (
  order_date DATE,
  paid_orders BIGINT,
  revenue DECIMAL(14,2)
)
STORED AS ORC
LOCATION 'hdfs://localhost:9000/warehouse/external/retail_orc.db/daily_sales'
TBLPROPERTIES ('transactional'='false', 'external.table.purge'='false');
INSERT OVERWRITE TABLE retail_orc.daily_sales
SELECT order_date, COUNT(*) AS paid_orders,
       SUM(quantity * unit_price) AS revenue
FROM retail_orc.orders
WHERE order_status = 'paid'
GROUP BY order_date;
SQL
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -f /home/labex/project/queries/build-sales-report.sql

Успешное завершение означает, что запись закончена. Подтвердите это запросом к сохранённой таблице ORC, а не простым повтором исходного SELECT:

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT order_date, paid_orders, revenue FROM retail_orc.daily_sales ORDER BY order_date;" > /home/labex/project/output/stored-report.tsv
cat /home/labex/project/output/stored-report.tsv

Ожидаются 14 октября / 2 / 45.00 и 15 октября / 2 / 80.00. Денежное отображение может включать конечные нули. Это две сохранённые строки результата, обобщающие четыре оплаченных исходных заказа; это не шесть копий первоначальных записей CSV.

Файлы ORC двоичные, поэтому просмотр байтов через cat не дал бы читаемый CSV. При SELECT Hive интерпретирует схему таблицы и формат файла. Исходные файлы остаются обычным текстом и сохраняют все шесть заказов, включая два исключённых статуса.

Перестройте отчёт без накопления повторяющихся дней

На этом шаге вы проверите повторяемость. Предположите число строк при повторном выполнении того же скрипта перезаписи. Назначение должно по-прежнему содержать две даты, а не четыре скопированные итоговые строки:

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -f /home/labex/project/queries/build-sales-report.sql
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT order_date, paid_orders, revenue FROM retail_orc.daily_sales ORDER BY order_date;" > /home/labex/project/output/rebuilt-report.tsv
cat /home/labex/project/output/rebuilt-report.tsv

Отчёт должен оставаться таким: 14 октября / 2 / 45.00 и 15 октября / 2 / 80.00. Выполните краткую сверку прямо из таблицы результата:

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT COUNT(*), SUM(paid_orders), SUM(revenue) FROM retail_orc.daily_sales;" > /home/labex/project/output/report-reconciliation.tsv
cat /home/labex/project/output/report-reconciliation.tsv

Ожидаются 2 сохранённые строки отчёта, 4 оплаченных исходных заказа и выручка 125.00. Число строк результата и сумма его paid_orders описывают разные уровни детализации.

Сравните сохранённые данные до и после локально. Поскольку оба SELECT используют ORDER BY, порядок строк данных стабилен. Beeline может включать сообщения клиента, поэтому осмысленное сравнение — строки результатов с датами и числовая сверка, а не временные метки сообщений.

Такое перестроение идемпотентно при неизменных входных данных: повторение оставляет то же содержимое отчёта. Далее временное назначение покажет важность режима записи.

Сравните добавление и перезапись на временной копии

На этом шаге вы намеренно продублируете небольшой производный отчёт в отдельной таблице. Основная daily_sales останется правильным отчётом. Создайте временную таблицу с той же явной схемой:

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "CREATE EXTERNAL TABLE IF NOT EXISTS retail_orc.append_demo (
  order_date DATE,
  paid_orders BIGINT,
  revenue DECIMAL(14,2)
)
STORED AS ORC
LOCATION 'hdfs://localhost:9000/warehouse/external/retail_orc.db/append_demo'
TBLPROPERTIES ('transactional'='false', 'external.table.purge'='false');"

INSERT INTO TABLE добавляет результаты SELECT к существующему содержимому. Добавьте основной отчёт из двух строк дважды:

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "INSERT INTO TABLE retail_orc.append_demo SELECT order_date, paid_orders, revenue FROM retail_orc.daily_sales;"
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "INSERT INTO TABLE retail_orc.append_demo SELECT order_date, paid_orders, revenue FROM retail_orc.daily_sales;"
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT COUNT(*), SUM(paid_orders), SUM(revenue) FROM retail_orc.append_demo;" > /home/labex/project/output/append-observation.tsv
cat /home/labex/project/output/append-observation.tsv

Ожидаются 4 строки, 8 суммарных оплаченных заказов и выручка 250.00. Дополнительные строки представляют дубликаты отчёта, а не новые продажи. Новых заказов не поступало; добавление полного перестроенного отчёта дало неверный бизнес-результат.

Замените временное содержимое одной копией, используя изученный режим записи:

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "INSERT OVERWRITE TABLE retail_orc.append_demo SELECT order_date, paid_orders, revenue FROM retail_orc.daily_sales;"
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT order_date, paid_orders, revenue FROM retail_orc.append_demo ORDER BY order_date;" > /home/labex/project/output/overwrite-observation.tsv
cat /home/labex/project/output/overwrite-observation.tsv

Снова возвращаются две правильные ежедневные строки. Для небольшой практической проверки повторите эту перезапись ещё раз:

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "INSERT OVERWRITE TABLE retail_orc.append_demo SELECT order_date, paid_orders, revenue FROM retail_orc.daily_sales;"
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT COUNT(*), SUM(revenue) FROM retail_orc.append_demo;"

Снова ожидаются 2 строки и 125.00. Добавление полезно, когда поступают действительно новые непересекающиеся данные; перестроение полного снимка требует замены. Сохранённый основной скрипт использует перезапись, поэтому может перестроить полный отчёт без незаметного накопления повторяющихся дат.

Итоги

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