الانتقال إلى المحتوى الرئيسي
إخفاء البيانات هو تقنية تُستخدم لحماية البيانات، حيث تُستبدل البيانات الأصلية بنسخة منها تحافظ على تنسيقها وبنيتها مع إزالة أي معلومات تعريف شخصية (PII) أو معلومات حساسة. يوضح هذا الدليل كيفية إخفاء البيانات في ClickHouse باستخدام عدة أساليب:
  • سياسات الإخفاء (ClickHouse Cloud، 25.12+): إخفاء ديناميكي مدمج يُطبَّق وقت الاستعلام لمستخدمين/أدوار محددة
  • String replacement functions: إخفاء أساسي باستخدام الدوال المضمنة
  • Masked views: إنشاء طرق عرض بمنطق تحويل
  • Materialized columns: تخزين نُسخ مخفية إلى جانب البيانات الأصلية
  • قواعد إخفاء الاستعلامات: إخفاء البيانات الحساسة في السجلات (ClickHouse OSS)

استخدام سياسات الإخفاء (ClickHouse Cloud)

تتوفر سياسات الإخفاء في ClickHouse Cloud بدءًا من الإصدار 25.12.
يوفّر الأمر CREATE MASKING POLICY طريقة مدمجة لإخفاء قيم الأعمدة ديناميكيًا لمستخدمين أو أدوار محددة عند وقت الاستعلام. وعلى عكس الأساليب الأخرى، لا تتطلب سياسات الإخفاء إنشاء واجهات عرض منفصلة أو تخزين بيانات مخفية، إذ يحدث هذا التحويل بشفافية عندما يستعلم المستخدمون من الجدول.

سياسة إخفاء بسيطة

لتوضيح سياسات الإخفاء، لننشئ جدول orders يحتوي على معلومات العملاء:
CREATE TABLE orders (
    user_id UInt32,
    name String,
    email String,
    phone String,
    total_amount Decimal(10,2),
    order_date Date,
    shipping_address String
)
ENGINE = MergeTree()
ORDER BY user_id;

INSERT INTO orders VALUES
    (1001, 'John Smith', 'john.smith@gmail.com', '555-123-4567', 299.99, '2024-01-15', '123 Main St, New York, NY 10001'),
    (1002, 'Sarah Johnson', 'sarah.johnson@outlook.com', '555-987-6543', 149.50, '2024-01-16', '456 Oak Ave, Los Angeles, CA 90210'),
    (1003, 'Michael Brown', 'mbrown@company.com', '555-456-7890', 599.00, '2024-01-17', '789 Pine Rd, Chicago, IL 60601'),
    (1004, 'Emily Rogers', 'emily.rogers@yahoo.com', '555-321-0987', 89.99, '2024-01-18', '321 Elm St, Houston, TX 77001'),
    (1005, 'David Wilson', 'dwilson@email.net', '555-654-3210', 449.75, '2024-01-19', '654 Cedar Blvd, Phoenix, AZ 85001');
الآن، أنشئ دورًا للمستخدمين الذين ينبغي لهم رؤية البيانات المخفية:
CREATE ROLE masked_data_viewer;
أنشئ سياسة إخفاء تُطبَّق على دور masked_data_viewer:
CREATE MASKING POLICY mask_pii_data ON orders
    UPDATE
        name = replaceRegexpOne(name, '^([A-Za-z]+)\\s+(.*)$', '\\1 ****'),
        email = replaceRegexpOne(email, '^(.{2})[^@]*(@.*)$', '\\1****\\2'),
        phone = replaceRegexpOne(phone, '^(\\d{3})-(\\d{3})-(\\d{4})$', '\\1-***-\\3'),
        shipping_address = replaceRegexpOne(shipping_address, '^[^,]+,\\s*(.*)$', '*** \\1')
    TO masked_data_viewer;
