توزيع وتعديل الجداول

توزيع الجداول

لإنشاء جدول موزع، تحتاج أولا إلى تعريف مخطط الجدول. للقيام بذلك، يمكنك تعريف جدول باستخدام عبارة إنشاء جدول بنفس الطريقة التي تفعل بها مع جدول PostgreSQL عادي.

CREATE TABLE github_events
(
    event_id bigint,
    event_type text,
    event_public boolean,
    repo_id bigint,
    payload jsonb,
    repo jsonb,
    actor jsonb,
    org jsonb,
    created_at timestamp
);

بعد ذلك، يمكنك استخدام الدالة create_distributed_table() لتحديد عمود توزيع الجدول وإنشاء شظايا العامل.

SELECT create_distributed_table('github_events', 'repo_id');

يقوم استدعاء الدالة بإعلام Hyperscale (Citus) بأنه يجب توزيع جدول github_events على العمود repo_id (عن طريق تجزئة قيمة العمود).

يقوم بإنشاء ما مجموعه 32 شظية بشكل افتراضي ، حيث تمتلك كل شظية جزءا من مساحة التجزئة ويتم نسخها استنادا إلى قيمة تكوين citus.shard_replication_factor الافتراضية. تحتوي النسخ المتماثلة للشارد التي تم إنشاؤها على العامل على نفس تعريفات مخطط الجدول والفهرس والقيد مثل الجدول الموجود على المنسق. بمجرد إنشاء النسخ المتماثلة ، تحفظ الوظيفة جميع البيانات الوصفية الموزعة على المنسق.

يتم تعيين معرف شارد فريد لكل شارد تم إنشاؤه وجميع النسخ المتماثلة لها نفس معرف شارد. يتم تمثيل الشظايا على عقدة العامل كجداول PostgreSQL عادية تسمى "tablename_shardid" حيث يكون اسم الجدول هو اسم الجدول الموزع ، ومعرف شارد هو المعرف الفريد المعين. يمكنك الاتصال بمثيلات postgres العاملة لعرض الأوامر أو تشغيلها على شظايا فردية.

أنت الآن جاهز لإدراج البيانات في الجدول الموزع وتشغيل الاستعلامات عليه. يمكنك أيضا معرفة المزيد حول UDF المستخدم في هذا القسم في الجدول ومرجع shard DDL .

الجداول المرجعية

تقوم الطريقة المذكورة أعلاه بتوزيع الجداول إلى شظايا أفقية متعددة. هناك احتمال آخر هو توزيع الجداول في قطعة واحدة وتكرار الشظايا على كل عقدة عامل. تسمى الجداول الموزعة بهذه الطريقة الجداول المرجعية. يتم استخدامها لتخزين البيانات التي تحتاج إلى الوصول إليها بشكل متكرر بواسطة عقد متعددة في مجموعة.

تشمل المرشحات الشائعة للجداول المرجعية ما يلي:

  • الجداول الأصغر التي تحتاج إلى الانضمام إلى الجداول الموزعة الأكبر.
  • الجداول في التطبيقات متعددة المستأجرين التي تفتقر إلى عمود معرف المستأجر أو غير المقترنة بمستأجر. (أو، أثناء الترحيل، حتى بالنسبة لبعض الجداول المقترنة بمستأجر.)
  • الجداول التي تحتاج إلى قيود فريدة عبر أعمدة متعددة وصغيرة بما فيه الكفاية.

على سبيل المثال ، لنفترض أن موقع التجارة الإلكترونية متعدد المستأجرين يحتاج إلى حساب ضريبة المبيعات للمعاملات في أي من متاجره. المعلومات الضريبية ليست خاصة بأي مستأجر. من المنطقي وضعه في جدول مشترك. قد يبدو الجدول المرجعي الذي يركز على الولايات المتحدة كما يلي:

-- a reference table

CREATE TABLE states (
  code char(2) PRIMARY KEY,
  full_name text NOT NULL,
  general_sales_tax numeric(4,3)
);

-- distribute it to all workers

SELECT create_reference_table('states');

الآن يمكن أن تنضم الاستعلامات مثل ضريبة حساب واحدة لعربة التسوق إلى الطاولة بدون نفقات عامة على states الشبكة ، ويمكن أن تضيف مفتاحا خارجيا إلى رمز الولاية للتحقق بشكل أفضل.

بالإضافة إلى توزيع جدول كشظية واحدة مكررة، يقوم create_reference_table UDF بتمييزه كجدول مرجعي في جداول بيانات تعريف Hyperscale (Citus). يقوم Hyperscale (Citus) تلقائيا بتنفيذ التزامات على مرحلتين (2PC) لإجراء تعديلات على الجداول المميزة بهذه الطريقة ، مما يوفر ضمانات اتساق قوية.

