في هذا القسم، سنستعرض صياغة SQL في ClickHouse. يستخدم ClickHouse صياغةً قائمة على SQL، لكنه يوفّر عددًا من الامتدادات والتحسينات.
تحليل الاستعلام
يوجد نوعان من المحلِّلات في ClickHouse:
- محلِّل SQL كامل (محلِّل تنازلي تكراري).
- محلِّل تنسيق البيانات (محلِّل تدفّق سريع).
يُستخدم محلِّل SQL الكامل في جميع الحالات باستثناء استعلام INSERT، إذ يستخدم هذا الاستعلام كلا المحلِّلين.
لنستعرض الاستعلام أدناه:
INSERT INTO t VALUES (1, 'Hello, world'), (2, 'abc'), (3, 'def')كما ذُكر سابقًا، يستخدم استعلام INSERT كلا المحلّلين.
يُحلَّل الجزء INSERT INTO t VALUES بواسطة المحلّل الكامل،
وتُحلَّل البيانات (1, 'Hello, world'), (2, 'abc'), (3, 'def') بواسطة محلّل تنسيق البيانات، أو محلّل التدفق السريع.
تشغيل المحلّل الكامل
يمكنك أيضًا تشغيل المحلّل الكامل للبيانات
باستخدام الإعداد input_format_values_interpret_expressions.
عندما تكون قيمة الإعداد المذكور أعلاه 1،
يحاول ClickHouse أولًا تحليل القيم باستخدام محلّل التدفق السريع.
وإذا أخفق ذلك، يحاول ClickHouse استخدام المحلّل الكامل للبيانات، مع التعامل معها كتعبير SQL تعبير.
يمكن أن تكون البيانات بأي تنسيق.
وعند استلام استعلام، لا يحتسب الخادم في RAM أكثر من max_query_size بايت من الطلب
(افتراضيًا، 1 MB)، ويُحلَّل الباقي كتدفق.
وذلك لتجنّب المشكلات المرتبطة باستعلامات INSERT الكبيرة، وهي الطريقة الموصى بها لإدراج بياناتك في ClickHouse.
عند استخدام تنسيق Values في استعلام INSERT،
قد يبدو أن البيانات تُحلَّل بالطريقة نفسها كما في التعبيرات ضمن استعلام SELECT، لكن الأمر ليس كذلك.
فتنسيق Values أكثر محدوديةً بكثير.
يغطي ما تبقّى من هذا القسم المحلّل الكامل.
المسافات
- يمكن أن يوجد أي عدد من محارف المسافات بين التركيبات النحوية (بما في ذلك في بداية الاستعلام ونهايته).
- تشمل محارف المسافات: المسافة، وعلامة الجدولة، وتغذية السطر، وCR، وتغذية الصفحة.
يدعم ClickHouse التعليقات بنمط SQL وبنمط C:
- تبدأ التعليقات بنمط SQL بـ
--أو#!أو#وتستمر حتى نهاية السطر. ويمكن حذف المسافة بعد--و#!. - التعليقات بنمط C:
//(أو أكثر من حرفي/) متبوعًا بنص حتى نهاية السطر. ولا يُشترط وجود مسافات بعد/.- يمكن أن تمتد من
/*إلى*/في التعليقات متعددة الأسطر. ولا تُشترط المسافات هنا أيضًا. - يمكن أن تكون التعليقات بنمط C متداخلة.
على سبيل المثال:
/*
* Compute the number of days between two dates.
* /* Returns NULL if either argument is NULL */
*/
SELECT
dateDiff('day', toDate('2024-01-01'), toDate('2024-12-31')) AS days_in_year, -- 365
dateDiff('day', toDate('2020-01-01'), today()) AS days_since #! since 2020
///////////////////////////////////////////////////////////////////
# TODO: add hour/minute variantsالكلمات المفتاحية
يمكن أن تكون الكلمات المفتاحية في ClickHouse إما حساسة لحالة الأحرف أو غير حساسة لحالة الأحرف، بحسب السياق.
تكون الكلمات المفتاحية غير حساسة لحالة الأحرف عندما تتوافق مع:
- معيار SQL. على سبيل المثال،
SELECTوselectوSeLeCtكلها صيغ صحيحة. - طريقة التنفيذ في بعض أنظمة إدارة قواعد البيانات الشائعة (MySQL أو Postgres). على سبيل المثال،
DateTimeهو نفسهdatetime.
وعلى خلاف SQL القياسي، فإن جميع الكلمات المفتاحية الأخرى (بما في ذلك أسماء الدوال) حساسة لحالة الأحرف.
إضافةً إلى ذلك، الكلمات المفتاحية ليست كلمات محجوزة.
ولا تُعامَل على هذا النحو إلا ضمن السياق المقابل.
إذا استخدمت المعرّفات بالاسم نفسه للكلمات المفتاحية، فأحطها بعلامات اقتباس مزدوجة أو بعلامات backticks.
على سبيل المثال، يكون الاستعلام التالي صالحًا إذا كان الجدول table_name يحتوي على عمود اسمه "FROM":
SELECT "FROM" FROM table_nameالمعرّفات
المعرّفات هي:
- أسماء العناقيد، وقواعد البيانات، والجداول، والتقسيمات، والأعمدة.
- الدوال.
- أنواع البيانات.
- الأسماء المستعارة للتعبيرات.
يمكن أن تكون المعرّفات مقتبسة أو غير مقتبسة، مع أن الأخيرة هي المفضّلة.
يجب أن تطابق المعرّفات غير المقتبسة التعبير النمطي ^[a-zA-Z_][0-9a-zA-Z_]*$، ولا يجوز أن تطابق الكلمات المفتاحية.
راجع الجدول أدناه للاطلاع على أمثلة للمعرّفات الصالحة وغير الصالحة:
| المعرّفات الصالحة | المعرّفات غير الصالحة |
|---|---|
xyz, _internal, Id_with_underscores_123_ |
1x, tom@gmail.com, äußerst_schön |
إذا كنت تريد استخدام معرّفات تطابق الكلمات المفتاحية، أو تريد استخدام رموز أخرى في المعرّفات، فضعها بين علامتي اقتباس مزدوجتين أو بين علامتي التنصيص الخلفيتين، على سبيل المثال: "id"، `id`.
القيم الحرفية
في ClickHouse، القيمة الحرفية هي قيمة تُمثَّل مباشرةً في الاستعلام. وبعبارة أخرى، فهي قيمة ثابتة لا تتغير أثناء تنفيذ الاستعلام.
يمكن أن تكون القيم الحرفية:
سنستعرض كلًّا منها بمزيد من التفصيل في الأقسام أدناه.
String
يجب أن تُحاط القيم الحرفية النصية بعلامات اقتباس مفردة. علامات الاقتباس المزدوجة غير مدعومة.
تعمل آلية الهروب بإحدى الطريقتين التاليتين:
- استخدام علامة اقتباس مفردة سابقة، إذ لا يمكن تهريب محرف علامة الاقتباس المفردة
'(وهذا المحرف فقط) إلا على هيئة''، أو - استخدام الشرطة المائلة العكسية السابقة مع تسلسلات الهروب المدعومة التالية والمُدرجة في الجدول أدناه.
| التهريب المدعوم | الوصف |
|---|---|
\xHH |
تحديد محرف من 8 بت متبوع بأي عدد من الأرقام الست عشرية (H). |
\N |
محجوز، ولا يفعل شيئًا (مثلًا SELECT 'a\Nb' تُرجع ab) |
\a |
تنبيه |
\b |
رجوع للخلف |
\e |
محرف الهروب |
\f |
فاصل صفحة |
\n |
تغذية سطر |
\r |
إرجاع العربة |
\t |
علامة تبويب أفقية |
\v |
علامة تبويب عمودية |
\0 |
محرف NULL |
\\ |
الشرطة المائلة العكسية |
\' (أو '') |
علامة اقتباس مفردة |
\" |
علامة اقتباس مزدوجة |
` |
علامة الاقتباس الخلفية |
\/ |
الشرطة المائلة الأمامية |
\= |
علامة يساوي |
| محارف تحكم ASCII (c <= 31). |
القيم الحرفية العددية
تُحلَّل القيم الحرفية العددية على النحو التالي:
- إذا كانت القيمة الحرفية مسبوقة بعلامة الطرح
-، فيُتخطى الرمز وتُطبَّق الإشارة السالبة على النتيجة بعد التحليل. - تُحلَّل القيمة الحرفية العددية أولًا كعدد صحيح غير موقَّع بعرض 64 بت، باستخدام الدالة strtoull.
- إذا كانت القيمة مسبوقة بـ
0bأو0x/0X، فيُحلَّل العدد كثنائي أو سداسي عشري، على التوالي. - إذا كانت القيمة سالبة وكان مقدارها المطلق أكبر من 263، فسيُعاد خطأ.
- إذا كانت القيمة مسبوقة بـ
- إذا لم ينجح ذلك، تُحلَّل القيمة بعد ذلك كعدد بفاصلة عائمة باستخدام الدالة strtod.
- بخلاف ذلك، يُعاد خطأ.
تُحوَّل القيم الحرفية إلى أصغر نوع تتسع له القيمة. على سبيل المثال:
- يُحلَّل
1على أنهUInt8 - يُحلَّل
256على أنهUInt16.
لمزيد من المعلومات، راجع أنواع البيانات.
تُتجاهل الشرطات السفلية _ داخل القيم الحرفية العددية، ويمكن استخدامها لتحسين سهولة القراءة.
القيم الحرفية العددية التالية مدعومة:
| القيمة الحرفية العددية | أمثلة |
|---|---|
| الأعداد الصحيحة | 1, 10_000_000, 18446744073709551615, 01 |
| الأعداد العشرية | 0.1 |
| الترميز الأسي | 1e100, -1e-100 |
| أعداد الفاصلة العائمة | 123.456, inf, nan |
| سداسي عشري | 0xc0fe |
| سلسلة سداسية عشرية متوافقة مع معيار SQL | x'c0fe' |
| ثنائي | 0b1101 |
| سلسلة ثنائية متوافقة مع معيار SQL | b'1101' |
المركّبات
تُنشأ المصفوفات باستخدام []: [1, 2, 3]. وتُنشأ الـ Tuples باستخدام (): (1, 'Hello, world!', 2).
من الناحية التقنية، لا تُعد هذه قيَمًا حرفية، بل هي تعبيرات تستخدم عامل إنشاء المصفوفة وعامل إنشاء الـ Tuple، على الترتيب.
يجب أن تتكوّن المصفوفة من عنصر واحد على الأقل، ويجب أن يتكوّن الـ Tuple من عنصرين على الأقل.
NULL
يُستخدم NULL للإشارة إلى أن قيمةً ما مفقودة.
ولتخزين NULL في حقل بجدول، يجب أن يكون هذا الحقل من النوع Nullable.
Heredoc
يُعد heredoc أسلوبًا لتعريف سلسلة نصية (غالبًا ما تكون متعددة الأسطر) مع الحفاظ على التنسيق الأصلي.
ويُعرَّف heredoc بأنه قيمة نصية حرفية مخصّصة توضع بين رمزي $.
على سبيل المثال:
SELECT $heredoc$SHOW CREATE VIEW my_view$heredoc$;
┌تعريف معلمات الاستعلام واستخدامها
تتيح لك معلمات الاستعلام كتابة استعلامات عامة تحتوي على عناصر نائبة مجردة بدلًا من المعرّفات الفعلية. وعند تنفيذ استعلام يتضمن معلمات استعلام، تُفسَّر جميع العناصر النائبة وتُستبدل بقيم معلمات الاستعلام الفعلية.
يمكن تعريف معلمات الاستعلام بعدة طرق:
SET param_<name>=<value>— باستخدام أمرSETداخل استعلام.--param_<name>='<value>'— كوسيطة لـclickhouse-clientفي سطر الأوامر.param_<name>=<value>— كمعلمة في سلسلة استعلام URL لواجهة HTTP.
يمكن الإشارة إلى معلمة استعلام داخل استعلام باستخدام {<name>: <datatype>}، حيث إن <name> هو اسم معلمة الاستعلام و<datatype> هو نوع البيانات الذي تُحوَّل إليه.
مثال باستخدام أمر SET
على سبيل المثال، يعرّف SQL التالي معلمات بأسماء a وb وc وd، ولكل منها نوع بيانات مختلف:
SET param_a = 13;
SET param_b = 'str';
SET param_c = '2022-08-04 18:30:53';
SET param_d = {'10': [11, 12], '13': [14, 15]};
SELECT
{a: UInt32},
{b: String},
{c: DateTime},
{d: Map(String, Array(UInt8))};
13 str 2022-08-04 18:30:53 {'10':[11,12],'13':[14,15]}مثال باستخدام clickhouse-client
إذا كنت تستخدم clickhouse-client، فتُحدَّد المعلمات بصيغة --param_name=value. على سبيل المثال، تحمل المعلمة التالية الاسم message وتُسترجع كـ String:
clickhouse-client --param_message='hello' --query="SELECT {message: String}"
helloإذا كانت معلمة الاستعلام تمثّل اسم database أو table أو function أو أي Identifier آخر، فاستخدم Identifier كنوع لها. على سبيل المثال، يعيد الاستعلام التالي rows من table اسمها uk_price_paid:
SET param_mytablename = "uk_price_paid";
SELECT * FROM {mytablename:Identifier};مثال باستخدام واجهة HTTP
يمكن تمرير معلمات الاستعلام كمعلمات في سلسلة استعلام URL مع البادئة param_. على سبيل المثال:
curl -s "http://localhost:8123/?param_message=hello" --data-binary "SELECT {message: String}"
helloمثال باستخدام واجهة الويب
تكتشف واجهة الويب المضمّنة (play.html) تلقائيًا العناصر النائبة للمعلمات بصيغة {name:Type} في الاستعلام، وتعرض حقول إدخال معنونة لكل معلمة. تُضمَّن قيم المعلمات في HTTP request، كما تُحفَظ أيضًا في URL الصفحة لأغراض وضع الإشارات المرجعية والمشاركة.
الدوال
تُكتب استدعاءات الدوال بصيغة مُعرِّف تتبعه قائمة من الوسائط داخل ()، وقد تكون هذه القائمة فارغة.
وعلى خلاف SQL القياسي، تكون الأقواس مطلوبة حتى عندما تكون قائمة الوسائط فارغة.
على سبيل المثال:
now()هناك أيضًا ما يلي:
قد تتضمن بعض الدوال التجميعية قائمتين من الوسائط بين قوسين. على سبيل المثال:
quantile (0.9)(x) تُسمّى هذه الدوال التجميعية دوالًا "بارامترية"، ويُطلَق على الوسيطات في القائمة الأولى اسم "المعلمات".
المعاملات
تُحوَّل المعاملات إلى الدوال المقابلة لها أثناء تحليل الاستعلام، مع مراعاة أولويتها وترابطيتها.
على سبيل المثال، التعبير
1 + 2 * 3 + 4يُحوَّل إلى
plus(plus(1, multiply(2, 3)), 4)`أنواع البيانات ومحركات الجداول في قاعدة البيانات
تُكتب أنواع البيانات ومحركات الجداول في استعلام CREATE بالطريقة نفسها التي تُكتب بها المعرّفات أو الدوال.
وبعبارة أخرى، قد تحتوي على قائمة وسائط بين أقواس، وقد لا تحتوي.
لمزيد من المعلومات، راجع الأقسام التالية:
التعبيرات
يمكن أن يكون التعبير أيًا مما يلي:
- دالة
- مُعرّف
- قيمة حرفية
- تطبيق معامل
- تعبير بين قوسين
- استعلام فرعي
- علامة النجمة
ويمكن أن يتضمن أيضًا اسمًا مستعارًا.
قائمة التعبيرات هي تعبير واحد أو أكثر تفصل بينها فاصلات. ويمكن للدوال والمعاملات بدورها أن تأخذ تعبيرات كوسيطات.
التعبير الثابت هو تعبير تكون نتيجته معروفة أثناء تحليل الاستعلام، أي قبل التنفيذ. على سبيل المثال، التعبيرات المبنية على القيم الحرفية هي تعبيرات ثابتة.
الأسماء المستعارة للتعبيرات
الاسم المستعار هو اسم يعرّفه المستخدم لـ تعبير ضمن استعلام.
expr AS aliasتُشرح أجزاء الصياغة أعلاه فيما يلي.
| جزء من الصياغة | الوصف | مثال | ملاحظات |
|---|---|---|---|
AS |
الكلمة المفتاحية لتعريف الأسماء المستعارة. يمكنك تعريف الاسم المستعار لاسم جدول أو اسم عمود في عبارة SELECT من دون استخدام الكلمة المفتاحية AS. |
SELECT table_name_alias.column_name FROM table_name table_name_alias. |
في الدالة CAST، يكون للكلمة المفتاحية AS معنى آخر. راجع وصف الدالة. |
expr |
أي تعبير يدعمه ClickHouse. | SELECT column_name * 2 AS double FROM some_table |
|
alias |
اسم لـ expr. يجب أن تتوافق الأسماء المستعارة مع صياغة المعرّفات. |
SELECT "table t".column_name FROM table_name AS "table t". |
ملاحظات حول الاستخدام
- تسري الأسماء المستعارة على مستوى الاستعلام أو الاستعلام الفرعي بالكامل، ويمكنك تعريف اسم مستعار لأي تعبير في أي جزء من الاستعلام. على سبيل المثال:
SELECT (1 AS n) + 2, n`.- الأسماء المستعارة لا تكون مرئية داخل الاستعلامات الفرعية ولا فيما بينها. على سبيل المثال، عند تنفيذ الاستعلام التالي، يُرجع ClickHouse الاستثناء
Unknown identifier: num:
`SELECT (SELECT sum(b.a) + num FROM b) - a.a AS num FROM a`- إذا تم تعريف اسم مستعار لأعمدة النتيجة في عبارة
SELECTداخل استعلام فرعي، فستكون هذه الأعمدة مرئية في الاستعلام الخارجي. على سبيل المثال:
SELECT n + m FROM (SELECT 1 AS n, 2 AS m)`.- انتبه إلى الأسماء المستعارة التي تطابق أسماء الأعمدة أو الجداول. لننظر إلى المثال التالي:
CREATE TABLE t
(
a Int,
b Int
)
ENGINE = TinyLog();
SELECT
argMax(a, b),
sum(b) AS b
FROM t;
Received exception from server (version 18.14.17):
Code: 184. DB::Exception: Received from localhost:9000, 127.0.0.1. DB::Exception: Aggregate function sum(b) is found inside another aggregate function in query.في المثال السابق، عرّفنا الجدول t بالعمود b.
ثم عند تحديد البيانات، عرّفنا الاسم المستعار sum(b) AS b.
ونظرًا لأن الأسماء المستعارة عامة النطاق،
استبدل ClickHouse الرمز b في التعبير argMax(a, b) بالتعبير sum(b).
وقد أدى هذا الاستبدال إلى حدوث الاستثناء.
النجمة
في استعلام SELECT، يمكن أن تحل النجمة محل التعبير.
لمزيد من المعلومات، راجع القسم SELECT.
التعليقات