عندما يُجري مستخدم لديه الدور masked_data_viewer استعلامًا على الجدول orders، فإنه يرى البيانات المخفية تلقائيًا:
Query
SELECT * FROM orders ORDER BY user_id;
Response (for masked_data_viewer role)
┌─user_id─┬─name─────────┬─email──────────────┬─phone────────┬─total_amount─┬─order_date─┬─shipping_address──────────┐
│    1001 │ John ****    │ jo****@gmail.com   │ 555-***-4567 │       299.99 │ 2024-01-15 │ *** New York, NY 10001    │
│    1002 │ Sarah ****   │ sa****@outlook.com │ 555-***-6543 │        149.5 │ 2024-01-16 │ *** Los Angeles, CA 90210 │
│    1003 │ Michael **** │ mb****@company.com │ 555-***-7890 │          599 │ 2024-01-17 │ *** Chicago, IL 60601     │
│    1004 │ Emily ****   │ em****@yahoo.com   │ 555-***-0987 │        89.99 │ 2024-01-18 │ *** Houston, TX 77001     │
│    1005 │ David ****   │ dw****@email.net   │ 555-***-3210 │       449.75 │ 2024-01-19 │ *** Phoenix, AZ 85001     │
└─────────┴──────────────┴────────────────────┴──────────────┴──────────────┴────────────┴───────────────────────────┘
يرى المستخدمون الذين لا يملكون الدور masked_data_viewer البيانات الأصلية غير المُخفاة.

الإخفاء المشروط

يمكنك استخدام العبارة WHERE لتطبيق الإخفاء على صفوف معيّنة فقط. على سبيل المثال، لإخفاء الطلبات ذات القيمة العالية فقط:
CREATE MASKING POLICY mask_high_value_orders ON orders
    UPDATE
        name = replaceRegexpOne(name, '^([A-Za-z]+)\\s+(.*)$', '\\1 ****'),
        email = replaceRegexpOne(email, '^(.{2})[^@]*(@.*)$', '\\1****\\2')
    WHERE total_amount > 200
    TO masked_data_viewer;

سياسات متعددة مع تحديد الأولوية

عندما تسري عدة سياسات إخفاء على العمود نفسه، استخدم البند PRIORITY للتحكم في التحويل الذي سيُطبَّق. وتُطبَّق قيم الأولوية الأعلى أخيرًا:
-- Lower priority: Basic masking for all sensitive data
CREATE MASKING POLICY basic_masking ON orders
    UPDATE
        name = '****',
        email = '****@****.com'
    TO masked_data_viewer
    PRIORITY 0;

-- Higher priority: More refined masking (overrides basic_masking)
CREATE MASKING POLICY refined_masking ON orders
    UPDATE
        name = replaceRegexpOne(name, '^([A-Za-z]+)\\s+(.*)$', '\\1 ****')
    WHERE total_amount > 100
    TO masked_data_viewer
    PRIORITY 10;
في هذا المثال، بالنسبة إلى الطلبات التي يكون فيها total_amount > 100، تحلّ سياسة refined_masking (الأولوية 10) محلّ سياسة basic_masking (الأولوية 0) بالنسبة إلى العمود name، بينما يواصل email استخدام الإخفاء الأساسي.

الإخفاء المستند إلى التجزئة

في الحالات التي تحتاج فيها إلى إخفاء متسق (أي إن الإدخال نفسه يُنتِج دائمًا المخرَج المُخفى نفسه)، استخدم دوال التجزئة:
CREATE MASKING POLICY hash_sensitive_data ON orders
    UPDATE
        email = concat(toString(cityHash64(email)), '@masked.com'),
        phone = concat('555-', toString(cityHash64(phone) % 10000000))
    TO masked_data_viewer;

إدارة سياسات الإخفاء

اعرض جميع سياسات الإخفاء:
SHOW MASKING POLICIES;
احذف سياسة إخفاء البيانات:
DROP MASKING POLICY mask_pii_data ON orders;
استبدال سياسة موجودة:
CREATE OR REPLACE MASKING POLICY mask_pii_data ON orders
    UPDATE name = '[REDACTED]'
    TO masked_data_viewer;
لمزيد من التفاصيل، راجع توثيق CREATE MASKING POLICY.

استخدم دوال استبدال السلاسل النصية

