CREATE TABLE

CREATE TABLE — создать таблицу

Синтаксис

CREATE [ UNLOGGED ] TABLE [ IF NOT EXISTS ] имя_таблицы ( [
  { имя_столбца тип_данных [ COLLATE правило_сортировки ] [ ограничение_столбца [ ... ] ]
    | ограничение_таблицы }
    [, ... ]
] )
[ USING метод ]
[ WITH ( параметр_хранения [= значение] [, ... ] ) ]
[ TABLESPACE табл_пространство ]

CREATE TABLE имя_таблицы ( [
  { имя_столбца тип_данных }
    [, ... ]
] )
WITH ( { распределение_по = 'имя_столбца'
         [, число_секций = число_секций ]
         [, сочетать_с = 'имя_табл_совм_размещения' ]
         [, секционирование_по = 'имя_столбца',
            границы_секции = 'массив_выражений_границ_секций' ] |
         глобальный }
)

Здесь ограничение_столбца:

[ CONSTRAINT имя_ограничения ]
{ NOT NULL |
  NULL |
  CHECK ( выражение ) [ NO INHERIT ] |
  DEFAULT выражение_по_умолчанию |
  UNIQUE параметры_индекса |
  PRIMARY KEY параметры_индекса }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

и ограничение_таблицы:

