GBase 8s数据库主键约束、唯一约束和唯一索引的区别

本文介绍了主键约束、唯一性约束及唯一索引的概念与区别,包括它们如何确保数据的唯一性和完整性,并通过实例演示了各种约束的效果。
主键约束(PRIMARY KEY)
  1. 主键用于唯一地标识表中的每一条记录,可以定义一列或多列为主键,一个表上仅只能有一个主键;
  2. 不建议更新主键;
  3. 主键列上没有任何两行具有相同值(即重复值),且不允许空(NULL);
  4. 主健可作外健,唯一索引不可;
唯一性约束(UNIQUE)
  1. 唯一性约束用来限制不受主键约束的列上的数据的唯一性,用于作为访问某行的可选手段,一个表上可以放置多个唯一性约束;
  2. 只要唯一就可以更新;
  3. 表中任意两行在指定列上都不允许有相同的值,但允许空(NULL);
唯一索引(UNIQUE INDEX)
  1. 唯一索引可以确保任何生成重复键值的尝试都会失败;
  2. 只要唯一就可以更新;
  3. 表中任意两行在指定列上都不允许有相同的值,但允许空(NULL);
唯一性约束和主键约束的区别:
  1. 唯一性约束允许在该列上存在NULL值,而主键约束的限制更为严格,不但不允许有重复,而且也不允许有空值。
唯一约束和唯一索引的区别:

前者是用来检查数据的正确性,后者用来实现数据查询的优化,目的不同。
唯一性约束与唯一索引有所不同:

  1. 创建唯一约束会在GBase 8s中创建一个constraint,同时也会创建一个该约束对应的唯一索引;
  2. 创建唯一索引只会创建一个唯一索引,不会创建constraint;
    也就是说其实唯一约束是通过创建唯一索引来实现的。

以下示例来说明这三者之间的区别:
1,创建表、导入基础数据

drop table if exists tab1;
create table tab1(col1 int, col2 varchar(20), col3 varchar(20));
insert into tab1 values(1,'test001','test001');
insert into tab1 values(2,null,'test002');
insert into tab1 values(3,'test003',null);

2,创建主键、唯一约束和唯一索引
主键唯一值且不允许为null,唯一约束值唯一但允许null,唯一索引值唯一但允许null

alter table tab1 add constraint primary key(col1) constraint pk_tab1_col1;
alter table tab1 add constraint unique(col2) constraint uk_tab1_col2;
create unique index ux_tab1_col3 on tab1 (col3);

查看表的报告,可以看到三个索引(对应主键、唯一约束和唯一索引),但需要注意的是主键、唯一约束的索引名称并不是指定的约束名称

oncheck -pt testdb:tab1 | grep 'fragment partition'

Index  102_3 fragment partition datadbs01 in DBspace datadbs01
Index  102_4 fragment partition datadbs01 in DBspace datadbs01
Index ux_tab1_col3 fragment partition datadbs01 in DBspace datadbs01

3,测试区别

insert into tab1 values(null,'test004','test004');

将报错误:703: Primary key on table (tab1) has a field with a null key value.
不允许空值。

insert into tab1 values(3,'test005','test005');

将报错误:268: Unique constraint (gbasedbt.pk_tab1_col1) violated.
违反主键约束(pk_tab1_col1),因已经存在值 3 。

insert into tab1 values(4,null,'test006');

将报错误:268: Unique constraint (gbasedbt.uk_tab1_col2) violated.
违反唯一约束(uk_tab1_col2),因已经存在值 null 。

insert into tab1 values(5,'test003','test007');

将报错误:268: Unique constraint (gbasedbt.uk_tab1_col2) violated.
违反唯一约束(uk_tab1_col2),因已经存在值 test003 。

insert into tab1 values(6,'test008',null);

将报错误:239: Could not insert new row - duplicate value in a UNIQUE INDEX column (Unique Index:ux_tab1_col3).
不允许插入重复值,因已经存在值 null 。

insert into tab1 values(7,'test009','test002');

将报错误:239: Could not insert new row - duplicate value in a UNIQUE INDEX column (Unique Index:ux_tab1_col3).
不允许插入重复值,因已经存在值 test002 。

insert into tab1 values(8,'test010','test010');

插入成功。

alter table tab1 drop constraint uk_tab1_col2;
oncheck -pt testdb:tab1 | grep 'fragment partition'

Index  102_3 fragment partition datadbs01 in DBspace datadbs01
Index ux_tab1_col3 fragment partition datadbs01 in DBspace datadbs01

删除约束,对应的索引一并删除。

细心的你,会发现:

  1. 如果字段加上not null约束,再加上唯一约束或者唯一索引,功能上将等同于主键约束;
  2. 唯一约束仅仅比唯一索引多了一个约束;