في حالات استخدام إخفاء البيانات الأساسية، توفّر عائلة الدوال replace طريقة ملائمة لإخفاء البيانات:
الدالةالوصف
replaceOneتستبدل أول ظهور لنمط في سلسلة النص المراد البحث فيه بالنص البديل المُقدَّم.
replaceAllتستبدل جميع مواضع ظهور النمط في سلسلة النص المراد البحث فيه بالنص البديل المُقدَّم.
replaceRegexpOneتستبدل أول ظهور لسلسلة فرعية تطابق نمط تعبير نمطي (بصياغة re2) في النص المراد البحث فيه بالنص البديل المُقدَّم.
replaceRegexpAllتستبدل جميع مواضع ظهور سلسلة فرعية تطابق نمط تعبير نمطي (بصياغة re2) في النص المراد البحث فيه بالنص البديل المُقدَّم.
على سبيل المثال، يمكنك استبدال الاسم “John Smith” بعنصر نائب [CUSTOMER_NAME] باستخدام الدالة replaceOne:
Query
SELECT replaceOne(
    'Customer John Smith called about his account',
    'John Smith',
    '[CUSTOMER_NAME]'
) AS anonymized_text;
Response
┌─anonymized_text───────────────────────────────────┐
│ Customer [CUSTOMER_NAME] called about his account │
└───────────────────────────────────────────────────┘
وبشكلٍ أعم، يمكنك استخدام replaceRegexpOne لاستبدال اسم أي عميل:
Query
SELECT 
    replaceRegexpAll(
        'Customer John Smith called. Later, Mary Johnson and Bob Wilson also called.',
        '\\b[A-Z][a-z]+ [A-Z][a-z]+\\b',
        '[CUSTOMER_NAME]'
    ) AS anonymized_text;
Response
┌─anonymized_text───────────────────────────────────────────────────────────────────────┐
│ [CUSTOMER_NAME] Smith called. Later, [CUSTOMER_NAME] and [CUSTOMER_NAME] also called. │
└───────────────────────────────────────────────────────────────────────────────────────┘
أو يمكنك إخفاء رقم الضمان الاجتماعي مع الإبقاء على آخر 4 أرقام فقط باستخدام الدالة replaceRegexpAll.
Query
SELECT replaceRegexpAll(
    'SSN: 123-45-6789',
    '(\d{3})-(\d{2})-(\d{4})',
    'XXX-XX-\3'
) AS masked_ssn;
في الاستعلام أعلاه، يُستخدم \3 لإدراج مجموعة الالتقاط الثالثة في السلسلة الناتجة، لينتج ما يلي:
Response
┌─masked_ssn───────┐
│ SSN: XXX-XX-6789 │
└──────────────────┘

إنشاء VIEWs لإخفاء البيانات

يمكن استخدام VIEW بالاقتران مع دوال السلاسل النصية المذكورة أعلاه لتطبيق تحويلات على الأعمدة التي تحتوي على بيانات حساسة قبل عرضها على المستخدم. وبهذه الطريقة، تبقى البيانات الأصلية من دون تغيير، ولا يرى المستخدمون الذين يستعلمون عبر هذا الـ VIEW سوى البيانات المُخفاة. للتوضيح، لنتخيّل أن لدينا جدولًا يخزّن سجلات طلبات العملاء. نريد التأكد من أن مجموعة من الموظفين يمكنها عرض هذه المعلومات، لكننا لا نريدهم أن يروا البيانات الكاملة الخاصة بالعملاء. شغّل الاستعلام أدناه لإنشاء جدول تجريبي باسم orders وإدراج بعض سجلات طلبات العملاء الافتراضية فيه:
CREATE TABLE orders (
    user_id UInt32,
    name String,
    email String,
    phone String,
    total_amount Decimal(10,2),
    order_date Date,
    shipping_address String
)
ENGINE = MergeTree()
ORDER BY user_id;

