PostgreSQL data definition language DDL

Table creation

The construction statement of the PostgreSQL table is the same as that of all databases. The structure is as follows. The core is to specify some constraints when building the table, such as primary key, non-null, unique, check, foreign key, default value, etc.

CREATE TABLE table_name (  
    column1 datatype,  
    column2 datatype,  
    column3 datatype,  
    ...  
);

primary key constraints

-- 主键约束
drop table test;
create table test(
    id bigserial primary key ,
    name varchar(32)
);

non empty

-- 非空约束
drop table test;
create table test(
    id bigserial primary key ,
    name varchar(32) not null
);

unique constraint

drop table test;
create table test(
    id bigserial primary key ,
    name varchar(32) not null,
    id_card varchar(32) unique
);
insert into test (name,id_card) values ('张三','333333333333333333');
insert into test (name,id_card) values ('李四','333333333333333333');
insert into test (name,id_card) values (NULL,'433333333333333333');

Check constraints

-- 检查约束
-- 价格的表,price,discount_price
drop table test;
create table test(
    id bigserial primary key,
    name varchar(32) not null,
    price numeric check(price > 0),
    discount_price numeric check(discount_price > 0),
    check(price >= discount_price)
);
insert into test (name,price,discount_price) values ('粽子',122,12);

foreign key constraints

Need not

Default value constraints

In general companies, in addition to the primary key and business fields, the table must have 5 fields: created,create_id,updated,update_id,is_delete, and usually default values ​​can be set for these fields.

-- 默认值
create table test(
    id bigserial primary key,
    created timestamp default current_timestamp
);

trigger

Trigger is a stored procedure triggered by an event. When insert, update, delete, or truncate operations are performed, the Trigger of the table will be triggered.

Here, taking student information and student scores as an example, when deleting student information, the student's scores are automatically deleted.

First build the table information and fill in the data

create table student(
    id int,
    name varchar(32)
);
create table score(
    id int,
    student_id int,
    math_score numeric,
    english_score numeric,
    chinese_score numeric
);
insert into student (id,name) values (1,'张三');
insert into student (id,name) values (2,'李四');
insert into
    score
(id,student_id,math_score,english_score,chinese_score)
    values
(1,1,66,66,66);

insert into
    score
(id,student_id,math_score,english_score,chinese_score)
    values
(2,2,55,55,55);

select * from student;
select * from score;

In order to complete the cascade delete operation, you need to write pl/sql.

First check the plsql supported by PGSQL and check the plsql syntax of PGSQL.

[ <<label>> ]
[ DECLARE
    declarations ]
BEGIN
    statements
END [ label ];

Trigger functions allow the use of some special variables

NEW
数据类型是RECORD;该变量为行级触发器中的INSERT/UPDATE操作保持新数据行。在语句级别的触发器以及DELETE操作,这个变量是null。

OLD
数据类型是RECORD;该变量为行级触发器中的UPDATE/DELETE操作保持新数据行。在语句级别的触发器以及INSERT操作,这个变量是null。

Build a function that removes student scores.

-- 构建一个删除学生分数的触发器函数。
create function trigger_function_delete_student_score() returns trigger as $$
begin
    delete from score where student_id = old.id;
    return old;
end;
$$ language plpgsql;

When the student information table is deleted, the declared function is executed

image.png

CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name { BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] }
    ON table_name
    [ FROM referenced_table_name ]
    [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
    [ REFERENCING { { OLD | NEW } TABLE [ AS ] transition_relation_name } [ ... ] ]
    [ FOR [ EACH ] { ROW | STATEMENT } ]
    [ WHEN ( condition ) ]
    EXECUTE { FUNCTION | PROCEDURE } function_name ( arguments )

where event can be one of:

    INSERT
    UPDATE [ OF column_name [, ... ] ]
    DELETE
    TRUNCATE

When CONSTRAINToption is specified, this command creates a constraint trigger . This is the same as a regular trigger, but the timing of firing the trigger can be adjusted using SET CONSTRAINTS . The constraint trigger must be a trigger on the table AFTER ROW. They can be raised at the end of the statement that causes the trigger event or at the end of the transaction that contains the statement. In the latter case, they are said to be delayed . The firing of a pending deferred trigger can also be SET CONSTRAINTSforced to occur using immediate force. A constraint trigger should throw an exception when a constraint implemented by the constraint trigger is violated.

Write a trigger and specify that when a certain row of student information is deleted, the current trigger will be triggered and the trigger_function_delete_student_score() function will be executed.

create trigger trigger_student 
after 
delete 
on student 
for each row 
execute function trigger_function_delete_student_score();
-- 测试效果
select * from student;
select * from score;
delete from student where id = 1;

table space

When storing data, the data must be placed on the disk. Based on the built tablespace, the physical address where the data is stored on the disk is specified. If you do not design the tablespace yourself, PGSQL will automatically specify a location as the default storage point. You can use a function to check the disk path where the physical data of the table is stored.

-- 查询表存储的物理地址
select pg_relation_filepath('student');

image.png

This location is the storage address after $PG_DATA, and 41000 is the physical file where the data is stored.

$PG_DATA == /var/lib/pgsql/12/data/

Build tablespace

image.png
To build a table space, building a table space requires the user rights to be a super administrator, and secondly, the specified directory needs to already exist.

create tablespace tp_test location '/var/lib/pgsql/12/tp_test';

image.png

Build the database and tables and assign them to this table space

image.png

In fact, after specifying the storage location of the table space, PGSQL will store a copy in the $PG_DATA directory. At the same time, when we build the tablespace, a copy will also be stored in the specified path.

The files under these two absolute paths all store data information in the table.

/var/lib/pgsql/12/data/pg_tblspc/41015/PG_12_201909212/41016/41020
/var/lib/pgsql/12/tp_test/PG_12_201909212/41016/41020

You will further find that in fact, in the default directory of PGSQL, a link is stored, a connection file, similar to a shortcut

view

Like MySQL, it encapsulates some complex operations and hides some sensitive data.

For users, a view is a real table, and the information of one or more tables can be directly queried based on the view. For development, a view is just a SQL statement.

image.png

In PGSQL, simple (single table) views allow write operations. However, it is strongly not recommended to write to views. Although PGSQL allows it by default (simple views), when writing, the table itself is actually modified.

simple view

-- 构建一个
create view vw_score as 
(select id,math_score from score);

select * from vw_score;
update vw_score set math_score = 99 where id = 2;

Multiple table view

-- 复杂视图(两张表关联)
create view vw_student_score as 
(select stu.id as id ,stu.name as name ,score.math_score from student stu,score score where stu.id = score.student_id);

select * from vw_student_score;

update vw_student_score set math_score =999 where id = 2;

image.png

index

Basic concepts of indexing

Indexes are a way to quickly query data in a database. While improving query efficiency, it will also bring about some problems:

  • Increased storage space
  • Writing operations take more time

Indexes can improve efficiency and can even impose some constraints on fields.

Index classification

  • B-Tree index: the most commonly used index.

  • Hash index: Similar to MySQL, it performs equivalence judgment.

  • GIN index: A type for multiple values ​​of a field, such as an array type.

Create index

image.png

Prepare a large amount of test data to easily check the indexing effect

-- 测试索引效果
create table tb_index(
    id bigserial primary key,
    name varchar(64),
    phone varchar(64)[]
);

-- 添加300W条数据测试效果
do $$
declare
    i int := 0;
begin
    while i < 3000000 loop
        i = i + 1;
        insert into
            tb_index
        (name,phone) 
            values
        (md5(random()::text || current_timestamp::text)::uuid,array[random()::varchar(64),random()::varchar(64)]);
    end loop;
end;
$$ language plpgsql;

In the absence of an index, first perform an equivalent query based on name, check the time, and check the execution plan at the same time.

-- c0064192-1836-b019-c649-b368c2be31ca
select * from tb_index where id = 2222222;
select * from tb_index where name = 'c0064192-1836-b019-c649-b368c2be31ca';
explain select * from tb_index where name = 'c0064192-1836-b019-c649-b368c2be31ca';
-- Seq Scan  代表全表扫描 
-- 时间大致0.3秒左右

If there is an index, do an equivalent query based on the name, check the time, and check the execution plan at the same time.

-- name字段构建索引(默认就是b-tree)
create index index_tb_index_name on tb_index(name);
-- 测试效果
select * from tb_index where name = 'c0064192-1836-b019-c649-b368c2be31ca';
explain select * from tb_index where name = 'c0064192-1836-b019-c649-b368c2be31ca';
-- Index Scan 使用索引
-- 0.1s左右

Test the GIN index effect

In the absence of an index, perform an include query based on the phone field

-- phone:{0.6925242730781953,0.8569644964711074}
select * from tb_index where phone @> array['0.6925242730781953'::varchar(64)];
explain select * from tb_index where phone @> array['0.6925242730781953'::varchar(64)];
-- Seq Scan 全表扫描
-- 0.5s左右

Build a GIN index for the phone field and query

-- 给phone字符串数组类型字段构建一个GIN索引
create index index_tb_index_phone_gin on tb_index using gin(phone);
-- 查询
select * from tb_index where phone @> array['0.6925242730781953'::varchar(64)];
explain select * from tb_index where phone @> array['0.6925242730781953'::varchar(64)];
-- Bitmap Index 位图扫描
-- 0.1s以内完成

materialized view

The previous ordinary view is essentially a SQL statement. An ordinary view is not stored on the local disk. Every time the view is queried, this SQL is executed, which has some efficiency problems.

As you can tell from the name, materialized views must persist a copy of data. The usage routines and views are basically the same. In this way, querying the materialized view is equivalent to querying a separate table. Compared with the previous ordinary views, materialized views do not need to query complex SQL every time. Each query is a piece of data (table) in the real physical storage address, and indexes and other information can be set separately to improve the materialized view. query efficiency.

But there are advantages and disadvantages, and the update time is not easy to control. If the updates are frequent, the pressure on the database will not be small. If updates are infrequent, data will be delayed and the real-time performance will be poor.

If you want to update the materialized view, you can use a trigger. When the data in the original table is written, you can use the trigger to perform the synchronization of the materialized view. Or complete data synchronization of materialized views based on scheduled tasks.
image.png

-- 构建物化视图
create materialized view mv_test as (select id,name,price from test);
-- 操作物化视图和操作表的方式没啥区别。
select * from mv_test;
-- 操作原表时,对物化视图没任何影响
insert into test values (4,'月饼',50,10);
-- 物化视图的添加操作(不允许写物化视图),会报错
insert into mv_test values (5,'大阅兵',66);

PostgreSQL provides two methods for synchronizing materialized views, one is full update and the other is incremental update.

Full syntax update, no restrictions, direct execution, full update

-- 查询原来物化视图的数据
select * from mv_test;
-- 全量更新物化视图
refresh materialized view mv_test;
-- 再次查询物化视图的数据
select * from mv_test;

Incremental update, incremental update requires a unique identifier to determine which ones are incremental, and there will also be version number constraints on the row data.

-- 查询原来物化视图的数据
select * from mv_test;
-- 给物化视图添加唯一索引。
create unique index index_mv_test on mv_test(id);
-- 增量更新物化视图
refresh materialized view concurrently mv_test;
-- 再次查询物化视图的数据
select * from mv_test;
-- 增量更新时,即便是修改数据,物化视图的同步,也会根据一个xmin和xmax的字段做正常的数据同步

update test set name = '汤圆' where id = 5;
insert into test values (5,'猪头肉',99,40);
select * from test;

Guess you like

Origin blog.csdn.net/qq_28314431/article/details/132872977