前言:
最近参加了由opengauss、墨天轮、鲲鹏社区一起推出的活动《每日一练 opengauss 3.0.0 数据库在线实训课程》,共21天,墨天轮提供实操环境,特此记录学习笔记。
活动详情:https://www.modb.pro/db/551619
主题:
学习表的约束、表的默认值、自增类型等技术
学习笔记
第14天:表管理2
先来看看表的概念:
表(Table)
表是由行与列组合成的,是数据库中用来存储数据的对象,是整个数据库系统的基础。
每张表只能属于一个数据库,也只能对应到一个表空间。每张表对应的数据文件必须在同一个表空间中。
然后再来看看opengauss中约束的类型:
约束
约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。如果存在违反约束的数据行为,行为会被约束终止。
约束可以在创建表时规定(通过 CREATE TABLE 语句),或者在表创建之后规定(通过 ALTER TABLE 语句)。
约束可以是列级或表级。列级约束仅适用于列,表级约束被应用到整个表。
openGauss中常用的约束如下:
NOT NULL:指示某列不能存储NULL值。
UNIQUE:确保某列的值都是唯一的。
PRIMARY KEY:NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。。
FOREIGN KEY: 保证一个表中的数据匹配另一个表中的值的参照完整性。
CHECK: 保证列中的值符合指定的条件。
1.创建表的时候定义列级约束

2.创建表的时候定义表级约束

3.为表的属性定义默认值

4.如果在创建表的时候,没有为某列定义默认值,缺省的默认值是空值null。

5.创建表时使用自增数据类型
有时候需要自增的数据列,最简单方法直接使用serial数据类型。

6.使用现有的表创建新表

约束练习:
先来提出一个问题,对于UNIQUE约束和PRIMARY KEY,怎样对待空值 ? 是否相同。
1.NOT NULL约束
创建表时,如果不指定约束,默认值为NULL,即允许列插入空值。如果您不想某列存在NULL值,那么需要在该列上定义NOT NULL约束,指定在该列上的值不允许存在NULL值。插入数据时,如果该列存在NULL值,则会报错,插入失败。
NULL与没有数据是不一样的,它代表着未知的数据。
例如,创建表not_null,共有3个字段,其中ID、NAME设置不接受空值。
[omm@opengauss ~]$ gsql -d mydb1 -U test1 -W 'kunpeng@1234' -p 15400 -r
gsql ((openGauss 3.1.0 build 4e931f9a) compiled at 2022-09-29 14:19:24 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
mydb1=> \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------------------------------------------------------------+-----------
john | | {}
omm | Sysadmin, Create role, Create DB, Replication, Administer audit, Monitoradmin, Operatoradmin, Policyadmin, UseFT | {}
test1 | Sysadmin | {}
test2 | Sysadmin | {}
mydb1=> \conninfo
You are connected to database "mydb1" as user "test1" via socket in "/oracle/huawei/tmp" at port "15400".
mydb1=>
mydb1=> create table not_null
mydb1-> (
mydb1(> id int not null,
mydb1(> name char(30) not null,
mydb1(> age int
mydb1(> );
CREATE TABLE
mydb1=> insert into not_null values(1,'tiger',3);
INSERT 0 1
mydb1=> insert into not_null (name,age) values ('scott',3);
ERROR: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null, scott , 3).
mydb1=>
2.UNIQUE约束
UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。
对于唯一约束,NULL被认为是互不相等的。
mydb1=> \conninfo
You are connected to database "mydb1" as user "test1" via socket in "/oracle/huawei/tmp" at port "15400".
mydb1=> \dt
List of relations
Schema | Name | Type | Owner | Storage
---------+----------+-------+-------+----------------------------------
testsm1 | not_null | table | test1 | {orientation=row,compression=no}
testsm1 | table | table | test1 | {orientation=row,compression=no}
testsm1 | testsm2 | table | test1 | {orientation=row,compression=no}
(3 rows)
mydb1=> create table unique
mydb1-> (
mydb1(> id int unique,
mydb1(> name char(30),
mydb1(> age int
mydb1(> );
ERROR: syntax error at or near "unique"
LINE 1: create table unique
^
mydb1=>
mydb1=>
mydb1=>
mydb1=> create table unique_test
(
id int unique,
name char(30),
age int
);
NOTICE: CREATE TABLE / UNIQUE will create implicit index "unique_test_id_key" for table "unique_test"
CREATE TABLE
mydb1=> insert into unique_test values(1,'tiger',3);
INSERT 0 1
mydb1=> insert into unique_test values(1,'tiger',3);
ERROR: duplicate key value violates unique constraint "unique_test_id_key"
DETAIL: Key (id)=(1) already exists.
mydb1=> insert into unique_test (name,age) values('scott',3);
INSERT 0 1
mydb1=> insert into unique_test (name,age) values('gauss',3);
INSERT 0 1
mydb1=> select * from unique_test;
id | name | age
----+--------------------------------+-----
1 | tiger | 3
| scott | 3
| gauss | 3
(3 rows)
mydb1=>
3.PRIMARY KEY
PRIMARY KEY为主键,是数据表中每一条记录的唯一标识。主键约束声明表中的一个或者多个字段只能包含唯一的非NULL值。
主键是非空约束和唯一约束的组合。一个表只能声明一个主键。

4.FOREIGN KEY
FOREIGN Key即外键约束,指定列(或一组列)中的值必须匹配另一个表的某一行中出现的值。通常一个表中的FOREIGN KEY指向另一个表中的 UNIQUE KEY(唯一约束的键),即维护了两个相关表之间的引用完整性。
mydb1-> \dt+ primary_table
List of relations
Schema | Name | Type | Owner | Size | Storage | Description
---------+---------------+-------+-------+-------+----------------------------------+-------------
testsm1 | primary_table | table | test1 | 16 kB | {orientation=row,compression=no} |
(1 row)
mydb1->
mydb1-> \d primary_table
Table "testsm1.primary_table"
Column | Type | Modifiers
--------+---------+-----------
id | integer | not null
name | text | not null
Indexes:
"primary_table_pkey" PRIMARY KEY, btree (id) TABLESPACE pg_default
mydb1->
mydb1=> create table foreign_table
(id int references primary_table(id),
name text
);
CREATE TABLE
mydb1=>
5.CHECK约束
CHECK约束声明一个布尔表达式,每次要插入的新行或者要更新的行的新值必须使表达式结果为真或未知才能成功,否则会抛出一个异常并且不会修改数据库。
声明为字段约束的检查约束应该只引用该字段的数值,而在表约束里出现的表达式可以引用多个字段。expression表达式中,如果存在“<>NULL”或“!=NULL”,这种写法是无效的,需要写成“is NOT NULL”。
mydb1=> create table check_table
mydb1-> (
mydb1(> id int primary key not null,
mydb1(> name text not null,
mydb1(> age int not null,
mydb1(> salary real check(salary > 0)
mydb1(> );
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "check_table_pkey" for table "check_table"
CREATE TABLE
mydb1=>
mydb1=> insert into check_table
values(1,'scott',3,100000);
INSERT 0 1
mydb1=> insert into check_table
values(1,'scott',3,0);
ERROR: new row for relation "check_table" violates check constraint "check_table_salary_check"
DETAIL: N/A
mydb1=>
总结:
第4天的学习中,我们学到了创建表的时候怎么创建约束、怎么利用serial创建自增列,怎么利用现有的表来创建新表以及各种约束的使用。其中,唯一约束可以接受多个空值,主键约束是唯一约束加非空约束,所以不能有空值。




