• 下面示例对 Oracle 模式内建类型的支持。

创建后可以通过DESC命令查看列属性。

  1. | FIELD | TYPE | NULL | KEY | DEFAULT | EXTRA |
  2. +-----------------+-----------------------------------+------+-----+---------+-------+
  3. | ID | NUMBER | NO | PRI | NULL | NULL |
  4. | C_CHAR | CHAR(100) | YES | NULL | NULL | NULL |
  5. | C_VARCHAR | VARCHAR2(100) | YES | NULL | NULL | NULL |
  6. | C_NCHAR | NCHAR(100) | YES | NULL | NULL | NULL |
  7. | C_NVARCHAR | NVARCHAR2(100) | YES | NULL | NULL | NULL |
  8. | C_NUMERIC | NUMBER(10,2) | YES | NULL | NULL | NULL |
  9. | C_INT | NUMBER(38) | YES | NULL | NULL | NULL |
  10. | C_FLOAT | FLOAT(2) | YES | NULL | NULL | NULL |
  11. | C_BINARY_FLOAT | BINARY_FLOAT | YES | NULL | NULL | NULL |
  12. | C_BINARY_DOUBLE | BINARY_DOUBLE | YES | NULL | NULL | NULL |
  13. | C_DATE | DATE | YES | NULL | NULL | NULL |
  14. | C_TIMESTAMP | TIMESTAMP(6) | YES | NULL | NULL | NULL |
  15. | C_TIMESTAMP2 | TIMESTAMP(6) WITH TIME ZONE | YES | NULL | NULL | NULL |
  16. | C_TIMESTAMP3 | TIMESTAMP(6) WITH LOCAL TIME ZONE | YES | NULL | NULL | NULL |
  17. | C_INTERVAL_YEAR | INTERVAL YEAR (2) TO MONTH | YES | NULL | NULL | NULL |
  18. | C_INTERVAL_DAY | INTERVAL DAY (2) TO SECOND (6) | YES | NULL | NULL | NULL |
  19. | C_RAW | RAW(2000) | YES | NULL | NULL | NULL |
  20. | C_BLOB | BLOB | YES | NULL | NULL | NULL |
  21. | C_CLOB | CLOB | YES | NULL | NULL | NULL |
  22. +-----------------+-----------------------------------+------+-----+---------+-------+
  23. 19 rows in set (0.01 sec)
  • 下面示例使用 CREATE TABLE 语句创建订单表 ware 和 cust 表。

说明

建议建表的时候为表设计主键或者唯一键,这样对性能或者后期维护都很有益。如果没有合适的字段作为主键,可以为表增加一个数值列作为主键,使用 OceanBase Oracle 租户的序列为这一列填充值。有关序列介绍请参见 创建和管理序列

由于 ALTER TABLE 语法不支持后期增加主键,所以在建表的时候设置主键就更加有必要了。

Oracle 租户不支持 CREATE TABLE LIKE 复制表结构的方法,所以完全的复制表结构必须拿到源表的 DDL,更改名字重新创建新表。

  1. obclient> show create table t3\G
  2. TABLE: T3
  3. CREATE TABLE: CREATE TABLE "T3" (
  4. "ID" NUMBER NOT NULL,
  5. "GMT_CREATE" DATE DEFAULT sysdate NOT NULL,
  6. CONSTRAINT "T3_OBPK_1582718853302518" PRIMARY KEY ("ID"),
  7. CONSTRAINT "T3_UK" UNIQUE ("NAME", "ID")
  8. ) COMPRESS FOR ARCHIVE REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 10
  9. partition by hash(id) partitions 8
  10. 1 row in set (0.01 sec)
  11. obclient> create table t3_like like t3;
  12. ERROR-00900: You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near 'like t3' at line 1
  13. obclient> create table t3_copy as select * from t3;
  14. Query OK, 0 rows affected (0.10 sec)
  15. obclient> show create table t3_copy\G
  16. *************************** 1. row ***************************
  17. TABLE: T3_COPY
  18. CREATE TABLE: CREATE TABLE "T3_COPY" (
  19. "ID" NUMBER,
  20. "NAME" VARCHAR2(50),
  21. "GMT_CREATE" DATE
  22. ) COMPRESS FOR ARCHIVE REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 10
  23. 1 row in set (0.00 sec)

在 OceanBase 数据库中,数据存储在表中,而数据表示的最小粒度是分区。普通的非分区表,就只有一个分区;而分区表,通常有多个分区,分区名默认以 p 开头,按数字顺序从 0 开始编号。所以分区是表的子集。