INSERT INTO orders VALUES
    (1001, 'John Smith', 'john.smith@gmail.com', '555-123-4567', 299.99, '2024-01-15', '123 Main St, New York, NY 10001'),
    (1002, 'Sarah Johnson', 'sarah.johnson@outlook.com', '555-987-6543', 149.50, '2024-01-16', '456 Oak Ave, Los Angeles, CA 90210'),
    (1003, 'Michael Brown', 'mbrown@company.com', '555-456-7890', 599.00, '2024-01-17', '789 Pine Rd, Chicago, IL 60601'),
    (1004, 'Emily Rogers', 'emily.rogers@yahoo.com', '555-321-0987', 89.99, '2024-01-18', '321 Elm St, Houston, TX 77001'),
    (1005, 'David Wilson', 'dwilson@email.net', '555-654-3210', 449.75, '2024-01-19', '654 Cedar Blvd, Phoenix, AZ 85001');
أنشئ طريقة عرض باسم masked_orders:
CREATE VIEW masked_orders AS
SELECT
    user_id,
    replaceRegexpOne(name, '^([A-Za-z]+)\\s+(.*)$', '\\1 ****') AS name,
    replaceRegexpOne(email, '^(.{0})[^@]*(@.*)$', '\\1****\\2') AS email,
    replaceRegexpOne(phone, '^(\\d{3})-(\\d{3})-(\\d{4})$', '\\1-***-\\3') AS phone,
    total_amount,
    order_date,
    replaceRegexpOne(shipping_address, '^[^,]+,\\s*(.*)$', '*** \\1') AS shipping_address
FROM orders;
في عبارة SELECT ضمن استعلام إنشاء طريقة العرض أعلاه، نحدّد التحويلات باستخدام replaceRegexpOne على الحقول name وemail وphone وshipping_address، وهي الحقول التي تحتوي على معلومات حساسة ونرغب في إخفائها جزئيًا. اعرض البيانات من طريقة العرض:
Query
SELECT * FROM masked_orders
Response
┌─user_id─┬─name─────────┬─email──────────────┬─phone────────┬─total_amount─┬─order_date─┬─shipping_address──────────┐
│    1001 │ John ****    │ jo****@gmail.com   │ 555-***-4567 │       299.99 │ 2024-01-15 │ *** New York, NY 10001    │
│    1002 │ Sarah ****   │ sa****@outlook.com │ 555-***-6543 │        149.5 │ 2024-01-16 │ *** Los Angeles, CA 90210 │
│    1003 │ Michael **** │ mb****@company.com │ 555-***-7890 │          599 │ 2024-01-17 │ *** Chicago, IL 60601     │
│    1004 │ Emily ****   │ em****@yahoo.com   │ 555-***-0987 │        89.99 │ 2024-01-18 │ *** Houston, TX 77001     │
│    1005 │ David ****   │ dw****@email.net   │ 555-***-3210 │       449.75 │ 2024-01-19 │ *** Phoenix, AZ 85001     │
└─────────┴──────────────┴────────────────────┴──────────────┴──────────────┴────────────┴───────────────────────────┘
لاحظ أن البيانات المُعادة من طريقة العرض تكون مخفية جزئيًا، مما يحجب المعلومات الحساسة. يمكنك أيضًا إنشاء عدة طرق عرض بمستويات مختلفة من التعتيم، بحسب مستوى الوصول الممنوح إلى المعلومات لدى الـ Viewer. لضمان تمكّن المستخدمين من الوصول فقط إلى طريقة العرض التي تُرجع البيانات المخفية، وليس إلى الـ table التي تحتوي على البيانات الأصلية غير المقنَّعة، ينبغي استخدام Role Based Access Control لضمان أن تكون لدى أدوار محددة فقط grants لإجراء select من طريقة العرض. أنشئ الدور أولًا:
CREATE ROLE masked_orders_viewer;
بعد ذلك، امنح الدور امتيازات SELECT على طريقة العرض:
GRANT SELECT ON masked_orders TO masked_orders_viewer;
نظرًا إلى أن أدوار ClickHouse تراكمية، يجب عليك التأكد من أن المستخدمين الذين ينبغي لهم رؤية العرض المُخفّى فقط لا يملكون أي امتياز SELECT على الجدول الأساسي من خلال أي دور. لذلك، ينبغي لك إلغاء امتياز الوصول إلى الجدول الأساسي صراحةً احتياطًا:
REVOKE SELECT ON orders FROM masked_orders_viewer;
أخيرًا، أسنِد الدور إلى المستخدمين المناسبين:
GRANT masked_orders_viewer TO your_user;
يضمن ذلك أن المستخدمين الذين لديهم الدور masked_orders_viewer لا يمكنهم سوى الاطلاع على البيانات المخفية من العرض، وليس البيانات الأصلية غير المُقنَّعة من الجدول.