للحصول على مثال آخر لاستخدام الجداول المرجعية، راجع البرنامج التعليمي لقاعدة البيانات متعددة المستأجرين.

توزيع بيانات المنسق

إذا تم تحويل قاعدة بيانات PostgreSQL موجودة إلى عقدة المنسق لمجموعة Hyperscale (Citus)، يمكن توزيع البيانات الموجودة في جداولها بكفاءة وبأقل قدر من الانقطاع على أحد التطبيقات.

تعمل الدالة create_distributed_table الموضحة سابقا على كل من الجداول الفارغة وغير الفارغة ، وبالنسبة للأخير ، تقوم تلقائيا بتوزيع صفوف الجدول في جميع أنحاء المجموعة. ستعرف ما إذا كان ينسخ البيانات من خلال وجود الرسالة ، "إشعار: نسخ البيانات من الجدول المحلي ..." على سبيل المثال:

CREATE TABLE series AS SELECT i FROM generate_series(1,1000000) i;
SELECT create_distributed_table('series', 'i');
NOTICE:  Copying data from local table...
 create_distributed_table
 --------------------------

 (1 row)

يتم حظر عمليات الكتابة على الجدول أثناء ترحيل البيانات، ويتم التعامل مع عمليات الكتابة المعلقة كاستعلامات موزعة بمجرد التزام الدالة. (إذا فشلت الدالة ، فستصبح الاستعلامات محلية مرة أخرى.) يمكن أن تستمر عمليات القراءة كالمعتاد وستصبح استعلامات موزعة بمجرد التزام الوظيفة.

عند توزيع الجدولين A و B، حيث يحتوي A على مفتاح خارجي إلى B، قم بتوزيع جدول الوجهة الرئيسية B أولا. سيؤدي القيام بذلك بترتيب خاطئ إلى حدوث خطأ:

ERROR:  cannot create foreign key constraint
DETAIL:  Referenced table must be a distributed table or a reference table.

إذا لم يكن من الممكن التوزيع بالترتيب الصحيح ، فقم بإسقاط المفاتيح الخارجية وتوزيع الجداول وإعادة إنشاء المفاتيح الخارجية.

عند ترحيل البيانات من قاعدة بيانات خارجية، مثل من Amazon RDS إلى Hyperscale (Citus) Cloud، قم أولا بإنشاء الجداول الموزعة Hyperscale (Citus) عبر create_distributed_table، ثم انسخ البيانات إلى الجدول. يؤدي النسخ إلى جداول موزعة إلى تجنب نفاد المساحة الموجودة على عقدة المنسق.

طاولات التجميع

التجميع يعني وضع المعلومات ذات الصلة على نفس الآلات. فهو يتيح الاستعلامات الفعالة، مع الاستفادة من قابلية التوسع الأفقي لمجموعة البيانات بأكملها. لمزيد من المعلومات، راجع الموقع المشترك.

توجد الجداول في مجموعات. للتحكم يدويا في تعيين مجموعة الموقع المشترك للجدول، استخدم المعلمة create_distributed_tableالاختيارية colocate_with . إذا كنت لا تهتم بالموقع المشترك للجدول ، فقم بحذف هذه المعلمة. يتم تعيينه افتراضيا إلى القيمة 'default'، التي تجمع الجدول مع أي جدول موقع مشترك افتراضي آخر له نفس نوع عمود التوزيع وعدد القطع وعامل النسخ المتماثل. إذا كنت ترغب في كسر أو تحديث هذا الموقع المشترك الضمني ، فيمكنك استخدام update_distributed_table_colocation().

-- these tables are implicitly co-located by using the same
-- distribution column type and shard count with the default
-- co-location group

SELECT create_distributed_table('A', 'some_int_col');
SELECT create_distributed_table('B', 'other_int_col');

عندما لا يكون جدول جديد مرتبطا بالآخرين في مجموعة التجميع الضمنية المحتملة الخاصة به، حدد colocated_with => 'none'.

-- not co-located with other tables

SELECT create_distributed_table('A', 'foo', colocate_with => 'none');

سيؤدي تقسيم الجداول غير ذات الصلة إلى مجموعات التجميع الخاصة بها إلى تحسين أداء إعادة توازن الشظايا ، لأنه يجب نقل الشظايا في نفس المجموعة معا.

عندما تكون الجداول مرتبطة بالفعل (على سبيل المثال متى سيتم ضمها) ، قد يكون من المنطقي تحديد موقعها بشكل صريح. إن مكاسب التوطين المناسب أكثر أهمية من أي إعادة توازن النفقات العامة.

