
# 表设计规范
- 【规则】视图不建议嵌套。
  - 一方面，如果视图编写时使用了通配符，当被调用的视图新增或删除列时，视图将发生错误。
  
  - 另一方面，视图嵌套可能因无法使用索引而导致执行效率低下，尽量使用带有索引的基表而不是视图上做关联操作。
   

- 【建议】视图定义中尽量避免排序操作。 ORDER BY子句在顶层视图上无效，如果必须对输出数据排序，请考虑在调用视图中使用ORDER BY。
  

- 【建议】尽量减少随机I/O。通过聚簇可以实现热数据的连续存储，将随机I/O转换为连续I/O，从而减少扫描的I/O代价。
#### 选择存储方案
【建议】表的存储类型是表定义设计的第一步，客户业务类型是决定表的存储类型的主要因素，表存储类型的选择依据请参考[表1]。
 表1表的存储类型及场景 
| 存储类型 | 适用场景                                                                                                                                                                                                                                                                                                                                                                                                                                             |
|:---|:---|
| 行存   | - 点查询（返回记录少，基于索引的简单查询）。  - 增、删、改操作较多的场景。   |
   
#### 选择分区方案
当表中的数据量很大时，应当对表进行分区，一般需要遵循以下原则：
- 【规则】对于大数据表，选取适当的分区方案。 数据库目前提供RANGE PARTITION、LIST PARTITION、HASH PARTITION分区方法，分区时应注意以下原则：
  - 建议使用具有区间性的字段进行分区，比如日期、区域等。
  
  - RANGE PARTITION分区的上边界分区值应定义为MAXVALUE，防止数据溢出。
  
  - 分区名称应体现分区的数据特征，例如使用关键字+区间特征进行命名。
  
  - 【建议】分区数建议不超过100个，单个分区数据量建议不超过5千万，单分区的数据容量不超过50GB。
   

- 【说明】减少需要扫描的数据量。通过分区表的剪枝机制可以大幅减少数据的扫描量。
- 【建议】使用具有明显区间性的字段进行分区，比如日期、区域等字段上建立分区。
- 【建议】分区名称应当体现分区的数据特征。例如，关键字+区间特征。
- 【建议】将分区上边界的分区值定义为MAXVALUE，以防止可能出现的数据溢出。
  表2表的分区方式及使用场景 
  | 分区方式     | 描述                              |
  |:---|:---|
  | Range    | 表数据通过范围进行分区。                    |
  | Interval | 表数据通过范围进行分区，超出范围的会自动根据间隔创建新的分区。 |
  | List     | 表数据通过指定列按照具体值进行分区。              |
  | Hash     | 表数据通过Hash散列方式进行分区。              |
     
  典型的分区表定义如下：
  ```
  --创建Range分区表
  CREATE TABLE staffS_p1
  (
    staff_ID       NUMBER(6) not null,
    FIRST_NAME     VARCHAR2(20),
    LAST_NAME      VARCHAR2(25),
    EMAIL          VARCHAR2(25),
    PHONE_NUMBER   VARCHAR2(20),
    HIRE_DATE      DATE,
    employment_ID  VARCHAR2(10),
    SALARY         NUMBER(8,2),
    COMMISSION_PCT NUMBER(4,2),
    MANAGER_ID     NUMBER(6),
    section_ID     NUMBER(4)
  )
  PARTITION BY RANGE (HIRE_DATE)
  ( 
     PARTITION HIRE_19950501 VALUES LESS THAN ('1995-05-01 00:00:00'),
     PARTITION HIRE_19950502 VALUES LESS THAN ('1995-05-02 00:00:00'),
     PARTITION HIRE_maxvalue VALUES LESS THAN (MAXVALUE)
  );
  --创建Interval分区表，初始两个分区，插入分区范围外的数据会自动新增分区
  CREATE TABLE sales
  (prod_id NUMBER(6),
   cust_id NUMBER,
   time_id DATE,
   channel_id CHAR(1),
   promo_id NUMBER(6),
   quantity_sold NUMBER(3),
   amount_sold NUMBER(10,2)
  )
  PARTITION BY RANGE (time_id)
  INTERVAL('1 day')
  ( PARTITION p1 VALUES LESS THAN ('2019-02-01 00:00:00'),
    PARTITION p2 VALUES LESS THAN ('2019-02-02 00:00:00')
  );
  --创建List分区表
  CREATE TABLE test_list (col1 int, col2 int)
  partition by list(col1)
  (
  partition p1 values (2000),
  partition p2 values (3000),
  partition p3 values (4000),
  partition p4 values (5000)
  );
  --创建Hash分区表
  CREATE TABLE test_hash (col1 int, col2 int)
  partition by hash(col1)
  (
  partition p1,
  partition p2
  );
  ```
  更多的表分区语法信息参见[CREATE TABLE PARTITION](https://support.huaweicloud.com/centralized-devg-v2-gaussdb/gaussdb_42_0426.html#ZH-CN_TOPIC_0000002221496321)。
  
 
