一、OpenGauss 表的约束(完整性规则)
约束是数据库保证数据正确性、一致性的核心机制,OpenGauss 支持三大类完整性约束,下面先解释概念,再给出具体创建示例。
1. 域完整性(列级完整性)
概念:限制列的取值范围和格式,确保列中的数据符合定义的规则(比如非空、默认值、数据类型、取值范围等),是对单个列的约束。
作用:防止无效、不合理的数据存入某一列(比如年龄不能为负数、手机号格式正确)。
2. 实体完整性(行级完整性)
概念:保证表中每行数据都是唯一的、可识别的,核心是主键(Primary Key)约束,主键列不能重复且不能为 NULL。
作用:避免表中出现重复记录,确保每行数据都有唯一标识(比如用户表的用户 ID 不能重复)。
3. 参照完整性(表间完整性)
概念:保证两个表之间的关联数据一致,核心是外键(Foreign Key)约束,外键列的值必须是关联表主键列的有效值(或 NULL)。
作用:防止出现“孤儿数据”(比如订单表的用户 ID 必须是用户表中存在的 ID)。
二、各类约束的创建示例
准备工作:先创建测试库/模式(可选)
-- 创建测试数据库(如果需要)
CREATE DATABASE test_db;
\c test_db; -- 切换到测试库
-- 创建模式(可选)
CREATE SCHEMA test_schema;
SET search_path TO test_schema;
1. 默认值约束(域完整性)
作用:列未显式赋值时,自动使用默认值。
示例:创建用户表,
register_time默认为当前时间,status默认为 1(启用)。
CREATE TABLE t_user (
user_id INT,
user_name VARCHAR(50),
register_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 默认当前时间
status INT DEFAULT 1 -- 默认值 1
);
-- 测试:插入数据时不指定默认值列
INSERT INTO t_user (user_id, user_name) VALUES (1, '张三');
-- 查询验证:register_time 会自动填充当前时间,status 为 1
SELECT * FROM t_user;
2. 非空约束(域完整性)
作用:强制列的值不能为 NULL。
示例:修改/创建表,
user_name非空,phone非空。
-- 方式1:创建表时指定
CREATE TABLE t_user (
user_id INT,
user_name VARCHAR(50) NOT NULL, -- 非空约束
phone VARCHAR(20) NOT NULL, -- 非空约束
register_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 方式2:已有表添加非空约束
ALTER TABLE t_user ADD CONSTRAINT ck_user_phone_notnull CHECK (phone IS NOT NULL);
-- 测试:插入 NULL 值会报错
INSERT INTO t_user (user_id, user_name, phone) VALUES (2, NULL, '13800138000'); -- 报错:user_name 非空
3. 唯一约束(实体完整性)
作用:保证列(或列组合)的值唯一(可包含 NULL,但 NULL 仅能出现一次)。
示例:
phone列唯一(手机号不能重复),user_name + email组合唯一。
-- 方式1:创建表时指定单列唯一
CREATE TABLE t_user (
user_id INT,
user_name VARCHAR(50) NOT NULL,
phone VARCHAR(20) NOT NULL UNIQUE, -- 唯一约束
email VARCHAR(50),
-- 组合唯一约束
CONSTRAINT uk_user_name_email UNIQUE (user_name, email)
);
-- 方式2:已有表添加唯一约束
ALTER TABLE t_user ADD CONSTRAINT uk_user_phone UNIQUE (phone);
-- 测试:插入重复手机号会报错
INSERT INTO t_user (user_id, user_name, phone) VALUES (1, '张三', '13800138000');
INSERT INTO t_user (user_id, user_name, phone) VALUES (2, '李四', '13800138000'); -- 报错:phone 重复
4. 主键约束(实体完整性)
作用:唯一标识行,同时满足“非空 + 唯一”,一个表只能有一个主键(可组合主键)。
示例:
user_id作为主键(单列主键),订单表order_id + shop_id组合主键。
-- 方式1:单列主键(推荐)
CREATE TABLE t_user (
user_id INT PRIMARY KEY, -- 主键约束(自动非空+唯一)
user_name VARCHAR(50) NOT NULL,
phone VARCHAR(20) NOT NULL UNIQUE
);
-- 方式2:组合主键
CREATE TABLE t_order (
order_id INT,
shop_id INT,
order_time TIMESTAMP,
-- 组合主键
PRIMARY KEY (order_id, shop_id)
);
-- 方式3:已有表添加主键
ALTER TABLE t_user ADD CONSTRAINT pk_user_id PRIMARY KEY (user_id);
-- 测试:主键重复/NULL 都会报错
INSERT INTO t_user (user_id, user_name, phone) VALUES (1, '张三', '13800138000');
INSERT INTO t_user (user_id, user_name, phone) VALUES (1, '李四', '13900139000'); -- 报错:主键重复
5. 外键约束(参照完整性)
作用:关联两个表,外键列引用主表的主键/唯一键,保证数据关联一致。
示例:订单表
t_order的user_id引用用户表t_user的user_id。
-- 先创建主表(用户表)
CREATE TABLE t_user (
user_id INT PRIMARY KEY,
user_name VARCHAR(50) NOT NULL
);
-- 创建从表(订单表),添加外键约束
CREATE TABLE t_order (
order_id INT PRIMARY KEY,
order_amount NUMERIC(10,2),
user_id INT,
-- 外键约束:user_id 引用 t_user.user_id
CONSTRAINT fk_order_user_id FOREIGN KEY (user_id)
REFERENCES t_user (user_id)
ON DELETE SET NULL -- 主表记录删除时,从表外键列设为 NULL
ON UPDATE CASCADE -- 主表主键更新时,从表外键列同步更新
);
-- 测试1:插入合法外键值(正常)
INSERT INTO t_user (user_id, user_name) VALUES (1, '张三');
INSERT INTO t_order (order_id, order_amount, user_id) VALUES (1001, 99.9, 1);
-- 测试2:插入不存在的 user_id(报错)
INSERT INTO t_order (order_id, order_amount, user_id) VALUES (1002, 59.9, 999); -- 报错:外键约束失败
三、字符集与校对集(排序规则)
1. 基本概念
- 字符集(Character Set):定义数据库/表/列支持的字符编码(比如 UTF8、GBK),决定能存储哪些字符(中文、英文、特殊符号等)。
OpenGauss 主流使用 UTF8(兼容所有语言),也支持 GBK(简体中文)、SQL_ASCII 等。
- 校对集(Collation):定义字符的排序、比较规则(比如大小写是否敏感、中文按拼音/笔画排序)。
格式:字符集_地区_排序规则(比如 zh_CN.UTF8 表示中文 UTF8 编码,按拼音排序)。
2. 设置方式(优先级:列 > 表 > 数据库 > 实例)
(1)实例级设置(修改配置文件,需重启)
# 编辑 openGauss 配置文件(postgresql.conf)
vi $GAUSSDATA/postgresql.conf
# 设置默认字符集和校对集
server_encoding = 'UTF8' # 默认字符集
collation_server = 'zh_CN.UTF8' # 默认校对集(中文拼音排序)
# 重启数据库生效
gs_om -t stop && gs_om -t start
(2)数据库级设置(创建/修改数据库)
-- 创建数据库时指定字符集和校对集
CREATE DATABASE test_db
WITH ENCODING = 'UTF8' -- 字符集
LC_COLLATE = 'zh_CN.UTF8' -- 排序规则(校对集)
LC_CTYPE = 'zh_CN.UTF8'; -- 字符分类规则(通常和 LC_COLLATE 一致)
-- 修改已有数据库的校对集(需谨慎,仅空库/低负载时操作)
ALTER DATABASE test_db SET LC_COLLATE = 'zh_CN.UTF8';
(3)表级/列级设置
-- 表级设置(列继承表的规则,可单独覆盖)
CREATE TABLE t_user (
user_id INT PRIMARY KEY,
user_name VARCHAR(50) NOT NULL,
-- 列级指定校对集(大小写不敏感)
email VARCHAR(50) COLLATE "zh_CN.UTF8"
) WITH (ENCODING = 'UTF8');
-- 测试校对集:中文按拼音排序
INSERT INTO t_user (user_id, user_name) VALUES (1, '张三'), (2, '李四'), (3, '王五');
SELECT * FROM t_user ORDER BY user_name COLLATE "zh_CN.UTF8"; -- 按拼音:李四、王五、张三
3. 常用校对集示例
| 校对集 | 说明 |
|---|---|
zh_CN.UTF8 |
中文 UTF8,拼音排序 |
zh_CN.UTF8_BIN |
中文 UTF8,二进制排序(大小写敏感) |
en_US.UTF8 |
英文 UTF8,默认排序 |
C(或 POSIX) |
二进制排序,最快,大小写敏感 |
总结
三大完整性约束:域完整性(列规则,如非空/默认值)、实体完整性(行唯一,如主键/唯一约束)、参照完整性(表关联,如外键)。
约束创建:可在
CREATE TABLE时直接定义,也可通过ALTER TABLE给已有表添加,主键/外键建议显式命名约束名。字符集与校对集:OpenGauss 推荐用
UTF8字符集,校对集决定排序/比较规则,优先级:列 > 表 > 数据库 > 实例。
(注:)