استخدم أعمدة MATERIALIZED وقيود الوصول على مستوى العمود

في الحالات التي لا تريد فيها إنشاء طريقة عرض منفصلة، يمكنك تخزين نُسخ مخفية من بياناتك إلى جانب البيانات الأصلية. وللقيام بذلك، يمكنك استخدام أعمدة MATERIALIZED. تُحتسب قيم هذه الأعمدة تلقائيًا وفقًا للتعبير المحدد لها عند إدراج الصفوف، ويمكن استخدامُها لإنشاء أعمدة جديدة تحتوي على نُسخ مخفية من البيانات. استنادًا إلى المثال السابق، وبدلًا من إنشاء VIEW منفصل للبيانات المخفية، سنُنشئ الآن أعمدة مخفية باستخدام MATERIALIZED:
DROP TABLE IF EXISTS orders;
CREATE TABLE orders (
    user_id UInt32,
    name String,
    name_masked String MATERIALIZED replaceRegexpOne(name, '^([A-Za-z]+)\\s+(.*)$', '\\1 ****'),
    email String,
    email_masked String MATERIALIZED replaceRegexpOne(email, '^(.{0})[^@]*(@.*)$', '\\1****\\2'),
    phone String,
    phone_masked String MATERIALIZED replaceRegexpOne(phone, '^(\\d{3})-(\\d{3})-(\\d{4})$', '\\1-***-\\3'),
    total_amount Decimal(10,2),
    order_date Date,
    shipping_address String,
    shipping_address_masked String MATERIALIZED replaceRegexpOne(shipping_address, '^[^,]+,\\s*(.*)$', '*** \\1')
)
ENGINE = MergeTree()
ORDER BY user_id;

INSERT INTO orders VALUES
    (1001, 'John Smith', 'john.smith@gmail.com', '555-123-4567', 299.99, '2024-01-15', '123 Main St, New York, NY 10001'),
    (1002, 'Sarah Johnson', 'sarah.johnson@outlook.com', '555-987-6543', 149.50, '2024-01-16', '456 Oak Ave, Los Angeles, CA 90210'),
    (1003, 'Michael Brown', 'mbrown@company.com', '555-456-7890', 599.00, '2024-01-17', '789 Pine Rd, Chicago, IL 60601'),
    (1004, 'Emily Rogers', 'emily.rogers@yahoo.com', '555-321-0987', 89.99, '2024-01-18', '321 Elm St, Houston, TX 77001'),
    (1005, 'David Wilson', 'dwilson@email.net', '555-654-3210', 449.75, '2024-01-19', '654 Cedar Blvd, Phoenix, AZ 85001');
إذا نفّذت الآن استعلام SELECT التالي، فسترى أن البيانات المُقنَّعة تصبح ‘مُخزَّنة ماديًا’ وقت الإدراج وتُخزَّن إلى جانب البيانات الأصلية غير المُقنَّعة. ومن الضروري تحديد الأعمدة المُقنَّعة صراحةً، لأن ClickHouse لا يضمّن الأعمدة المُخزَّنة ماديًا تلقائيًا في استعلامات SELECT * افتراضيًا.
Query
SELECT
    *,
    name_masked,
    email_masked,
    phone_masked,
    shipping_address_masked