<think>我们正在使用GBase 8s数据库,需要查询表的元数据信息。根据引用[2]中提到的元数据查询,我们可以通过系统表来获取这些信息。GBase 8s提供了若干系统表(如systables、syscolumns等)来存储数据库的元数据。 常见的元数据查询包括: 1. 查询表是否存在 2. 查询表的列信息 3. 查询表的索引 4. 查询表的主键、外键等约束 以下是一些常用的SQL查询示例: 1. 查询当前数据库中所有表的信息(包括表名、所有者等): ```sql SELECT tabname, owner FROM systables WHERE tabid >= 100 AND tabtype = 'T'; ``` 说明:`systables`存储了所有表的信息,`tabid>=100`是为了过滤系统表(系统表的tabid小于100),`tabtype='T'`表示是普通表(不包括视图、同义词等)。 2. 查询指定表(例如表名为'user')的列信息(列名、数据类型、长度等): ```sql SELECT c.colname, c.coltype, c.collength FROM syscolumns c, systables t WHERE t.tabname = 'user' AND c.tabid = t.tabid; ``` 或者使用: ```sql SELECT colname, coltype, collength FROM syscolumns WHERE tabid = (SELECT tabid FROM systables WHERE tabname = 'user'); ``` 3. 查询表的主键约束: ```sql SELECT c.constrname, c.idxname, i.idxname, i.idxtype, i.part1, i.part2, ... FROM sysconstraints c, sysindexes i WHERE c.tabid = (SELECT tabid FROM systables WHERE tabname = 'user') AND c.constrtype = 'P' AND c.idxname = i.idxname; ``` 注意:`constrtype`为'P'表示主键约束。 4. 查询表的外键约束: ```sql SELECT c.constrname, c.constrtype, f.primary_tabid, f.primary_key, ... FROM sysconstraints c, sysreferences f WHERE c.tabid = (SELECT tabid FROM systables WHERE tabname = 'user') AND c.constrtype = 'R' AND c.constrid = f.constrid; ``` 说明:`constrtype`为'R'表示参照完整性约束(外键)。 5. 查询表的索引信息(不包括主键唯一约束): ```sql SELECT idxname, idxtype, part1, part2, ... FROM sysindexes WHERE tabid = (SELECT tabid FROM systables WHERE tabname = 'user') AND idxtype != 'U' -- 排除唯一索引唯一约束会创建唯一索引) AND idxname NOT IN (SELECT idxname FROM sysconstraints WHERE tabid = sysindexes.tabid); ``` 注意:这里可能还需要排除主键约束创建的索引,因为主键也会创建唯一索引。 6. 查询表的唯一约束(包括主键): ```sql SELECT c.constrname, c.constrtype, i.idxname FROM sysconstraints c, sysindexes i WHERE c.tabid = (SELECT tabid FROM systables WHERE tabname = 'user') AND (c.constrtype = 'P' OR c.constrtype = 'U') AND c.idxname = i.idxname; ``` 说明:`constrtype='U'`表示唯一约束。 7. 查询表的检查约束(Check): ```sql SELECT constrname, checktext FROM syschecks WHERE constrid IN ( SELECT constrid FROM sysconstraints WHERE tabid = (SELECT tabid FROM systables WHERE tabname = 'user') AND constrtype = 'C' ); ``` 说明:`constrtype='C'`表示检查约束。 注意:以上查询可能需要根据具体的GBase 8s版本系统表结构进行调整。在实际使用中,可能需要连接多个系统表来获取更完整的信息。 另外,引用[3][4]提供了关于GBase 8s存储结构架构的信息,但对于元数据查询,我们主要关注系统表(数据字典)。 如果用户需要更详细的信息,可以参考GBase 8s官方文档中关于系统表数据字典的部分。 相关问题: 1. 如何查询GBase 8s数据库中所有视图的信息? 2. 如何查询GBase 8s数据库中存储过程函数的信息? 3. 如何查询GBase 8s数据库中表的空间使用情况?</think>### 如何使用SQL查询GBase s数据库表的元数据 在GBase 8s中,可通过查询系统表(数据字典)获取表的元数据信息。以下是常用查询方法: #### 1. **查询所有表信息** ```sql SELECT tabname AS 表名, owner AS 所有者, partnum AS 分区号 FROM systables WHERE tabid >= 100 AND tabtype = 'T'; -- 过滤系统表 ``` > 说明:`systables`存储所有表/视图信息,`tabid>=100`过滤用户表[^2][^3]。 #### 2. **查询表结构(列信息)** ```sql SELECT c.colname AS 列名, c.coltype AS 数据类型编码, t.typname AS 数据类型, c.collength AS 长度 FROM syscolumns c JOIN systables tb ON c.tabid = tb.tabid JOIN sysxtdtypes t ON c.coltype = t.xtypeid WHERE tb.tabname = '表名'; -- 替换实际表名 ``` #### 3. **查询主键约束** ```sql SELECT idxname AS 主键名, col1 AS 主键列 FROM sysindexes WHERE tabid = (SELECT tabid FROM systables WHERE tabname='表名') AND idxtype = 'U'; -- U表示唯一约束主键) ``` #### 4. **查询外键约束** ```sql SELECT r.constrname AS 外键名, p.tabname AS 主表, f.colname AS 外键列 FROM sysreferences r JOIN sysconstraints c ON r.constrid = c.constrid JOIN syscolumns f ON c.tabid = f.tabid AND r.primary_col = f.colno JOIN systables p ON r.ptabid = p.tabid WHERE c.tabid = (SELECT tabid FROM systables WHERE tabname='表名'); ``` #### 5. **查询索引信息** ```sql SELECT idxname AS 索引名, idxtype AS 索引类型, part1 AS 索引列 FROM sysindexes WHERE tabid = (SELECT tabid FROM systables WHERE tabname='表名'); ``` #### 6. **查询表存储位置** ```sql SELECT dbsname AS 所属dbspace, partnum AS 分区号 FROM systables WHERE tabname = '表名'; ``` > **关键系统表说明**: > - `systables`:表/视图元数据 > - `syscolumns`:列定义 > - `sysindexes`:索引信息 > - `sysconstraints`:约束定义 > - `sysreferences`:外键关系[^2][^3][^4] --- ### 相关问题 1. 如何查询GBase 8s中所有视图的元数据? 2. 怎样获取GBase 8s表的存储空间使用情况? 3. GBase 8s的系统表结构与Oracle/MySQL有何差异? 4. 如何通过JDBC编程动态获取GBase 8s元数据?[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值