لتنسيق جداول متعددة بشكل صريح، قم بتوزيع واحد ثم ضع الجداول الأخرى في مجموعة الموقع المشترك الخاصة به. على سبيل المثال:

-- distribute stores
SELECT create_distributed_table('stores', 'store_id');

-- add to the same group as stores
SELECT create_distributed_table('orders', 'store_id', colocate_with => 'stores');
SELECT create_distributed_table('products', 'store_id', colocate_with => 'stores');

يتم تخزين معلومات حول مجموعات الموقع المشترك في جدول pg_dist_colocation ، بينما تكشف pg_dist_partition عن الجداول التي تم تعيينها للمجموعات.

إسقاط الجداول

يمكنك استخدام الأمر PostgreSQL Drop TABLE القياسي لإزالة الجداول الموزعة. كما هو الحال مع الجداول العادية، يزيل DROP TABLE أي فهارس وقواعد ومشغلات وقيود موجودة للجدول الهدف. بالإضافة إلى ذلك ، فإنه يسقط أيضا الشظايا على عقد العمال وينظف بياناتهم الوصفية.

DROP TABLE github_events;

تعديل الجداول

يقوم Hyperscale (Citus) تلقائيا بنشر العديد من أنواع عبارات DDL. سيؤدي تعديل جدول موزع على عقدة المنسق إلى تحديث الشظايا على العمال أيضا. تتطلب عبارات DDL الأخرى الانتشار اليدوي ، ويحظر بعض البيانات الأخرى مثل أي بيانات من شأنها تعديل عمود توزيع. ستؤدي محاولة تشغيل DDL غير المؤهل للانتشار التلقائي إلى حدوث خطأ وترك الجداول على عقدة المنسق دون تغيير.

فيما يلي مرجع لفئات بيانات DDL التي تنشر.

إضافة/تعديل الأعمدة

يقوم Hyperscale (Citus) بنشر معظم أوامر ALTER TABLE تلقائيا. تعمل إضافة أعمدة أو تغيير قيمها الافتراضية كما تفعل في قاعدة بيانات PostgreSQL أحادية الجهاز:

-- Adding a column

ALTER TABLE products ADD COLUMN description text;

-- Changing default value

ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;

التغييرات الكبيرة على عمود موجود مثل إعادة تسميته أو تغيير نوع البيانات الخاص به جيدة أيضا. ومع ذلك لا يمكن تغيير نوع البيانات لعمود التوزيع . يحدد هذا العمود كيفية توزيع بيانات الجدول من خلال الكتلة Hyperscale (Citus)، ويتطلب تعديل نوع البيانات الخاص به نقل البيانات.

تؤدي محاولة القيام بذلك إلى حدوث خطأ:

-- assumining store_id is the distribution column
-- for products, and that it has type integer

ALTER TABLE products
ALTER COLUMN store_id TYPE text;

/*
ERROR:  XX000: cannot execute ALTER TABLE command involving partition column
LOCATION:  ErrorIfUnsupportedAlterTableStmt, multi_utility.c:2150
*/

إضافة/إزالة القيود

يتيح لك استخدام Hyperscale (Citus) الاستمرار في الاستمتاع بأمان قاعدة البيانات العلائقية ، بما في ذلك قيود قاعدة البيانات (راجع مستندات PostgreSQL). نظرا لطبيعة الأنظمة الموزعة ، لن يقوم Hyperscale (Citus) بالإشارة إلى قيود التفرد أو التكامل المرجعي بين عقد العاملين.

لإعداد مفتاح خارجي بين الجداول الموزعة في وضع مشترك، قم دائما بتضمين عمود التوزيع في المفتاح. بما في ذلك عمود التوزيع قد ينطوي على صنع المركب الرئيسي.

قد يتم إنشاء مفاتيح خارجية في هذه الحالات:

  • بين جدولين محليين (غير موزعين) ،
  • بين جدولين مرجعيين،
  • بين جدولين موزعين في وضع واحد عندما يتضمن المفتاح عمود التوزيع، أو
  • كجدول موزع يشير إلى جدول مرجعي

المفاتيح الخارجية من الجداول المرجعية إلى الجداول الموزعة غير مدعومة.

ملاحظة

يجب أن تتضمن المفاتيح الأساسية وقيود التفرد عمود التوزيع. ستؤدي إضافتها إلى عمود غير توزيعي إلى حدوث خطأ

يوضح هذا المثال كيفية إنشاء مفاتيح أساسية وخارجية على الجداول الموزعة:

--
-- Adding a primary key
-- --------------------

-- We'll distribute these tables on the account_id. The ads and clicks
-- tables must use compound keys that include account_id.