FROM orders
ORDER BY user_id ASC
Response
   ┌─user_id─┬─name──────────┬─email─────────────────────┬─phone────────┬─total_amount─┬─order_date─┬─shipping_address───────────────────┬─name_masked──┬─email_masked───────┬─phone_masked─┬─shipping_address_masked────┐
1. │    1001 │ John Smith    │ john.smith@gmail.com      │ 555-123-4567 │       299.99 │ 2024-01-15 │ 123 Main St, New York, NY 10001    │ John ****    │ jo****@gmail.com   │ 555-***-4567 │ **** New York, NY 10001    │
2. │    1002 │ Sarah Johnson │ sarah.johnson@outlook.com │ 555-987-6543 │        149.5 │ 2024-01-16 │ 456 Oak Ave, Los Angeles, CA 90210 │ Sarah ****   │ sa****@outlook.com │ 555-***-6543 │ **** Los Angeles, CA 90210 │
3. │    1003 │ Michael Brown │ mbrown@company.com        │ 555-456-7890 │          599 │ 2024-01-17 │ 789 Pine Rd, Chicago, IL 60601     │ Michael **** │ mb****@company.com │ 555-***-7890 │ **** Chicago, IL 60601     │
4. │    1004 │ Emily Rogers  │ emily.rogers@yahoo.com    │ 555-321-0987 │        89.99 │ 2024-01-18 │ 321 Elm St, Houston, TX 77001      │ Emily ****   │ em****@yahoo.com   │ 555-***-0987 │ **** Houston, TX 77001     │
5. │    1005 │ David Wilson  │ dwilson@email.net         │ 555-654-3210 │       449.75 │ 2024-01-19 │ 654 Cedar Blvd, Phoenix, AZ 85001  │ David ****   │ dw****@email.net   │ 555-***-3210 │ **** Phoenix, AZ 85001     │
   └─────────┴───────────────┴───────────────────────────┴──────────────┴──────────────┴────────────┴────────────────────────────────────┴──────────────┴────────────────────┴──────────────┴────────────────────────────┘
لضمان ألا يتمكن المستخدمون من الوصول إلا إلى الأعمدة التي تحتوي على البيانات المخفية، يمكنك استخدام Role Based Access Control مرة أخرى لضمان ألّا تُمنَح أدوار محددة سوى صلاحية select على الأعمدة المقنّعة في orders. أعِد إنشاء الدور الذي أنشأناه سابقًا:
DROP ROLE IF EXISTS masked_order_viewer;
CREATE ROLE masked_order_viewer;
بعد ذلك، امنح صلاحية SELECT على الجدول orders:
GRANT SELECT ON orders TO masked_data_reader;
ألغِ الوصول إلى أي أعمدة حساسة:
REVOKE SELECT(name) ON orders FROM masked_data_reader;
REVOKE SELECT(email) ON orders FROM masked_data_reader;
REVOKE SELECT(phone) ON orders FROM masked_data_reader;
REVOKE SELECT(shipping_address) ON orders FROM masked_data_reader;
أخيرًا، أسنِد الدور إلى المستخدمين المناسبين:
GRANT masked_orders_viewer TO your_user;
إذا كنت تريد تخزين البيانات المخفية فقط في جدول orders، فيمكنك تمييز الأعمدة الحساسة غير المقنّعة بأنها EPHEMERAL، وهذا يضمن عدم تخزين أعمدة من هذا النوع في الجدول.
DROP TABLE IF EXISTS orders;
CREATE TABLE orders (
    user_id UInt32,
    name String EPHEMERAL,
    name_masked String MATERIALIZED replaceRegexpOne(name, '^([A-Za-z]+)\\s+(.*)$', '\\1 ****'),
    email String EPHEMERAL,
    email_masked String MATERIALIZED replaceRegexpOne(email, '^(.{2})[^@]*(@.*)$', '\\1****\\2'),
    phone String EPHEMERAL,
    phone_masked String MATERIALIZED replaceRegexpOne(phone, '^(\\d{3})-(\\d{3})-(\\d{4})$', '\\1-***-\\3'),
    total_amount Decimal(10,2),
    order_date Date,
    shipping_address String EPHEMERAL,
    shipping_address_masked String MATERIALIZED replaceRegexpOne(shipping_address, '^([^,]+),\\s*(.*)$', '*** \\2')
)
ENGINE = MergeTree()
ORDER BY user_id;

