ينشئ سياسة الصفوف، أي عامل تصفية يُستخدم لتحديد الصفوف التي يمكن للمستخدم قراءتها من جدول.
لا تكون سياسات الصفوف مجدية إلا للمستخدمين الذين لديهم وصول readonly. إذا كان بإمكان المستخدم تعديل جدول أو نسخ partition بين الجداول، فإن ذلك يُلغي قيود سياسات الصفوف.
الصياغة:
يقبل ParserRowPolicyNames ثلاث صيغ للتجميع (وليس حاصل ضرب ديكارتي كامل):
- أسماء متعددة، هدف واحد — ينشئ
pol1, pol2 ON table1 كل اسم مُدرج على ذلك الجدول وحده (أو db.*).
- اسم واحد، أهداف متعددة — ينشئ
pol1 ON table1, table2 الاسم المختصر نفسه على كل هدف مُدرج.
- أزواج مختلطة — ينشئ
p1 ON t1, p2 ON t2 كل اسم على هدفه المقترن به فقط.
لا يمكن دمج قائمة بأسماء متعددة مع قائمة ON متعددة الجداول ضمن مجموعة واحدة: يُرفض p1, p2 ON t1, t2. وبعد مجموعة بأسماء متعددة، لا يمكنك أيضًا إلحاق مجموعة أخرى من name ON target مفصولة بفواصل ضمن العبارة نفسها.
ينطبق ON CLUSTER الاختياري على العبارة بأكملها (اسم عنقود واحد). لا يقبل ClickHouse ON CLUSTER مختلفًا لكل اسم سياسة مُجمّع ضمن عملية إنشاء واحدة — نفّذ عبارات CREATE ROW POLICY منفصلة عندما يلزم إنشاء سياسات على عناقيد مختلفة.
صحيح:
غير صالح:
تتيح تحديد شرط لتصفية الصفوف. يرى المستخدم صفًا إذا كانت قيمة الشرط المحسوبة لهذا الصف غير صفرية.
في قسم TO، يمكنك تحديد قائمة بالمستخدمين والأدوار التي تنطبق عليها هذه السياسة. على سبيل المثال، CREATE ROW POLICY ... TO accountant, john@localhost.
تعني الكلمة المفتاحية ALL جميع مستخدمي ClickHouse، بما في ذلك المستخدم الحالي. وتتيح الكلمة المفتاحية ALL EXCEPT استبعاد بعض المستخدمين من قائمة جميع المستخدمين، على سبيل المثال، CREATE ROW POLICY ... TO ALL EXCEPT accountant, john@localhost
يُسمح بتفعيل أكثر من سياسة واحدة على الجدول نفسه للمستخدم نفسه في الوقت ذاته. لذلك نحتاج إلى طريقة لدمج الشروط الواردة من سياسات متعددة.
افتراضيًا، تُدمَج السياسات باستخدام العامل المنطقي OR. على سبيل المثال، السياسات التالية:
يُمكِّن المستخدم peter من رؤية الصفوف التي يكون فيها إما b=1 أو c=2.
تحدِّد عبارة AS كيفية دمج السياسات مع السياسات الأخرى. ويمكن أن تكون السياسات إما متساهلة أو مقيِّدة. وبشكل افتراضي، تكون السياسات متساهلة، ما يعني أنها تُدمج باستخدام المعامل المنطقي OR.
ويمكن بدلاً من ذلك تعريف السياسة على أنها مقيِّدة. وتُدمج السياسات المقيِّدة باستخدام المعامل المنطقي AND.
إليك الصيغة العامة:
على سبيل المثال، السياسات التالية:
اسمح للمستخدم peter برؤية الصفوف فقط إذا كان الشرطان b=1 AND c=2 متحققَين.
تُدمَج سياسات قاعدة البيانات مع سياسات الجدول.
على سبيل المثال، السياسات التالية:
يتيح للمستخدم peter رؤية صفوف table1 فقط إذا تحقّق الشرطان b=1 AND c=2 معًا، رغم أن أي جدول آخر في mydb لن تُطبَّق عليه للمستخدم سوى سياسة b=1.
جداول Distributed والجداول المعتمدة على خوادم بعيدة
تُصفّي سياسة الصفوف الصفوف في الموضع الذي تُقرأ فيه بيانات الجدول فعليًا. فالجدول الذي يفوّض القراءة إلى خوادم بعيدة، مثل جدول Distributed أو طبقة تغليف فوقه (مثل عرض مادي له هدف Distributed)، لا يرسل إلى الخوادم البعيدة سوى نص الاستعلام، ولا يمكنه تطبيق عامل تصفية السياسة على القراءة البعيدة. ولمنع إسقاط عامل التصفية بصمت، تُرفض الاستعلامات الموجّهة إلى هذه الجداول من المستخدمين الذين تنطبق عليهم السياسة، ويظهر الخطأ ILLEGAL_PREWHERE.
بدلًا من ذلك، عرّف السياسة على الجداول المحلية الأساسية في كل خادم بعيد؛ إذ تُطبّق هناك عند قراءة الاستعلام المُرسَل لها:
يعمل هذا ما دام query تُرسَل كنص، وهو السلوك الافتراضي. عند استخدام serialize_query_plan = 1، يرسل initiator بدلاً من ذلك plan قراءة مُعدّة مسبقاً، ولا يطبّق remote server الذي ينفّذ هذه plan سياسات الصفوف الخاصة به. لذلك، تُرجع قراءة table من نوع Distributed عبر local_table صفوفاً غير مُرشّحة. أبقِ serialize_query_plan = 0 للمستخدمين الذين يجب فرض سياسات الصفوف عليهم. راجع issue #112891.
تسمح بإنشاء سياسات الصفوف على مستوى العنقود، راجع DDL الموزع. وهذه أيضًا طريقة ملائمة لإنشاء السياسة على الجداول المحلية لكل خادم في العنقود.
CREATE ROW POLICY filter1 ON mydb.mytable USING a<1000 TO accountant, john@localhost
CREATE ROW POLICY filter2 ON mydb.mytable USING a<1000 AND b=5 TO ALL EXCEPT mira
CREATE ROW POLICY filter3 ON mydb.mytable USING 1 TO admin
CREATE ROW POLICY filter4 ON mydb.* USING 1 TO admin