ALTER TABLE accounts ADD PRIMARY KEY (id);
ALTER TABLE ads ADD PRIMARY KEY (account_id, id);
ALTER TABLE clicks ADD PRIMARY KEY (account_id, id);

-- Next distribute the tables

SELECT create_distributed_table('accounts', 'id');
SELECT create_distributed_table('ads',      'account_id');
SELECT create_distributed_table('clicks',   'account_id');

--
-- Adding foreign keys
-- -------------------

-- Note that this can happen before or after distribution, as long as
-- there exists a uniqueness constraint on the target column(s) which
-- can only be enforced before distribution.

ALTER TABLE ads ADD CONSTRAINT ads_account_fk
  FOREIGN KEY (account_id) REFERENCES accounts (id);
ALTER TABLE clicks ADD CONSTRAINT clicks_ad_fk
  FOREIGN KEY (account_id, ad_id) REFERENCES ads (account_id, id);

وبالمثل، قم بتضمين عمود التوزيع في قيود التفرد:

-- Suppose we want every ad to use a unique image. Notice we can
-- enforce it only per account when we distribute by account id.

ALTER TABLE ads ADD CONSTRAINT ads_unique_image
  UNIQUE (account_id, image_url);

يمكن تطبيق قيود غير فارغة على أي عمود (توزيع أم لا) لأنها لا تتطلب أي عمليات بحث بين العمال.

ALTER TABLE ads ALTER COLUMN image_url SET NOT NULL;

استخدام قيود غير صالحة

في بعض الحالات، قد يكون من المفيد فرض قيود على الصفوف الجديدة، مع السماح للصفوف الحالية غير المطابقة بالبقاء دون تغيير. يدعم Hyperscale (Citus) هذه الميزة لقيود CHECK والمفاتيح الخارجية ، باستخدام تعيين القيد "غير صالح" الخاص ب PostgreSQL.

على سبيل المثال، ضع في اعتبارك تطبيقا يخزن ملفات تعريف المستخدمين في جدول مرجعي.

-- we're using the "text" column type here, but a real application
-- might use "citext" which is available in a postgres contrib module

CREATE TABLE users ( email text PRIMARY KEY );
SELECT create_reference_table('users');

مع مرور الوقت تخيل أن بعض العناوين غير الواردة تدخل في الجدول.

INSERT INTO users VALUES
   ('foo@example.com'), ('hacker12@aol.com'), ('lol');

نود التحقق من صحة العناوين ، لكن PostgreSQL لا يسمح لنا عادة بإضافة قيد CHECK يفشل في الصفوف الموجودة. ومع ذلك ، فإنه يسمح بقيد تم وضع علامة عليه غير صالح:

ALTER TABLE users
ADD CONSTRAINT syntactic_email
CHECK (email ~
   '^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$'
) NOT VALID;

الصفوف الجديدة محمية الآن.

INSERT INTO users VALUES ('fake');

/*
ERROR:  new row for relation "users_102010" violates
        check constraint "syntactic_email_102010"
DETAIL:  Failing row contains (fake).
*/

في وقت لاحق، خلال ساعات غير الذروة، يمكن لمسؤول قاعدة البيانات محاولة إصلاح الصفوف التالفة وإعادة التحقق من صحة القيد.

-- later, attempt to validate all rows
ALTER TABLE users
VALIDATE CONSTRAINT syntactic_email;

تحتوي وثائق PostgreSQL على مزيد من المعلومات حول غير صالح والتحقق من صحة القيد في المقطع ALTER TABLE .

إضافة/إزالة المؤشرات

يدعم Hyperscale (Citus) إضافة المؤشرات وإزالتها:

-- Adding an index

CREATE INDEX clicked_at_idx ON clicks USING BRIN (clicked_at);

-- Removing an index

DROP INDEX clicked_at_idx;

تتطلب إضافة فهرس قفلا للكتابة، والذي يمكن أن يكون غير مرغوب فيه في "نظام السجلات" متعدد المستأجرين. لتقليل وقت تعطل التطبيق، قم بإنشاء الفهرس بشكل متزامن بدلا من ذلك. تتطلب هذه الطريقة عملا إجماليا أكثر من إنشاء فهرس قياسي وتستغرق وقتا أطول لإكمالها. ومع ذلك ، نظرا لأنه يسمح باستمرار العمليات العادية أثناء إنشاء الفهرس ، فإن هذه الطريقة مفيدة لإضافة فهارس جديدة في بيئة الإنتاج.

-- Adding an index without locking table writes

CREATE INDEX CONCURRENTLY clicked_at_idx ON clicks USING BRIN (clicked_at);