الانتقال إلى المحتوى الرئيسي
نوع تعدادي يتكوّن من قيم مسمّاة. يمكن تعريف القيم المسمّاة على شكل أزواج من 'string' = integer أو كأسماء 'string'. لا يخزّن ClickHouse سوى الأرقام، لكنه يدعم إجراء العمليات على هذه القيم عبر أسمائها. يدعم ClickHouse ما يلي:
  • Enum ذو 8 بتات. يمكن أن يحتوي على ما يصل إلى 256 قيمة معدّدة ضمن النطاق [-128, 127].
  • Enum ذو 16 بتًا. يمكن أن يحتوي على ما يصل إلى 65536 قيمة معدّدة ضمن النطاق [-32768, 32767].
يختار ClickHouse تلقائيًا نوع Enum عند إدراج البيانات. ويمكنك أيضًا استخدام النوعين Enum8 أو Enum16 للتأكّد من حجم التخزين.

أمثلة الاستخدام

ننشئ هنا جدولًا يتضمن عمودًا من النوع Enum8('hello' = 1, 'world' = 2):
CREATE TABLE t_enum
(
    x Enum('hello' = 1, 'world' = 2)
)
ENGINE = TinyLog
وبالمثل، يمكنك حذف الأرقام. سيُعيّن ClickHouse أرقامًا متتالية تلقائيًا. تُعيَّن الأرقام بدءًا من 1 افتراضيًا.
CREATE TABLE t_enum
(
    x Enum('hello', 'world')
)
ENGINE = TinyLog
يمكنك أيضًا تحديد رقم بداية مسموح به للاسم الأول.
CREATE TABLE t_enum
(
    x Enum('hello' = 1, 'world')
)
ENGINE = TinyLog
CREATE TABLE t_enum
(
    x Enum8('hello' = -129, 'world')
)
ENGINE = TinyLog
Exception on server:
Code: 69. DB::Exception: Value -129 for element 'hello' exceeds range of Enum8.
لا يمكن للعمود x تخزين سوى القيم المدرجة في تعريف النوع: 'hello' أو 'world'. إذا حاولت حفظ أي قيمة أخرى، فسيُصدر ClickHouse استثناءً. يُختار حجم 8 بت لهذا Enum تلقائيًا.
INSERT INTO t_enum VALUES ('hello'), ('world'), ('hello')
Ok.
INSERT INTO t_enum VALUES('a')
Exception on client:
Code: 49. DB::Exception: Unknown element 'a' for type Enum('hello' = 1, 'world' = 2)
عند الاستعلام عن البيانات من الجدول، يعرض ClickHouse القيم النصية من Enum.
SELECT * FROM t_enum
┌─x─────┐
│ hello │
│ world │
│ hello │
└───────┘
إذا كنت بحاجة إلى رؤية القيم الرقمية المقابلة للصفوف، فيجب تحويل قيمة Enum إلى نوع عدد صحيح.
SELECT CAST(x, 'Int8') FROM t_enum
┌─CAST(x, 'Int8')─┐
│               1 │
│               2 │
│               1 │
└─────────────────┘
لإنشاء قيمة من النوع Enum في استعلام، تحتاج أيضًا إلى استخدام CAST.
SELECT toTypeName(CAST('a', 'Enum(\'a\' = 1, \'b\' = 2)'))
┌─toTypeName(CAST('a', 'Enum(\'a\' = 1, \'b\' = 2)'))─┐
│ Enum8('a' = 1, 'b' = 2)                             │
└─────────────────────────────────────────────────────┘

القواعد العامة والاستخدام

