为了确保表里的数据符合业务规则,您可以在列上定义约束。
约束定义在列上,可以限制列里存储的值。当尝试在该列上写入或更新为违反约束定义的值时,会触发一个错误并回滚这个操作;当尝试在已有的表的列上加上一个跟现有数据相冲突的约束时,也会触发一个错误并回滚这个操作。
约束类型
下面以 ware
表和 cut
表为例,介绍 OceanBase 数据库的约束类型。
obclient>CREATE TABLE ware (w_id int
, w_ytd decimal(12,2)
, w_tax decimal(4,4)
, w_name varchar(10)
, w_street_1 varchar(20)
, w_street_2 varchar(20)
, w_city varchar(20)
, w_state char(2)
, w_zip char(9)
, unique(w_name, w_city)
, primary key(w_id)
);
Query OK, 0 rows affected (0.09 sec)
obclient>CREATE TABLE cust (c_w_id int NOT NULL
, c_d_id int NOT NULL
, c_id int NOT NULL
, c_discount decimal(4, 4)
, c_credit char(2)
, c_last varchar(16)
, c_first varchar(16)
, c_middle char(2)
, c_balance decimal(12, 2)
, c_ytd_payment decimal(12, 2)
, c_payment_cnt int
, c_credit_lim decimal(12, 2)
, c_street_1 varchar(20)
, c_street_2 varchar(20)
, c_city varchar(20)
, c_state char(2)
, c_zip char(9)
, c_phone char(16)
, c_since date
, c_delivery_cnt int
, c_data varchar(500)
, index icust(c_last, c_d_id, c_w_id, c_first, c_id)
, FOREIGN KEY (c_w_id) REFERENCES table_name1(w_id)
, primary key (c_w_id, c_d_id, c_id)
);
Query OK, 0 rows affected (0.10 sec)
非空约束(
NOT NULL
):不允许约束包含的列的值为NULL
。例如,
ware
表的w_name
列类型后面有NOT NULL
约束,表示业务约束每个仓库必须有个名称。有非空约束的列,在
INSERT
语句中必须指明该列的值,除非该列还定义了默认值。例如,cust
表的列c_discount
定义了默认值0.99
,即业务上每个人默认折扣是0.99
。唯一约束(
UNIQUE
):不允许约束包含的列的值有重复值,但是可以有多个NULL
值。例如,
ware
表的(w_name, w_city)
列上有个唯一约束,表示每个城市里仓库的名称必须是不重复的。主键约束(
PRIMARY KEY
): NOT NULL 约束和唯一约束的组合。例如,
ware
表和cust
表都有个主键w_id
和c_id
,这两列不允许为NULL
并且必须是不重复的。obclient>CREATE TABLE cust (c_w_id int NOT NULL,
c_d_id int NOT NULL, c_id int NOT NULL,
c_discount decimal(4, 4),
c_credit char(2),
c_last varchar(16),
c_first varchar(16),
c_middle char(2),
c_balance decimal(12, 2),
c_ytd_payment decimal(12, 2),
c_payment_cnt int,
c_credit_lim decimal(12, 2),
c_street_1 varchar(20),
c_street_2 varchar(20),
c_city varchar(20),
c_state char(2),
c_zip char(9),
c_phone char(16),
c_since date,
c_delivery_cnt int,
c_data varchar(500),
index icust(c_last, c_d_id, c_w_id, c_first, c_id),
FOREIGN KEY (c_w_id) REFERENCES table_name1(w_id),
primary key (c_w_id, c_d_id, c_id)
);
Query OK, 0 rows affected (0.10 sec)
外键约束(
FOREIGN KEY
):要求约束的列的值取自于另外一个表的主键列。例如,
cust
表的c_w_id
上有个外键约束引用了ware
表的w_id
列,表示业务上顾客归属的仓库必须是属于仓库表里的仓库。OceanBase 数据库默认开启了外键约束检查,外键约束检查开关由租户变量
foreign_key_checks
来控制。CHECK
约束:要求数据库中某列的值符合指定的条件,仅 Oracle 模式支持。
此外,Oracle 模式下,支持对外键约束和 CHECK
约束执行启用或禁用操作。具体语法如下:
obclient> ALTER TABLE table_name MODIFY CONSTRAINT constrain_name ENABLE | DISABLE;
默认情况下,约束创建后为启用状态。
说明
目前 OceanBase 数据库不支持通过 ALTER TABLE
语句增加或修改约束,因此您需要在创建表时即确定好表的约束。
关于时间列的默认时间设置
当列上有 NOT NULL
约束时,通常建议设置为默认值。当列类型是日期或时间类型时,可以设置默认值为数据库当前时间。
- 示例:为表的时间列设置默认值,可以使用
sysdate
或systimestamp
函数。
obclient> CREATE TABLE t1(
id bigint not null primary KEY
, gmt_create datetime not null default current_timestamp
, gmt_modified datetime not null default current_timestamp
);
Query OK, 0 rows affected (0.07 sec)
obclient> INSERT INTO t1(id) VALUES(1),(2),(3);
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
obclient> SELECT * FROM t1;
+----+---------------------+---------------------+
| id | gmt_create | gmt_modified |
+----+---------------------+---------------------+
| 1 | 2020-02-27 17:09:23 | 2020-02-27 17:09:23 |
| 2 | 2020-02-27 17:09:23 | 2020-02-27 17:09:23 |
| 3 | 2020-02-27 17:09:23 | 2020-02-27 17:09:23 |
+----+---------------------+---------------------+
3 rows in set (0.00 sec)