От раздела диапазона к интервалу диапазона

Я хотел бы перейти от Range Partition к Range-Interval, но моя текущая таблица имеет раздел на MAXVALUE, а столбец, используемый для разделения, допускает нулевые значения :(

Например: Допустим, у нас есть:

create table a (b number)
partition by range (b) (
  PARTITION p0 VALUES LESS THAN (10),
  PARTITION p1 VALUES LESS THAN (50),
  PARTITION p2 VALUES LESS THAN (MAXVALUE)
);

Затем заполняем:

INSERT INTO a(b) VALUES (1);
INSERT INTO a(b) VALUES (11);
INSERT INTO a(b) VALUES (51);
INSERT INTO a(b) VALUES (null);

Чтобы иметь возможность перейти к интервалу, нам нужно удалить раздел с MAXVALUE, поэтому другие значения должны быть перемещены в новый раздел.
51 не проблема, я бы создал раздел с VALUES LESS than 100, но как насчет NULL один?

Я думал о том, чтобы перейти на что-то вроде разделения по диапазону (NVL(b,0)), но меня пугает необходимость повторной обработки всей таблицы (это невозможно, в реальной таблице много данных).

Любая идея?


person Mario Corchero    schedule 17.09.2013    source источник


Ответы (2)


NULL в столбце ключа раздела раздела таблица с интервальным секционированием (по состоянию на 12.1):

Ограничения на интервальное разбиение

  • Вы можете указать только один столбец ключа разделения, и он должен иметь тип данных NUMBER, DATE, FLOAT или TIMESTAMP.

[...]

  • Вы не можете указать значения NULL для столбца ключа разделения.

Вы также не можете использовать выражения для ключа разделения. Однако, как предлагает @Shoelace, вы можете использовать виртуальный столбец (содержащий ваше выражение) в качестве столбца раздела:

SQL> CREATE TABLE a (b NUMBER, comput_b NUMBER AS (NVL(b, 0)))
  2  PARTITION BY RANGE (comput_b) (
  3    PARTITION p0 VALUES LESS THAN (0),
  4    PARTITION p1 VALUES LESS THAN (50),
  5    PARTITION p2 VALUES LESS THAN (MAXVALUE)
  6  );

Table created

SQL> INSERT INTO a(b) VALUES (1);
1 row inserted
SQL> INSERT INTO a(b) VALUES (11);
1 row inserted
SQL> INSERT INTO a(b) VALUES (51);
1 row inserted
SQL> INSERT INTO a(b) VALUES (null);
1 row inserted

SQL> SELECT * FROM a;

         B   COMPUT_B
---------- ----------
         1          1
        11         11
                    0
        51         51

В этом конкретном случае, я думаю, вам понадобится перестройка таблицы.

person Vincent Malgrat    schedule 17.09.2013
comment
это не совсем так. поскольку по крайней мере 11g, вы можете создать виртуальный столбец (который является просто выражением) и использовать его для разделения на ... - person ShoeLace; 15.12.2017
comment
@ShoeLace Спасибо, я этого не знал! - person Vincent Malgrat; 15.12.2017

http://www.dba-oracle.com/t_interval_partitioning.htm%20This говорит вы можете изменить диапазон на интервал и обратно, используя синтаксис alter table

ie

alter table a set INTERVAL(100) ; 

полный синтаксис таблицы изменений для 11g доступен здесь .

к сожалению, это не позволяет вам изменять столбцы разделов .. так что я думаю, вам не повезло. но всегда можно попробовать.

person ShoeLace    schedule 15.12.2017