يُسند إلى كل قيمة رقم ضمن النطاق -128 ... 127 في Enum8 أو ضمن النطاق -32768 ... 32767 في Enum16. ويجب أن تكون جميع السلاسل والأرقام مختلفة. ويُسمح بسلسلة فارغة. إذا حُدِّد هذا النوع (في تعريف جدول)، فيمكن أن تأتي الأرقام بأي ترتيب. ومع ذلك، لا يهم الترتيب. لا يمكن أن تكون السلسلة ولا القيمة الرقمية في Enum هي NULL. يمكن أن يكون Enum ضمن النوع Nullable. لذا، إذا أنشأت جدولًا باستخدام الاستعلام
CREATE TABLE t_enum_nullable
(
    x Nullable( Enum8('hello' = 1, 'world' = 2) )
)
ENGINE = TinyLog
يمكنه تخزين ليس 'hello' و'world' فقط، بل NULL أيضًا.
INSERT INTO t_enum_nullable VALUES('hello'),('world'),(NULL)
في RAM، يُخزَّن عمود Enum بالطريقة نفسها التي تُخزَّن بها Int8 أو Int16 للقيم الرقمية المقابلة. عند القراءة بصيغة نصية، يحلّل ClickHouse القيمة كسلسلة نصية ويبحث عن السلسلة المقابلة ضمن مجموعة قيم Enum. وإذا لم يعثر عليها، يُطرَح استثناء. عند القراءة بتنسيق نصي، تُقرأ السلسلة النصية ويُبحث عن القيمة الرقمية المقابلة لها. ويُطرَح استثناء إذا لم يتم العثور عليها. عند الكتابة بصيغة نصية، تُكتب القيمة على شكل السلسلة النصية المقابلة. وإذا كانت بيانات الأعمدة تحتوي على قيم غير صالحة (أرقام لا تنتمي إلى المجموعة المسموح بها)، يُطرَح استثناء. وعند القراءة والكتابة بالصيغة الثنائية، يعمل ذلك بالطريقة نفسها كما في نوعَي البيانات Int8 وInt16. القيمة الافتراضية الضمنية هي القيمة ذات الرقم الأصغر. أثناء ORDER BY وGROUP BY وIN وDISTINCT وما إلى ذلك، تتصرف قيم Enum بالطريقة نفسها مثل الأرقام المقابلة. فعلى سبيل المثال، يقوم ORDER BY بفرزها رقميًا. كما تعمل معاملات المساواة والمقارنة على قيم Enum بالطريقة نفسها التي تعمل بها على القيم الرقمية الأساسية. لا يمكن مقارنة قيم Enum بالأرقام. ويمكن مقارنة قيم Enum بسلسلة نصية ثابتة. وإذا لم تكن السلسلة النصية المُقارَن بها قيمة صالحة لـ Enum، فسيُطرَح استثناء. المعامل IN مدعوم عندما يكون Enum في الطرف الأيسر ومجموعة من السلاسل النصية في الطرف الأيمن. وتمثل هذه السلاسل النصية قيم Enum المقابلة. معظم العمليات الرقمية والنصية غير معرّفة لقيم Enum، مثل إضافة رقم إلى Enum أو ربط سلسلة نصية مع Enum. ومع ذلك، يوفّر Enum دالة toString طبيعية تُرجع قيمته النصية. يمكن أيضًا تحويل قيم Enum إلى أنواع رقمية باستخدام الدالة toT، حيث إن T نوع رقمي. وعندما تتوافق T مع النوع الرقمي الأساسي لـ enum، يكون هذا التحويل بلا تكلفة. يمكن تغيير نوع Enum بلا تكلفة باستخدام ALTER إذا جرى تغيير مجموعة القيم فقط. ومن الممكن إضافة أعضاء Enum وإزالتهم باستخدام ALTER (تكون الإزالة آمنة فقط إذا لم تُستخدم القيمة المُزالة مطلقًا في الجدول). وكإجراء احترازي، فإن تغيير القيمة الرقمية لعضو Enum معرّف مسبقًا سيؤدي إلى طرح استثناء. وباستخدام ALTER، يمكن تغيير Enum8 إلى Enum16 أو العكس، تمامًا كما عند تغيير Int8 إلى Int16.

إضافة قيم إلى enum

يوجد اختصار نحوي لإضافة قيم جديدة إلى enum باستخدام ALTER MODIFY COLUMN ADD ENUM VALUES
CREATE TABLE enum
(
    x Enum('One' = 1, 'Two', 'Three')
) ENGINE = Memory;
ALTER TABLE enum MODIFY COLUMN x ADD ENUM VALUES ('Zero' = 0, 'Four' = 4);
SHOW CREATE TABLE enum;
┌─statement────────────────────────────────────────────────────────────────┐
│CREATE TABLE default.enum                                                 │
│(                                                                         │
│    `x` Enum8('Zero' = 0, 'One' = 1, 'Two' = 2, 'Three' = 3, 'Four' = 4)  │
│)                                                                         │
│ENGINE = Memory                                                           │
└──────────────────────────────────────────────────────────────────────────┘
آخر تعديل في ٢٥ يونيو ٢٠٢٦