محرك جدول يوفّر واجهة شبيهة بالجدول لإجراء SELECT من الملفات وINSERT إليها، على غرار دالة الجدول s3. استخدم file عند العمل مع الملفات المحلية، واستخدم s3 عند العمل مع الحاويات في تخزين الكائنات مثل S3 أو GCS أو MinIO.
يمكن استخدام الدالة file في استعلامات SELECT وINSERT لقراءة الملفات أو الكتابة إليها.
file([path_to_archive ::] path [,format] [,structure] [,compression])
في استعلامات SELECT، يمكن أيضًا أن يكون path تعبيرًا يُرجِع Array(String):
file(['file1.csv', 'file2.csv'], 'CSV', 'column1 UInt32, column2 UInt32')
| المعلمة | الوصف |
|---|
path | المسار النسبي إلى الملف من user_files_path، أو Array(String) من المسارات في استعلامات SELECT. يدعم في وضع القراءة فقط أنماط glob التالية: * و? و{abc,def} (حيث إن 'abc' و'def' سلاسل نصية) و{N..M} (حيث إن N وM أرقام). |
path_to_archive | المسار النسبي إلى أرشيف zip/tar/7z. ويدعم أنماط glob نفسها المستخدمة في path. |
format | التنسيق الخاص بالملف. |
structure | بنية الجدول. التنسيق: 'column1_name column1_type, column2_name column2_type, ...'. |
compression | نوع الضغط الموجود عند استخدامه في استعلام SELECT، أو نوع الضغط المطلوب عند استخدامه في استعلام INSERT. أنواع الضغط المدعومة هي gz وbr وxz وzst وlz4 وbz2. |
عند حذف الوسيط structure، يستنتج ClickHouse المخطط من التنسيق نفسه.
وتنتج التنسيقات المختلفة أسماء أعمدة وأنواعًا افتراضية مختلفة.
لعرض المخطط لتنسيق معيّن، استخدم DESC مع دالة الجدول format.على سبيل المثال:DESC format(LineAsString, 'Hello\nWorld')
┌─name─┬─type───┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐
│ line │ String │ │ │ │ │ │
└──────┴────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘
جدول لقراءة البيانات من ملف أو كتابتها فيه.
أمثلة على الكتابة إلى ملف
INSERT INTO TABLE FUNCTION
file('test.tsv', 'TSV', 'column1 UInt32, column2 UInt32, column3 UInt32')
VALUES (1, 2, 3), (3, 2, 1), (1, 3, 2)
ونتيجةً لذلك، تُكتَب البيانات في الملف test.tsv:
# cat /var/lib/clickhouse/user_files/test.tsv
1 2 3
3 2 1
1 3 2
كتابة مُقسَّمة إلى عدة ملفات TSV
إذا حدّدت تعبير PARTITION BY عند إدراج البيانات في دالة جدول من النوع file، فسيُنشأ ملف منفصل لكل partition. ويساعد تقسيم البيانات إلى ملفات منفصلة على تحسين أداء عمليات القراءة.
INSERT INTO TABLE FUNCTION
file('test_{_partition_id}.tsv', 'TSV', 'column1 UInt32, column2 UInt32, column3 UInt32')
PARTITION BY column3
VALUES (1, 2, 3), (3, 2, 1), (1, 3, 2)
وبالتالي، تُكتب البيانات في ثلاثة ملفات: test_1.tsv وtest_2.tsv وtest_3.tsv.
# cat /var/lib/clickhouse/user_files/test_1.tsv
3 2 1
# cat /var/lib/clickhouse/user_files/test_2.tsv
1 3 2
# cat /var/lib/clickhouse/user_files/test_3.tsv
1 2 3
أولًا، اضبط user_files_path في إعدادات الخادم وجهّز ملفًا باسم test.csv:
$ grep user_files_path /etc/clickhouse-server/config.xml
<user_files_path>/var/lib/clickhouse/user_files/</user_files_path>
$ cat /var/lib/clickhouse/user_files/test.csv
1,2,3
3,2,1
78,43,45
ثم اقرأ البيانات من test.csv إلى جدول، ثم اعرض أول صفّين منه:
SELECT * FROM
file('test.csv', 'CSV', 'column1 UInt32, column2 UInt32, column3 UInt32')
LIMIT 2;
┌─column1─┬─column2─┬─column3─┐
│ 1 │ 2 │ 3 │
│ 3 │ 2 │ 1 │
└─────────┴─────────┴─────────┘
إدخال البيانات من ملف إلى جدول
INSERT INTO FUNCTION
file('test.csv', 'CSV', 'column1 UInt32, column2 UInt32, column3 UInt32')
VALUES (1, 2, 3), (3, 2, 1);
SELECT * FROM
file('test.csv', 'CSV', 'column1 UInt32, column2 UInt32, column3 UInt32');
┌─column1─┬─column2─┬─column3─┐
│ 1 │ 2 │ 3 │
│ 3 │ 2 │ 1 │
└─────────┴─────────┴─────────┘
قراءة البيانات من table.csv، الموجود في archive1.zip أو في archive2.zip أو كليهما:
SELECT * FROM file('user_files/archives/archive{1..2}.zip :: table.csv');
قد تستخدم المسارات أنماط glob. يجب أن تطابق الملفات نمط المسار بالكامل، لا اللاحقة أو البادئة فقط. ويوجد استثناء واحد: إذا كان المسار يشير إلى
دليل موجود ولا يستخدم أنماط glob، فستُضاف * ضمنيًا إلى المسار بحيث
تُحدَّد جميع الملفات الموجودة في الدليل.
* — يمثّل أي عدد من المحارف باستثناء /، بما في ذلك السلسلة الفارغة.
? — يمثّل محرفًا واحدًا أيًا كان.
{some_string,another_string,yet_another_one} — يستبدل بأي من السلاسل 'some_string', 'another_string', 'yet_another_one'. ويمكن أن تحتوي السلاسل على الرمز /.
{N..M} — يمثّل أي رقم >= N و <= M.
** - يمثّل جميع الملفات داخل مجلد على نحوٍ تكراري.
البُنى التي تستخدم {} مشابهة لما في دالتي الجداول remote و hdfs.
مثال
لنفترض وجود هذه الملفات بالمسارات النسبية التالية:
some_dir/some_file_1
some_dir/some_file_2
some_dir/some_file_3
another_dir/some_file_1
another_dir/some_file_2
another_dir/some_file_3
نفّذ استعلامًا لحساب العدد الإجمالي للصفوف في جميع الملفات:
SELECT count(*) FROM file('{some,another}_dir/some_file_{1..3}', 'TSV', 'name String, value UInt32');
تعبير بديل للمسار يحقق النتيجة نفسها:
SELECT count(*) FROM file('{some,another}_dir/*', 'TSV', 'name String, value UInt32');
استعلم عن إجمالي عدد الصفوف في some_dir باستخدام * الضمني:
SELECT count(*) FROM file('some_dir', 'TSV', 'name String, value UInt32');
إذا كانت قائمة الملفات لديك تحتوي على نطاقات رقمية تبدأ بأصفار، فاستخدم الصيغة بالأقواس المعقوفة لكل رقم على حدة، أو استخدم ?.
مثال
استعلم عن العدد الإجمالي للصفوف في الملفات المسماة file000 وfile001 و… وfile999:
SELECT count(*) FROM file('big_dir/file{0..9}{0..9}{0..9}', 'CSV', 'name String, value UInt32');
مثال
استعلم عن العدد الإجمالي للصفوف من جميع الملفات داخل الدليل big_dir/، بما في ذلك الأدلة الفرعية:
SELECT count(*) FROM file('big_dir/**', 'CSV', 'name String, value UInt32');
مثال
استعلم عن العدد الإجمالي للصفوف في جميع ملفات file002 داخل أي مجلد ضمن الدليل big_dir/، بما يشمل جميع المجلدات الفرعية:
SELECT count(*) FROM file('big_dir/**/file002', 'CSV', 'name String, value UInt32');
_path — مسار الملف. النوع: LowCardinality(String).
_file — اسم الملف. النوع: LowCardinality(String).
_size — حجم الملف بالبايت. النوع: Nullable(UInt64). إذا كان حجم الملف غير معروف، تكون القيمة NULL.
_time — وقت آخر تعديل على الملف. النوع: Nullable(DateTime). إذا كان الوقت غير معروف، تكون القيمة NULL.
إعداد use_hive_partitioning
عند تعيين use_hive_partitioning إلى 1، سيكتشف ClickHouse التقسيم بنمط Hive في المسار (/name=value/)، وسيتيح استخدام أعمدة التقسيم كأعمدة افتراضية في الاستعلام. وستحمل هذه الأعمدة الافتراضية الأسماء نفسها الموجودة في مسار التقسيم.
مثال
استخدام عمود افتراضي أُنشئ باستخدام التقسيم بنمط Hive
SELECT * FROM file('data/path/date=*/country=*/code=*/*.parquet') WHERE date > '2020-01-01' AND country = 'Netherlands' AND code = 42;
| الإعداد | الوصف |
|---|
| engine_file_empty_if_not_exists | يتيح إرجاع بيانات فارغة من ملف غير موجود. يكون معطّلًا افتراضيًا. |
| engine_file_truncate_on_insert | يتيح اقتطاع الملف قبل الإدراج فيه. يكون معطّلًا افتراضيًا. |
| engine_file_allow_create_multiple_files | يتيح إنشاء ملف جديد عند كل عملية إدراج إذا كان التنسيق يتضمن لاحقة. يكون معطّلًا افتراضيًا. |
| engine_file_skip_empty_files | يتيح تخطي الملفات الفارغة أثناء القراءة. يكون معطّلًا افتراضيًا. |
| storage_file_read_method | طريقة قراءة البيانات من ملف التخزين، وهي إحدى القيم التالية: read أو pread أو mmap (فقط لـ clickhouse-local). القيمة الافتراضية: pread لـ clickhouse-server، وmmap لـ clickhouse-local. |