Данные о жалобах NYPD
Файлы с разделением на табуляцию или TSV являются распространенными и могут включать заголовки полей в первой строке файла. ClickHouse может загружать TSV и также может выполнять запросы к TSV без загрузки файлов. Этот гид охватывает оба этих случая. Если вам нужно выполнить запрос или загрузить файлы CSV, те же методы работают, просто замените TSV
на CSV
в ваших аргументах формата.
Во время работы с этим гидом вы:
- Исследуете: Выполняйте запрос к структуре и содержимому TSV файла.
- Определите целевую схему ClickHouse: Выберите правильные типы данных и сопоставьте существующие данные с этими типами.
- Создайте таблицу ClickHouse.
- Предобработайте и передайте данные в ClickHouse.
- Выполните несколько запросов к ClickHouse.
Набор данных, использованный в этом руководстве, предоставлен командой NYC Open Data и содержит данные о "всех действительных преступлениях фелонии, правонарушениях и нарушениях, о которых сообщил Департамент полиции Нью-Йорка (NYPD)". На момент написания размер файла данных составляет 166 МБ, но он регулярно обновляется.
Источник: data.cityofnewyork.us
Условия использования: https://www1.nyc.gov/home/terms-of-use.page
Пререквизиты
- Скачайте набор данных, посетив страницу Текущие данные о жалобах NYPD (на сегодня), нажав кнопку Экспорт и выбрав TSV для Excel.
- Установите сервер и клиент ClickHouse.
- Запустите сервер ClickHouse и подключитесь с помощью
clickhouse-client
.
Примечание о командах, описанных в этом руководстве
В этом руководстве есть два типа команд:
- Некоторые команды выполняют запросы к файлам TSV, они запускаются в командной строке.
- Остальные команды выполняют запросы к ClickHouse и запускаются в
clickhouse-client
или Play UI.
Примеры в этом руководстве предполагают, что вы сохранили файл TSV в ${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv
, пожалуйста, скорректируйте команды при необходимости.
Ознакомьтесь с файлом TSV
Перед тем как начать работу с базой данных ClickHouse, ознакомьтесь с данными.
Посмотрите на поля в исходном файле TSV
Это пример команды для выполнения запроса к файлу TSV, но не запускайте её пока.
Пример ответа
Чаще всего вышеуказанная команда даст вам знать, какие поля во входных данных являются числовыми, а какие строковыми, а какие являются кортежами. Это не всегда так. Поскольку ClickHouse часто используется с наборами данных, содержащими миллиарды записей, по умолчанию проверяется количество (100) строк для вывода схемы, чтобы избежать парсинга миллиардов строк для определения схемы. Ответ ниже может не совпадать с тем, что вы видите, поскольку набор данных обновляется несколько раз в год. Посмотрев на Справочник данных, вы можете увидеть, что CMPLNT_NUM указан как текст, а не как числовой. Переопределив значение по умолчанию для 100 строк для вывода с помощью настройки SETTINGS input_format_max_rows_to_read_for_schema_inference=2000
, вы можете лучше понять содержимое.
Примечание: начиная с версии 22.5 по умолчанию теперь 25 000 строк для вывода схемы, поэтому изменяйте настройку только если вы используете более старую версию или если вам нужно более 25 000 строк для выборки.
Запустите эту команду в командной строке. Вы будете использовать clickhouse-local
для выполнения запроса к данным в TSV файле, который вы скачали.
Результат:
На этом этапе вы должны проверить, что колонки в файле TSV совпадают с именами и типами, указанными в разделе Columns in this Dataset на веб-странице набора данных. Типы данных не очень специфичны, все числовые поля установлены на Nullable(Float64)
, а все остальные поля - на Nullable(String)
. Когда вы создаете таблицу ClickHouse для хранения данных, вы можете указать более подходящие и эффективные типы.
Определите правильную схему
Чтобы выяснить, какие типы следует использовать для полей, необходимо знать, как выглядят данные. Например, поле JURISDICTION_CODE
является числовым: должно ли это быть UInt8
, Enum
или Float64
подходит?
Результат:
Ответ запроса показывает, что JURISDICTION_CODE
хорошо вписывается в UInt8
.
Точно так же посмотрите некоторые поля String
и посмотрите, подходят ли они для представления DateTime
или LowCardinality(String)
полей.
Например, поле PARKS_NM
описывается как "Имя парка, игровой площадки или зеленого пространства NYC, если применимо (государственные парки не включены)". Имена парков в Нью-Йорке могут стать хорошим кандидатом для LowCardinality(String)
:
Результат:
Посмотрите на некоторые имена парков:
Результат:
Набор данных, используемый на момент написания, имеет только несколько сотен различных парков и игровых площадок в столбце PARK_NM
. Это небольшое число на основании рекомендации LowCardinality оставаться ниже 10 000 различных строк в поле LowCardinality(String)
.
Поля DateTime
Согласно разделу Columns in this Dataset на веб-странице набора данных, существуют поля даты и времени для начала и окончания сообщенного события. Просмотр min и max CMPLNT_FR_DT
и CMPLT_TO_DT
дает представление о том, заполняются ли эти поля всегда:
Результат:
Результат:
Результат:
Результат:
Построение плана
На основе вышеизложенного:
JURISDICTION_CODE
следует привести кUInt8
.PARKS_NM
следует привести кLowCardinality(String)
.CMPLNT_FR_DT
иCMPLNT_FR_TM
всегда заполняются (возможно, со значением по умолчанию00:00:00
).CMPLNT_TO_DT
иCMPLNT_TO_TM
могут быть пустыми.- Даты и времени хранятся в отдельных полях в источнике.
- Даты в формате
mm/dd/yyyy
. - Время в формате
hh:mm:ss
. - Даты и время могут быть объединены в типы DateTime.
- Есть некоторые даты до 1 января 1970 года, что значит, что нам нужен 64-битный DateTime.
Существует много других изменений, которые необходимо внести в типы, они все могут быть определены, следуя тем же шагам исследования. Рассмотрите количество различных строк в поле, min и max чисел и примите свои решения. Структура таблицы, приведенная позже в руководстве, имеет много строк с низкой кардинальностью и полей беззнакового целого числа и очень мало числовых значений с плавающей точкой.
Объедините поля даты и времени
Чтобы объединить поля даты и времени CMPLNT_FR_DT
и CMPLNT_FR_TM
в одну String
, которую можно привести к типу DateTime
, выберите два поля, соединенных оператором объединения: CMPLNT_FR_DT || ' ' || CMPLNT_FR_TM
. Поля CMPLNT_TO_DT
и CMPLNT_TO_TM
обрабатываются аналогичным образом.
Результат:
Преобразование строки даты и времени в тип DateTime64
Ранее в руководстве мы обнаружили, что в файле TSV есть даты до 1 января 1970 года, что означает, что нам нужен 64-битный тип DateTime для дат. Даты также нужно преобразовать из формата MM/DD/YYYY
в YYYY/MM/DD
. Всё это можно сделать с помощью функции parseDateTime64BestEffort()
.
Строки 2 и 3 выше содержат объединение из предыдущего шага, а строки 4 и 5 выше парсируют строки в DateTime64
. Поскольку время окончания жалобы не гарантировано, используется parseDateTime64BestEffortOrNull
.
Результат:
Даты, указанные как 1925
, выше являются результатом ошибок в данных. В оригинальных данных есть несколько записей с датами в годах 1019
- 1022
, которые должны быть 2019
- 2022
. Они сохраняются как 1 января 1925 года, так как это самое раннее значение, соответствующее 64-битному DateTime.
Создайте таблицу
Принятые выше решения о типах данных для столбцов отражены в следующей структуре таблицы. Также необходимо решить, какие поля следует использовать для ORDER BY
и PRIMARY KEY
. По крайней мере, одно из ORDER BY
или PRIMARY KEY
должно быть указано. Вот некоторые рекомендации по выбору столбцов для включения в ORDER BY
, и более подробная информация содержится в разделе Следующие шаги в конце этого документа.
Условия Order By и Primary Key
- Кортеж
ORDER BY
должен включать поля, которые используются в фильтрах запросов. - Чтобы максимизировать сжатие на диске, кортеж
ORDER BY
следует упорядочить по возрастающей кардинальности. - Если он существует, кортеж
PRIMARY KEY
должен быть подсетом кортежаORDER BY
. - Если указан только
ORDER BY
, то тот же кортеж будет использоваться какPRIMARY KEY
. - Индекс первичного ключа создается с использованием кортежа
PRIMARY KEY
, если он указан; в противном случае — кортежаORDER BY
. - Индекс
PRIMARY KEY
хранится в основной памяти.
Посмотрев на набор данных и на вопросы, на которые могут быть даны ответы запросами, мы можем решить, что будем рассматривать типы преступлений, о которых сообщалось с течением времени в пяти районах Нью-Йорка. Эти поля могут быть включены в ORDER BY
:
Столбец | Описание (из справочника данных) |
---|---|
OFNS_DESC | Описание правонарушения, соответствующего ключевому коду |
RPT_DT | Дата, когда событие было сообщено в полицию |
BORO_NM | Название района, в котором произошло происшествие |
Выполните запрос к файлу TSV для кардинальности трех кандидатных столбцов:
Результат:
Упорядочивая по кардинальности, ORDER BY
становится:
В таблице ниже будут использоваться более удобные для чтения имена столбцов, вышеуказанные имена будут сопоставлены с
Составив изменения типов данных и кортеж ORDER BY
, мы получаем следующую структуру таблицы:
Поиск первичного ключа таблицы
База данных ClickHouse system
, а именно system.table
, содержит всю информацию о только что созданной таблице. Этот запрос показывает ORDER BY
(ключ сортировки) и PRIMARY KEY
:
Ответ
Предобработка и импорт данных
Мы будем использовать инструмент clickhouse-local
для предобработки данных и clickhouse-client
для их загрузки.
Аргументы clickhouse-local, используемые для
table='input'
появляется в аргументах к clickhouse-local
ниже. clickhouse-local
принимает предоставленный ввод (cat ${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv
) и вставляет вход в таблицу. По умолчанию таблица называется table
. В этом руководстве имя таблицы установлено на input
, чтобы сделать поток данных более ясным. Последний аргумент для clickhouse-local
— это запрос, который выбирает из таблицы (FROM input
), который затем передается в clickhouse-client
для заполнения таблицы NYPD_Complaint
.
Проверьте данные
Набор данных меняется один или несколько раз в год, ваши подсчеты могут не совпадать с теми, что приведены в этом документе.
Запрос:
Результат:
Размер набора данных в ClickHouse составляет всего 12% от оригинального файла TSV, сравните размер оригинального файла TSV с размером таблицы:
Запрос:
Результат:
Выполните несколько запросов
Запрос 1. Сравните количество жалоб по месяцам
Запрос:
Результат:
Запрос 2. Сравните общее количество жалоб по району
Запрос:
Результат:
Следующие шаги
Практическое введение в разреженные первичные индексы в ClickHouse обсуждает различия в индексации ClickHouse по сравнению с традиционными реляционными базами данных, как ClickHouse создает и использует разреженный первичный индекс, а также лучшие практики индексирования.