CREATE TABLE

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

Синтаксис

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

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

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

[ 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 накладывает ограничения на общий синтаксис команды. Например, в настоящее время нет поддержки для:

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

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

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

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

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

Параметры

IF NOT EXISTS

Не считать ошибкой, если отношение с таким именем уже существует. В этом случае будет выдано замечание. С IF NOT EXISTS ошибка не выдаётся, если уже существующая одноимённая таблица является глобальной или сегментированной или она находится на узле, где выполняется запрос. В ином случае такой запрос завершится ошибкой.

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

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