Создание секционных таблиц, политик и деталей с помощью OpenEdge SQL
Если вы предпочитаете использовать OpenEdge SQL, то вы можете использовать операторы SQL для работы с секционированием.
Далее мы рассмотрим, как с помощью OpenEdge SQL можно реализовать четыре типа табличного секционирования:
- Секционирование по диапазону
- Секционирование по списку
- Подсекционирование типа List-Range
- Подсекционирование типа List-List
Также вы узнаете, как используя OpenEdge SQL можно создавать секционно-ориентированные локальные индексы.
Секционирование по диапазону
Для создания новой секционированной таблицы, политики секционирования и деталей политики секционирования на основе разделения по диапазону используется команда CREATE TABLE со следующим синтаксисом:
CREATE TABLE table-name PARTITION BY RANGE column-name [USING TABLE AREA area-name] [USING INDEX AREA area-name] [USING LOB AREA area-name] (PARTITION [partition-name1] VALUES <= (const) [area-spec], PARTITION [partition-name2] VALUES <= (const) [area-spec], ...);
Здесь,
const – значение ключа секции, определяющее подмножество строк входящих в секцию. Должно быть заключено в скобки.
area-spec – если необходимо распределить секции по различным физическим устройствам, то укажите область хранения с помощью утверждения USING TABLE | INDEX | LOB AREA для каждой секции.
При использовании SQL-команды CREATE TABLE для создания секций в таблице, OpenEdge автоматически генерирует имя политики секционирования, основываясь на имени таблицы применяя следующий шаблон: table-name_n, где n, является целым числом.
Если не будет указано имя секции, то OpenEdge автоматически сгенерирует имя на основе следующего шаблона: P#-timestamp-usernum#. Например, P#-1440679079-24#.
Пример SQL-кода для создания секционированной таблицы tOrder, разделенной по диапазону на основе значений столбца OrderDate с тремя секциями:
CREATE TABLE "PUB"."tpOrder" ( "OrderNum" integer, "CustNum" integer, "OrderDate" date, "ShipDate" date, "Carrier" varchar (50), "Country" varchar (50), "SalesRep" varchar (10) ) PARTITION BY RANGE "OrderDate" USING TABLE AREA "tpOrderData1" USING INDEX AREA "tpOrderIndex1" USING LOB AREA "tpOrderData1" (PARTITION "tpOrder_2012" VALUES <= ('12/31/2012'), PARTITION "tpOrder_2013" VALUES <= ('12/31/2013'), PARTITION "tpOrder_2014" VALUES <= ('12/31/2014') );
Секционирование по списку
Команда для разделения таблицы на секции с применением секционирования по списку, аналогична команде разделения по диапазону, за исключением того, что вам необходимо заменить параметр RANGE на LIST, и в каждом описании секции заменить VALUES <= на VALUES IN. В следующем примере создается таблица tpOrder с разделением на 3 секции основанных на списке значений столбца Country:
CREATE TABLE "PUB"."tpOrder" ( "OrderNum" integer, "CustNum" integer, "OrderDate" date, "ShipDate" date, "Carrier" varchar (50), "Country" varchar (50), "SalesRep" varchar (10) ) PARTITION BY LIST "Country" USING TABLE AREA "tpOrderData1" USING INDEX AREA "tpOrderIndex1" USING LOB AREA "tpOrderData1" (PARTITION "tpOrder_AUS" VALUES IN ('Australia'), PARTITION "tpOrder_CHN" VALUES IN ('China'), PARTITION "tpOrder_IND" VALUES IN ('India'), );
Подсекционирование типа List-Range
Синтаксис команды для создания подсекционирования типа List-Range следующий:
CREATE TABLE table-name PARTITION BY LIST column-name1 SUBPARTITION BY RANGE column-name2 [USING TABLE AREA area-name] [USING INDEX AREA area-name] [USING LOB AREA area-name] (PARTITION [partition-name1] VALUES <= (const) [area-spec], PARTITION [partition-name2] VALUES <= (const) [area-spec], ...);
Для прочих типов подсекционирования, которые включают секционирование по диапазону, например, list-list-range, list-list-list-range, необходимо добавить утверждение SUBPARTITION BY LIST для каждого списка. При этом помните, утверждение SUBPARTITION BY RANGE всегда должно быть последним.
Для каждой подсекции, содержащей диапазон, для установки значения секционных столбцов применяется VALUES <=.
Следующий пример демонстрирует SQL-код для создания таблицы tpOrder с применением подсекционирования типа list-range на основе полей Carrier и Order и двух секций:
CREATE TABLE "PUB"."tpOrder" ( "OrderNum" integer, "CustNum" integer, "OrderDate" date, "ShipDate" date, "Carrier" varchar (50), "Country" varchar (50), "SalesRep" varchar (10) ) PARTITION BY LIST "Carrier" SUBPARTITION BY RANGE "OrderDate" USING TABLE AREA "tpOrderData1" USING INDEX AREA "tpOrderIndex1" USING LOB AREA "tpOrderData1" (PARTITION "tpOrder_StandardMail_2014" VALUES <= ('Standard Mail','12/31/2014'), PARTITION "tpOrder_FlyByNight_Cour_2014" VALUES <= ('FlyByNight Courier','12/31/2014'), );
Подсекционирование типа List-List
Команда для создания подсекционирования типа list-list отличается от подсекционирования list-range тем, что вместо RANGE используется LIST, а для идентификации значений секций вместо VALUES <= применяется VALUES IN.
Для прочих типов секционирования на основе списков, list-list-list, list-list-list-list и т.д., просто добавьте утверждение SUBPARTITION BY LIST для каждой подсекции.
Следующий пример демонстрирует создание таблицы tpOrder с разбиением на 3 секции на основе полей Carrier и Country.
CREATE TABLE "PUB"."tpOrder" ( "OrderNum" integer, "CustNum" integer, "OrderDate" date, "ShipDate" date, "Carrier" varchar (50), "Country" varchar (50), "SalesRep" varchar (10) ) PARTITION BY LIST "Carrier" SUBPARTITION BY LIST "Country" USING TABLE AREA "tpOrderData1" USING INDEX AREA "tpOrderIndex1" USING LOB AREA "tpOrderData1" PARTITION "tpOrder_StandardMail_JPN" VALUES IN ('Standard Mail','Japan'), PARTITION "tpOrder_FlyByNight_Courier_JPN" VALUES IN ('FlyByNight Courier','Japan'), PARTITION "tpOrder_WalkersDelivery_JPN" VALUES IN ('Walkers Delivery','Japan') );
Создание локального индекса
Как вы уже знаете, каждая таблица должна иметь первичный уникальный глобальный индекс, а каждая секционированная таблица должна иметь минимум один локальный индекс, который использует ключ секции в качестве лидирующего компонента.
Команда создания первичного уникального глобального индекса и её синтаксис аналогичны команде создания такого индекса для обычной таблицы. СУБД OpenEdge автоматически создаст локальный индекс, если в качестве лидирующего компонента этого индекса вы используете ключ секции.
Также, как и глобальные индексы, локальные могут быть уникальными или не уникальными.
Представьте, что вам необходимо создать секционированную таблицу, в которой применяется подсекционирование list-range, которое использует ключ секции на основе столбцов Carrier и OrderDate.
Следующий пример демонстрирует создание локального не уникального индекса CarrierDataLocalIdx на основе столбцов Carrier и OrderDate:
CREATE INDEX "CarrierDateLocalIdx" on "PUB"."tpOrder" ("Carrier", "OrderDate");
Во втором примере мы создаем локальный уникальный индекс CarrierDataNumLocalIdx на основе столбцов Carrier, OrderDate и OrderNum:
CREATE UNIQUE INDEX "CarrierDateNumLocalIdx" on "PUB"."tpOrder" ("Carrier", "OrderDate", "OrderNum");