通常分区对用户的应用是透明的,应用只需要使用 SQL 读写表即可。只有某些场景下,为了提升分区表的查询性能,应用也可以使用 SQL 直接访问某个具体的分区,SQL 语法格式是:

  • 示例:通过 SQL 直接访问分区表的分区
  1. obclient> select o_id,o_c_id,o_carrier_id,o_ol_cnt,o_all_local,o_entry_d from ordr partition (p5) where o_w_id=1 and o_d_id=2 and o_id=2100;
  2. +------+--------+--------------+----------+-------------+---------------------+
  3. +------+--------+--------------+----------+-------------+---------------------+
  4. | 2100 | 8 | 8 | 11 | 1 | 2020-02-15 18:57:10 |
  5. 1 row in set (0.00 sec)
  6. obclient> select ol_o_id, ol_number,ol_delivery_d,ol_amount,ol_i_id,ol_supply_w_id,ol_quantity from ordl partition (p5) where ol_w_id=1 and ol_d_id=2 and ol_o_id=2100;
  7. +---------+-----------+---------------------+-----------+---------+----------------+-------------+
  8. | OL_O_ID | OL_NUMBER | OL_DELIVERY_D | OL_AMOUNT | OL_I_ID | OL_SUPPLY_W_ID | OL_QUANTITY |
  9. +---------+-----------+---------------------+-----------+---------+----------------+-------------+
  10. | 2100 | 1 | 2020-02-15 18:57:10 | 0 | 87133 | 1 | 5 |
  11. | 2100 | 2 | 2020-02-15 18:57:10 | 0 | 47413 | 1 | 5 |
  12. | 2100 | 3 | 2020-02-15 18:57:10 | 0 | 9115 | 1 | 5 |
  13. | 2100 | 4 | 2020-02-15 18:57:10 | 0 | 42985 | 1 | 5 |
  14. | 2100 | 5 | 2020-02-15 18:57:10 | 0 | 43621 | 1 | 5 |
  15. | 2100 | 6 | 2020-02-15 18:57:10 | 0 | 5787 | 1 | 5 |
  16. | 2100 | 7 | 2020-02-15 18:57:10 | 0 | 62576 | 1 | 5 |
  17. | 2100 | 8 | 2020-02-15 18:57:10 | 0 | 91592 | 1 | 5 |
  18. | 2100 | 9 | 2020-02-15 18:57:10 | 0 | 34452 | 1 | 5 |
  19. | 2100 | 10 | 2020-02-15 18:57:10 | 0 | 13792 | 1 | 5 |
  20. | 2100 | 11 | 2020-02-15 18:57:10 | 0 | 94326 | 1 | 5 |
  21. +---------+-----------+---------------------+-----------+---------+----------------+-------------+
  22. 11 rows in set (0.01 sec)

说明

如果是组合分区,可以访问更细粒度的分区,详细描述请参考 。

在 OceanBase 数据库里,节点间的数据迁移的最小粒度是分区,每个分区在集群里有三个副本,内容保持同步,角色上有区分。三副本会有一个主副本(Leader 副本)和两个备副本(Follower 副本),只有主副本可以提供写服务,默认也只有主副本可以提供读服务。主副本上的事务提交时会将事务日志同步到两个备副本,三副本使用 Paxos 协议表决事务是否提交成功。有时候为了不影响主副本,可以让备副本承担部分读请求,这就是应用常用的读写分离的解决方案,

  • 示例:使用 SQL Hint 实现读写分离。

    弱一致读的 Hint 语法是 /*+ read_consistency(weak) */ 。通常的读默认是强一致性读,就不用 Hint 了。

复制表是分布式数据库 OceanBase 的高级优化手段。

通常 OceanBase 集群是三副本架构,默认每个表的每个分区在 OceanBase 集群中会有三个副本数据,角色上分为一个主副本(Leader 副本)和两个备副本(Follower副本),默认提供读写服务的是主副本。

复制表可以指定在租户的每台机器上都有一个备副本,并且主副本跟所有备份的数据使用全同步策略保持强同步。这样做的目的是为了让业务有些 SQL 关联查询时能在同一节点内部执行,以获取更好的性能。

  • 示例:创建复制表。
  1. obclient> create table item (i_id int
  2. , i_name varchar(24)
  3. , i_price decimal(5,2)
  4. , i_data varchar(50)
  5. , i_im_id int
  6. , primary key(i_id)) COMPRESS FOR QUERY pctfree=0 BLOCK_SIZE=16384
  7. Query OK, 0 rows affected (0.10 sec)