-
Notifications
You must be signed in to change notification settings - Fork 0
/
schema.sql
215 lines (183 loc) · 7.07 KB
/
schema.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
-- Customers go in this table.
CREATE TABLE customers (
id bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
first_name text NOT NULL,
middle_name text,
last_name text,
marketing_consent boolean DEFAULT false NOT NULL
);
-- This is where we hold contact details for customers.
CREATE TABLE customer_contact_details (
id bigint PRIMARY KEY REFERENCES customers(id),
email text DEFAULT '' NOT NULL,
street_address text,
city text,
state text,
country text,
phone_no text
);
CREATE INDEX on customer_contact_details (email);
-- Each invoice for an order group goes in here.
CREATE TABLE invoices (
id bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
amount numeric NOT NULL,
customer bigint REFERENCES customers(id),
paid boolean DEFAULT false NOT NULL,
order_group bigint REFERENCES order_groups(id),
updated_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP
);
-- We represent order status by an enumeration.
CREATE TYPE order_status AS ENUM (
'Placed',
'Fulfilled',
'Cancelled'
);
-- Order groups aggregate large orders for multiple items.
CREATE TABLE order_groups (
id bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
status order_status,
placed_at timestamp with time zone,
updated_at timestamp with time zone,
customer bigint REFERENCES customers(id)
);
-- Table to hold orders for individual items or services.
CREATE TABLE orders (
id bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
order_group bigint REFERENCES order_groups(id),
status order_status,
placed_at timestamp with time zone,
updated_at timestamp with time zone,
item integer,
service integer
);
-- We hold payments for specific invoices in here.
CREATE TABLE payments (
id bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
tstamp timestamp with time zone NOT NULL,
amount numeric NOT NULL,
invoice bigint REFERENCES invoices(id)
);
CREATE INDEX ON payments (tstamp);
-- Our list of suppliers and their details.
CREATE TABLE suppliers (
id integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
company_name text,
state text,
country text,
phone_no text,
email text
);
-- This table holds customer service ticket details.
CREATE TABLE tickets (
id integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
content text,
status smallint,
opened_at timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL,
closed_at timestamptz
);
-- We represent the type of each email sent by an enumeration.
CREATE TYPE email_type AS ENUM (
'Invoice reminder',
'Welcome',
'Account closed',
'Happy birthday'
);
-- This table is the history of all emails sent out to customers.
CREATE TABLE sent_emails (
tstamp timestamp with time zone PRIMARY KEY DEFAULT CURRENT_TIMESTAMP
NOT NULL,
customer bigint REFERENCES customers(id),
type email_type,
invoice bigint REFERENCES invoices(id)
);
-- This table records energy usage readings for each of the branches.
CREATE TABLE energy_usage (
branch_id integer NOT NULL,
reading_time timestamptz DEFAULT CURRENT_TIMESTAMP,
reading numeric NOT NULL,
unit varchar DEFAULT 'kWh' NOT NULL
);
-- Logging of user activity for audit purposes.
CREATE TABLE public.audit_log (
what text,
who text,
id bigint,
tstamp timestamp with time zone
);
-- Data for customers and customer_contact_details tables
-- NOTE: Load data from customers_and_customer_contact_details_dump.sql
-- at https://github.com/vyruss/postgresql-mistakes/
-- Data for suppliers table
INSERT INTO suppliers (company_name, state, country, email) VALUES
('Omni Consumer Products', 'MI', 'United States of America',
('Yoyodyne',null,'Japan','[email protected]');
-- Data for orders, order_groups, invoices, payments, sent_emails tables
DO $$
DECLARE _id bigint;
DECLARE _t timestamptz;
BEGIN
SELECT CURRENT_DATE INTO _t;
FOR i IN 1 .. 50000 LOOP
INSERT INTO order_groups (status, placed_at, updated_at, customer)
VALUES ('Fulfilled',
('2023-10-18 00:01:28.000+1'::timestamptz + (i * INTERVAL '1 s')),
('2023-10-18 00:01:28.000+1'::timestamptz + (i * INTERVAL '1 s')),
TRUNC(RANDOM() * 14000 + 1)) RETURNING id INTO _id;
INSERT INTO orders (order_group, status, placed_at, updated_at,
item) VALUES
(_id, 'Fulfilled',
('2023-10-18 00:01:28.000+1'::timestamptz + (i * INTERVAL '1 s')),
('2023-10-18 00:01:28.000+1'::timestamptz + (i * INTERVAL '1 s')),
TRUNC(RANDOM() * 1000 + 1));
INSERT INTO invoices (amount, customer, paid, order_group,
created_at, updated_at) VALUES
(59.95, (SELECT customer FROM order_groups WHERE id=_id), 't', _id,
('2023-10-18 00:01:28.000+1'::timestamptz + (i * INTERVAL '1 s')),
('2023-10-18 00:01:28.000+1'::timestamptz + (i * INTERVAL '1 s')
+ INTERVAL '30 s')) RETURNING id INTO _id;
INSERT INTO payments (tstamp, amount, invoice)
VALUES (('2023-10-18 00:01:28.000+1'::timestamptz + (i * INTERVAL '1 s')
+ INTERVAL '30 s'), 59.95, _id);
END LOOP;
FOR i IN 1 .. 200000 LOOP
INSERT INTO order_groups (status, placed_at, updated_at, customer)
VALUES ('Placed', _t - INTERVAL '2 d' + (i * INTERVAL '1 s'),
_t - INTERVAL '2 d' + (i * INTERVAL '1 s'),
TRUNC(RANDOM() * 14000 + 1)) RETURNING id INTO _id;
INSERT INTO orders (order_group, status, placed_at, updated_at,
item) VALUES
(_id, 'Placed', _t - INTERVAL '2 d' + (i * INTERVAL '1 s'),
_t - INTERVAL '2 d' + (i * INTERVAL '1 s'),
TRUNC(RANDOM() * 1000 + 1));
INSERT INTO invoices (amount, customer, paid, order_group,
created_at, updated_at) VALUES
(59.95, (SELECT customer FROM order_groups WHERE id=_id), 't', _id,
_t - INTERVAL '2 d' + (i * INTERVAL '1 s'),
_t - INTERVAL '2 d' + (i * INTERVAL '1 s') + INTERVAL '30 s')
RETURNING id INTO _id;
INSERT INTO payments (tstamp, amount, invoice)
VALUES (_t - INTERVAL '2 d' + (i * INTERVAL '1 s') + INTERVAL '30 s',
59.95, _id);
END LOOP;
WITH o AS (SELECT id FROM orders ORDER BY RANDOM() LIMIT 1350 FOR UPDATE)
UPDATE orders SET item = NULL, service = 21 FROM o WHERE orders.id=o.id;
WITH i AS (SELECT id FROM invoices ORDER BY RANDOM() LIMIT 1350 FOR UPDATE)
UPDATE invoices SET paid='f' FROM i WHERE invoices.id=i.id;
WITH i AS (SELECT id, created_at, customer FROM invoices
WHERE paid='f')
INSERT INTO sent_emails (tstamp, customer, type, invoice)
SELECT i.created_at + INTERVAL '1 d', i.customer,
'Invoice reminder', i.id FROM i;
END $$ LANGUAGE plpgsql;
-- Data for tickets table
INSERT into tickets (status, content, opened_at, closed_at)
SELECT 20, 'issue text',
'2023-05-01'::timestamptz + n * (INTERVAL '1 m'),
'2023-05-01'::timestamptz + n * (INTERVAL '1 m') + INTERVAL '1 d'
FROM generate_series(1,1000000) n;
INSERT into tickets (status, content, opened_at)
SELECT 10, 'issue text',
'2024-05-01'::timestamptz + n * (INTERVAL '1 m')
FROM generate_series(1,500) n;