I have created two tables in postgresql as follows:
CREATE TABLE legals.cashaccount
(
cashaccid serial NOT NULL,
cashserial bigint NOT NULL DEFAULT nextval('legals.global_id_sequence'::regclass),
memo character varying(50) NOT NULL,
credit numeric(255,0),
debit numeric(255,0),
transactdate timestamp without time zone,
CONSTRAINT cashaccount_pkey PRIMARY KEY (cashaccid)
)
WITH (
OIDS=FALSE
);
ALTER TABLE legals.cashaccount
OWNER TO postgres;
and
CREATE TABLE legals.ledgeraccount
(
ledgerid bigserial NOT NULL,
cashaccid integer NOT NULL,
memo character varying(50) NOT NULL,
credit numeric(255,0),
debit numeric(255,0),
cashserial bigint NOT NULL,
clientserial bigint NOT NULL,
clientaccid bigint NOT NULL,
transactdate timestamp without time zone,
CONSTRAINT ledgeraccount_pkey PRIMARY KEY (ledgerid)
)
INHERITS (legals.cashaccount)
WITH (
OIDS=FALSE
);
ALTER TABLE legals.ledgeraccount
OWNER TO postgres;
However, I find that while table ledgeraccount inherits the structure of table cashaccount. Any data inserted into cash account is not inherited by ledgeraccount. Does this mean that table inheritance in postgresql only applies to the structural part of the tables and not to data contained in the tables?
I find table inheritance in postgresql odd for instance ledgeraccount will inherit structures of cashaccount but not any data inserted into cashaccount. However any data inserted into the child table ledgeraccount will be inherited by the parent table cash account. Further research by watching Meet PostgreSQL by Pluralsight by Xavier Shay section on inheritance clarified the issue.
Related
On IBM Db2 on Cloud I have imported a script. I created a new schema under which I want to have the new tables created, but when I run the script, it keeps trying to create the tables in a previous schema. Not sure how to get the scripts to create the tables in the new schema.
I have tried the below script without the .SQL_GROUPING_SORTING and it tries to add the tables to a different schema. I have changed the default schema in the Run SQL window within db2 to SQL_GROUPING_SORTING and am now getting the error
""KZF72118" does not have the privilege to perform operation "IMPLICIT CREATE SCHEMA".. SQLCODE=-552, SQLSTATE=42502, DRIVER=4.26.14"
DDL statement for table 'HR' database:
CREATE TABLE EMPLOYEES.SQL_GROUPING_SORTING (
EMP_ID CHAR(9) NOT NULL,
F_NAME VARCHAR(15) NOT NULL,
L_NAME VARCHAR(15) NOT NULL,
SSN CHAR(9),
B_DATE DATE,
SEX CHAR,
ADDRESS VARCHAR(30),
JOB_ID CHAR(9),
SALARY DECIMAL(10,2),
MANAGER_ID CHAR(9),
DEP_ID CHAR(9) NOT NULL,
PRIMARY KEY (EMP_ID));
CREATE TABLE JOB_HISTORY.SQL_GROUPING_SORTING (
EMPL_ID CHAR(9) NOT NULL,
START_DATE DATE,
JOBS_ID CHAR(9) NOT NULL,
DEPT_ID CHAR(9),
PRIMARY KEY (EMPL_ID,JOBS_ID));
CREATE TABLE JOBS.SQL_GROUPING_SORTING (
JOB_IDENT CHAR(9) NOT NULL,
JOB_TITLE VARCHAR(15) ,
MIN_SALARY DECIMAL(10,2),
MAX_SALARY DECIMAL(10,2),
PRIMARY KEY (JOB_IDENT));
CREATE TABLE DEPARTMENTS.SQL_GROUPING_SORTING (
DEPT_ID_DEP CHAR(9) NOT NULL,
DEP_NAME VARCHAR(15) ,
MANAGER_ID CHAR(9),
LOC_ID CHAR(9),
PRIMARY KEY (DEPT_ID_DEP));
CREATE TABLE LOCATIONS.SQL_GROUPING_SORTING (
LOCT_ID CHAR(9) NOT NULL,
DEP_ID_LOC CHAR(9) NOT NULL,
PRIMARY KEY (LOCT_ID,DEP_ID_LOC));
With the Db2 on Cloud Lite Plan
The Lite plan uses one database schema.
So the only schema you can use is the one that matches your user name. In your case this would be KZF72118
Create your tables with out a schema name, and they will be created in schema KZF72118.
You would need to use one of the other plans to remove this restriction
I'm trying to implement an Audit table design in PostgreSQL, where I have different types of user id's that can be audited.
Let's say I have a table named admins (which belong to an organization), and table superadmins (which don't).
CREATE TABLE example.organizations (
id SERIAL UNIQUE,
company_name varchar(50) NOT NULL UNIQUE,
phone varchar(20) NOT NULL check (phone ~ '^[0-9]+$')
);
and an example of a potential admin design
CREATE TABLE example.admins (
id serial primary_key,
admin_type varchar not null,
#... shared data
check constraint admin_type in ("super_admins", "regular_admins")
);
CREATE TABLE example.regular_admins (
id integer primary key,
admin_type varchar not null default "regular_admins"
organization_id integer references example.organizations(id),
#... other regular admin fields
foreign key (id, admin_type) references example.admins (id, admin_type),
check constraint admin_type = "regular_admins"
);
CREATE TABLE example.super_admins (
id integer primary key,
admin_type varchar not null default "super_admins"
#... other super admin fields
foreign key (id, admin_type) references example.admins (id, admin_type),
check constraint admin_type = "super_admins"
);
Now an audit table
CREATE TABLE audit.organizations (
audit_timestamp timestamp not null default now(),
operation text,
admin_id integer primary key,
before jsonb,
after jsonb,
);
This calls for inheritance or polymorphism at some level, but I'm curious about how to design it. I've heard that using PostgreSQL's inheritance functionality is not always a great way to go, although I'm finding it to fit this use case.
I'll need to be able to reference a single admin id in the trigger that updates the audit table, and it would be nice to be able to get the admin information when selecting from the audit table without using multiple queries.
Would it be better to use PostgreSQL inheritance or are there other ideas I haven't considered?
I wouldn't say that it calls for inheritance or polymorphism. Admins and superadmins are both types of user, whose only difference is that the former belong to an organization. You can represent this with a single table and a nullable foreign key. No need to overcomplicate matters. Especially if you're using a serial as your primary key type: bad things happen if you confuse admin #2 for superadmin #2.
There are a lot of PostgreSQL inheritance questions on SO, but I wanted to be clear about my particular case. Suppose I have the following tables:
CREATE TABLE abstract_person (
id bigint PRIMARY KEY,
ver int NOT NULL,
code varchar NOT NULL,
id_country bigint NOT NULL,
...
);
CREATE TABLE abstract_person_phone (
id bigint PRIMARY KEY,
ver int NOT NULL,
phone varchar NOT NULL,
id_abstract_person bigint NOT NULL
);
CREATE TABLE individual (
first_name varchar NOT NULL,
last_name varchar NOT NULL,
...
CONSTRAINT individual_pkey PRIMARY KEY (id),
CONSTRAINT individual_id_country_fkey FOREIGN KEY (id_country) REFERENCES country (id),
CONSTRAINT individual_unique UNIQUE (code) DEFERRABLE INITIALLY DEFERRED
) INHERITS (abstract_person);
There will be more inheriting tables, individual is just one example. The table abstract_person won't ever be written to directly. Am I correct in the following assumptions:
Child tables do not inherit unique, primary key, and foreign key constraints, but I have resolved that by declaring those constraints on child table directly.
About enforcing referential integrity between abstract_person and abstract_person_phone tables, I can do that with triggers. I can't use a trigger on parent table, I'd have to attach it to every child table, but I can use a single trigger function, like so:
CREATE OR REPLACE FUNCTION person_deleted() RETURNS trigger AS $BODY$
BEGIN
DELETE FROM abstract_person_phone WHERE id_abstract_person = OLD.id;
RETURN OLD;
END;
$BODY$ LANGUAGE plpgsql;
CREATE TRIGGER individual_deleted_trigger AFTER DELETE ON individual
FOR EACH ROW EXECUTE PROCEDURE person_deleted();
Yes, you're completely right. All these constraints are not
propagated to child tables.
As for triggers, you can use them on child tables as you wrote. And you could use a trigger on the parent table that would decide in which of the child tables it should put data on an insert query (or retrieve on select) based on some conditions
I wanted to use timetravel function (F.39. spi, PostgreSQL 9.1 Documentation) in my application, however it doesn't seem to work properly for me. With inserting rows into table everything works just fine, I get start and stop date properly, but when I'm trying to update those rows postgres gives me error about violating of PRIMARY KEY constraint. He's trying to insert a tuple with the same primary id as previous tuple...
It's insane to remove primary key constraints from all tables in the database but it's the functionality I need. So maybe you have some expierience with timetravel?
Any sort of help will be appreciated. Thanks in advance.
DDL:
CREATE TABLE cities
(
city_id serial NOT NULL,
state_id integer,
name character varying(80) NOT NULL,
start_date abstime,
stop_date abstime,
CONSTRAINT pk_cities PRIMARY KEY (city_id ),
CONSTRAINT fk_cities_states FOREIGN KEY (state_id)
REFERENCES states (state_id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
-- Trigger: time_travel on cities
-- DROP TRIGGER time_travel ON cities;
CREATE TRIGGER time_travel
BEFORE INSERT OR UPDATE OR DELETE
ON cities
FOR EACH ROW
EXECUTE PROCEDURE timetravel('start_date', 'stop_date');
STATEMENT GIVEN:
INSERT INTO cities(
state_id, name)
VALUES (20,'Paris');
and that's ok. I get start_date and stop_date.
But by:
UPDATE cities SET name='Rome' WHERE name='Paris'
I get error- described earlier.
Schema of states
-- Table: states
-- DROP TABLE states;
CREATE TABLE states
(
state_id serial NOT NULL, -- unikatowy numer wojewodztwa
country_id integer, -- identyfikator panstwa, w ktorym znajduje sie wojewodztwo
name character varying(50), -- nazwa wojewodztwa
CONSTRAINT pk_states PRIMARY KEY (state_id ),
CONSTRAINT uq_states_state_id UNIQUE (state_id )
)
WITH (
OIDS=FALSE
);
Unfortunately,as a new user I'm not allowed to post images here.
You can see them there:
Sample data from table cities: korpusvictifrew.cba.pl/postgres_cities.png
Sample data from table states: korpusvictifrew.cba.pl/states_data.png
Time travel converts an UPDATE into an UPDATE of the old record's stop_date and an INSERT of a new one with the changed data plus an infinity stop_date. You can't have more than one record for city_id due to pk_cities. The time travel triggers do not allow you to break that requirement.
You cannot use this:
CONSTRAINT pk_cities PRIMARY KEY (city_id )
You must use this
CONSTRAINT pk_cities PRIMARY KEY (city_id, stop_date)
Is there no easy way to do this without sequences and triggers? I have average SQL skills, and I want to use the industry standard method for pl/sql (PostgreSQL). I'm basically converting over this example table from Spring Security:
create table group_members (
id bigint generated by default as identity(start with 0) primary key,
username varchar(50) not null,
group_id bigint not null,
constraint fk_group_members_group foreign key(group_id) references groups(id));
What I have so far:
CREATE TABLE auth_group_members (
id NUMBER,
username VARCHAR(50) NOT NULL,
group_id NUMBER NOT NULL,
CONSTRAINT "FK_AuthGroupMembers" FOREIGN KEY(group_id) REFERENCES auth_groups(id)
);
The standard way would be to use serial or bigserial:
The data types serial and bigserial are not true types, but merely a notational convenience for creating unique identifier columns (similar to the AUTO_INCREMENT property supported by some other databases).
[...]
Thus, we have created an integer column and arranged for its default values to be assigned from a sequence generator.
So you'd create the table with something like this:
CREATE TABLE auth_group_members (
id bigserial primary key,
username VARCHAR(50) NOT NULL,
group_id NUMBER NOT NULL,
CONSTRAINT "FK_AuthGroupMembers" FOREIGN KEY(group_id) REFERENCES auth_groups(id)
);
The serial and bigserial types do create a sequences behind the scenes but you never have to work with the sequence directly.
In PostgreSQL 10 you can use identity columns. Here is example:
create table group_members (
id bigint generated by default as identity(start with 1) primary key,
username varchar(50) not null,
group_id bigint not null
);
Additionally:
Good article about identity columns vs serial.
PostgreSQL documentation for more info (Ctrl+F and search "AS IDENTITY").