INSERT INTO orders (user_id, name, email, phone, total_amount, order_date, shipping_address) VALUES
    (1001, 'John Smith', 'john.smith@gmail.com', '555-123-4567', 299.99, '2024-01-15', '123 Main St, New York, NY 10001'),
    (1002, 'Sarah Johnson', 'sarah.johnson@outlook.com', '555-987-6543', 149.50, '2024-01-16', '456 Oak Ave, Los Angeles, CA 90210'),
    (1003, 'Michael Brown', 'mbrown@company.com', '555-456-7890', 599.00, '2024-01-17', '789 Pine Rd, Chicago, IL 60601'),
    (1004, 'Emily Rogers', 'emily.rogers@yahoo.com', '555-321-0987', 89.99, '2024-01-18', '321 Elm St, Houston, TX 77001'),
    (1005, 'David Wilson', 'dwilson@email.net', '555-654-3210', 449.75, '2024-01-19', '654 Cedar Blvd, Phoenix, AZ 85001');
إذا شغّلنا الاستعلام نفسه كما في السابق، فسترى الآن أن البيانات المخفية المُخزَّنة فعليًا فقط هي التي أُدرِجت في الجدول:
Query
SELECT
    *,
    name_masked,
    email_masked,
    phone_masked,
    shipping_address_masked
FROM orders
ORDER BY user_id ASC
Response
   ┌─user_id─┬─total_amount─┬─order_date─┬─name_masked──┬─email_masked───────┬─phone_masked─┬─shipping_address_masked───┐
1. │    1001 │       299.99 │ 2024-01-15 │ John ****    │ jo****@gmail.com   │ 555-***-4567 │ *** New York, NY 10001    │
2. │    1002 │        149.5 │ 2024-01-16 │ Sarah ****   │ sa****@outlook.com │ 555-***-6543 │ *** Los Angeles, CA 90210 │
3. │    1003 │          599 │ 2024-01-17 │ Michael **** │ mb****@company.com │ 555-***-7890 │ *** Chicago, IL 60601     │
4. │    1004 │        89.99 │ 2024-01-18 │ Emily ****   │ em****@yahoo.com   │ 555-***-0987 │ *** Houston, TX 77001     │
5. │    1005 │       449.75 │ 2024-01-19 │ David ****   │ dw****@email.net   │ 555-***-3210 │ *** Phoenix, AZ 85001     │
   └─────────┴──────────────┴────────────┴──────────────┴────────────────────┴──────────────┴───────────────────────────┘

استخدم قواعد إخفاء الاستعلامات لبيانات السجلات

بالنسبة إلى مستخدمي ClickHouse OSS الذين يرغبون تحديدًا في إخفاء بيانات السجلات، يمكنهم استخدام قواعد إخفاء الاستعلامات (إخفاء السجلات) لإخفاء البيانات. للقيام بذلك، يمكنك تحديد قواعد إخفاء تستند إلى تعبيرات نمطية في تهيئة الخادم. تُطبَّق هذه القواعد على الاستعلامات وجميع رسائل السجل قبل تخزينها في سجلات الخادم أو جداول النظام (مثل system.query_log وsystem.text_log وsystem.processes). يساعد هذا على منع تسرّب البيانات الحساسة إلى السجلات فقط. لاحظ أن هذا لا يُخفي البيانات في نتائج الاستعلام. على سبيل المثال، لإخفاء رقم الضمان الاجتماعي، يمكنك إضافة القاعدة التالية إلى تهيئة الخادم:
<query_masking_rules>
    <rule>
        <name>hide SSN</name>
        <regexp>(^|\D)\d{3}-\d{2}-\d{4}($|\D)</regexp>
        <replace>000-00-0000</replace>
    </rule>
</query_masking_rules>
آخر تعديل في ٢٩ يونيو ٢٠٢٦