[ CONSTRAINT имя_ограничения ]
{ CHECK ( выражение ) [ NO INHERIT ] |
  UNIQUE ( имя_столбца [, ... ] ) параметры_индекса |
  PRIMARY KEY ( имя_столбца [, ... ] ) параметры_индекса |
  EXCLUDE [ USING индексный_метод ] ( элемент_исключения WITH оператор [, ... ] ) параметры_индекса [ WHERE ( предикат ) ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

Описание

Расширение Shardman синтаксиса CREATE TABLE позволяет создавать сегментированные таблицы, распределённые по всем группам репликации, используя один оператор DDL.

Расширенный синтаксис CREATE TABLE накладывает ограничения на общий синтаксис команды. Например, в настоящее время нет поддержки для:

  • Последовательных псевдотипов, отличных от SERIAL8 и BIGSERIAL.

  • Генерируемых столбцов.

  • Ограничений REFERENCES и FOREIGN KEY между несовмещёнными сегментированными таблицами.

  • Предложений PARTITION BY и PARTITION OF.

При создании совмещённой таблицы следует помнить о соответствующих ограничениях. В частности, из этих ограничений следует, что внешний ключ в глобальной или сегментированной таблице может поддерживаться, только если он ссылается на кортежи, которые хранятся в той же группе репликации. Это приводит к следующим ограничениям: внешний ключ в глобальной таблице может ссылаться только на другую глобальную таблицу, внешний ключ в сегментированной таблице может ссылаться на совмещённую сегментированную таблицу или глобальную таблицу. Обратите внимание, что когда внешний ключ в сегментированной или глобальной таблице ссылается на глобальную таблицу, поддерживаются только ссылочные действия NO ACTION или RESTRICT для действия ON UPDATE, а для ON DELETE — только действия NO ACTION, RESTRICT или CASCADE.

Столбцы типа SERIAL8 реализованы с использованием автоматически созданной глобальной последовательности, поэтому здесь также применяются все свойства глобальной последовательности. (Подробности описаны в Раздел 7.6.)

Параметры

Параметры хранения

Shardman расширяет параметры хранения таблиц собственными метапараметрами хранения. Они не сохраняются в соответствующей записи каталога, а используются для указания расширению Shardman выполнить некоторые дополнительные действия. Обычные параметры хранения прозрачно передаются секциям таблицы.

distributed_by (text)

Указывает имя столбца, используемого для секционирования таблицы. В настоящее время поддерживается только разбиение по хешу, так что оно эквивалентно PARTITION BY HASH, но все конечные секции будут созданы немедленно во всех группах репликации, а таблица будет зарегистрирована в метаданных Shardman.

num_parts (integer)

Устанавливает количество секций, которые будут созданы для этой таблицы. Этот параметр является необязательным. Если он не указан, по умолчанию будет использоваться значение глобального параметра shardman.num_parts.

colocate_with (text)

Указывает имя таблицы, с которой будет выполнено совмещение. Если установлено, Shardman попытается разместить секции созданной таблицы с тем же ключом секции на тех же узлах, что и имя_табл_совм_размещения. Этот параметр является необязательным.

partition_by (text)

Указывает имя столбца, используемого для секционирования таблицы второго уровня. В настоящее время поддерживается только секционирование по диапазонам. При использовании этого параметра каждая секция таблицы создаётся как секционированная таблица. Подсекции могут быть созданы сразу, если установлен параметр границы_секции. Этот параметр является необязательным.

partition_bounds (text)

Устанавливает границы секций таблицы второго уровня. Границы должны быть строковым представлением двумерного массива. Каждый элемент массива представляет собой пару нижней и верхней границ секций. Если и нижняя, и верхняя границы равны NULL, создаётся стандартная секция. Количество секций определяется первым измерением массива. Этот параметр является необязательным.

global (boolean)

Определяет, что таблица является глобальной. Если этот параметр задан, таблица будет распределена по всем группам репликации и будет синхронизироваться триггерами. Этот параметр является необязательным.

Примеры

В данном примере создаётся таблица pgbench_branches, а также совмещённые таблицы pgbench_accounts и pgbench_history. Каждая секция таблицы pgbench_history дополнительно разбивается на секции по диапазону.

CREATE TABLE pgbench_branches (
       bid integer NOT NULL PRIMARY KEY,
       bbalance integer,
       filler character(88)
)
WITH (distributed_by = 'bid',
      num_parts = 8);
CREATE TABLE pgbench_accounts (
       aid integer NOT NULL,
       bid integer,
       abalance integer,
       filler character(84),
       PRIMARY KEY (bid, aid)
)
WITH (distributed_by = 'bid',
      num_parts = 8,
      colocate_with = 'pgbench_branches');
CREATE TABLE public.pgbench_history (
            tid integer,
            bid integer,
            aid integer,
            delta integer,
            mtime timestamp without time zone,
            filler character(22)
        )
WITH (distributed_by = 'bid',
      colocate_with = 'pgbench_branches',
      partition_by = 'mtime',
      partition_bounds =
          $${{minvalue, '2021-01-01 00:00'},{'2021-01-01 00:00', '2022-01-01 00:00'},{'2022-01-01 00:00', maxvalue}}$$
);

В следующих примерах команды CREATE TABLE показаны ограничения, связанные с созданием совмещённых таблиц:

Эта команда создаёт таблицу для совместного размещения:

CREATE TABLE teams_players (
       team_id integer NOT NULL,
       player_id integer,
       scores int,
       PRIMARY KEY (team_id, player_id)
) WITH (distributed_by='team_id, player_id');

Следующая команда корректно создаёт совмещённую таблицу:

CREATE TABLE players_scores (
       player_id integer NOT NULL,
       team_id integer,
       interval tstzrange,
       scores integer,
       foreign key (team_id, player_id) references teams_players(team_id, player_id)
) WITH (distributed_by='team_id, player_id', colocate_with='teams_players');

А следующая команда содержит ошибку в определении внешнего ключа:

CREATE TABLE players_scores (
       player_id integer NOT NULL,
       team_id integer,
       interval tstzrange,
       scores integer,
       foreign key (team_id, player_id) references teams_players(team_id, player_id)
) WITH (distributed_by='player_id, team_id', colocate_with='teams_players');
ERROR:  foreign key should start with distributed_by columns

Рассмотрим другой пример:

CREATE TABLE teams (team_id integer primary key, team_name text) with (distributed_by='team_id');
CREATE TABLE players_teams (
       player_id integer,
       team_id integer references teams(team_id),
       scores integer
) WITH (distributed_by='player_id', colocate_with='teams');
ERROR:  foreign key should start with distributed_by columns