DatabaseCreation: ddl_without_unnecessary_cascades.sql

File ddl_without_unnecessary_cascades.sql, 15.5 KB (added by 231133, 9 days ago)
Line 
1CREATE TABLE public.user_app (
2 user_id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
3 username varchar(20) NOT NULL UNIQUE,
4 email varchar(50) NOT NULL UNIQUE,
5 contact_phone varchar(50),
6 CONSTRAINT chk_email_format CHECK (email LIKE '%@%.%')
7);
8
9CREATE TABLE public.order_status (
10 status_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
11 status_name varchar(50) NOT NULL UNIQUE
12);
13
14CREATE TABLE public.event_status (
15 event_status_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
16 status_name varchar(50) NOT NULL UNIQUE
17);
18
19CREATE TABLE public.category (
20 id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
21 name varchar(100) NOT NULL UNIQUE
22);
23
24CREATE TABLE public.attribute (
25 attribute_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
26 name text NOT NULL,
27 data_type varchar(20) NOT NULL,
28 description text,
29 is_required boolean NOT NULL
30);
31
32CREATE TABLE public.promo_code (
33 promo_code_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
34 code varchar(64) NOT NULL UNIQUE
35);
36
37CREATE TABLE public.location_type (
38 type_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
39 type_name varchar(100) NOT NULL UNIQUE
40);
41
42CREATE TABLE public.location (
43 location_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
44 name varchar(100) NOT NULL,
45 type_id integer NOT NULL REFERENCES public.location_type(type_id) ON DELETE RESTRICT,
46 address varchar(255),
47 city varchar(255) NOT NULL,
48 capacity integer NOT NULL,
49 CONSTRAINT chk_location_capacity CHECK (capacity > 0)
50);
51
52CREATE TABLE public.section (
53 section_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
54 section_name varchar(100),
55 capacity integer NOT NULL,
56 -- Cascade because sections are physical parts of a location and have no meaning without it.
57 location_id integer NOT NULL REFERENCES public.location(location_id) ON DELETE CASCADE,
58 CONSTRAINT chk_section_capacity CHECK (capacity > 0)
59);
60
61CREATE TABLE public.seat (
62 seat_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
63 row_identifier varchar(10) NOT NULL,
64 -- Cascade because seats are contained inside a section and should disappear with that section.
65 section_id integer NOT NULL REFERENCES public.section(section_id) ON DELETE CASCADE,
66 seat_number varchar(10) NOT NULL,
67 is_accessible boolean NOT NULL,
68 is_available boolean NOT NULL
69);
70
71CREATE TABLE public.organiser (
72 organiser_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
73 company_name varchar(255) NOT NULL,
74 contact_phone varchar(50),
75 website_url varchar(255)
76);
77
78CREATE TABLE public.event (
79 event_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
80 event_status_id integer NOT NULL REFERENCES public.event_status(event_status_id) ON DELETE RESTRICT,
81 title varchar(64) NOT NULL,
82 start_datetime timestamp without time zone NOT NULL,
83 end_datetime timestamp without time zone,
84 CONSTRAINT chk_event_chronology CHECK (end_datetime > start_datetime)
85);
86
87CREATE TABLE public.event_organiser (
88 event_organiser_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
89 -- Cascade because this is only a junction row between event and organiser.
90 event_id integer NOT NULL REFERENCES public.event(event_id) ON DELETE CASCADE,
91 -- Cascade because this is only a junction row between event and organiser.
92 organiser_id integer NOT NULL REFERENCES public.organiser(organiser_id) ON DELETE CASCADE,
93 CONSTRAINT uq_event_organiser UNIQUE (event_id, organiser_id)
94);
95
96CREATE TABLE public.event_category (
97 event_category_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
98 -- Cascade because this is only a junction row between event and category.
99 event_id integer NOT NULL REFERENCES public.event(event_id) ON DELETE CASCADE,
100 -- Cascade because this is only a junction row between event and category.
101 category_id integer NOT NULL REFERENCES public.category(id) ON DELETE CASCADE
102);
103
104CREATE TABLE public.event_schedule_session (
105 schedule_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
106 -- Cascade because sessions belong to one event and should be removed when that event is removed.
107 event_id integer NOT NULL REFERENCES public.event(event_id) ON DELETE CASCADE,
108 session_title varchar(50),
109 start_time timestamp without time zone,
110 end_time timestamp without time zone,
111 section_id integer NOT NULL REFERENCES public.section(section_id) ON DELETE RESTRICT,
112 CONSTRAINT chk_session_chronology CHECK (end_time > start_time)
113);
114
115CREATE TABLE public.field (
116 field_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
117 field_name varchar(50) NOT NULL
118);
119
120CREATE TABLE public.exhibitor (
121 exhibitor_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
122 name varchar(50) NOT NULL,
123 surname varchar(50),
124 field_id integer NOT NULL REFERENCES public.field(field_id) ON DELETE RESTRICT
125);
126
127CREATE TABLE public.exhibitor_event_schedule_session (
128 exhibitor_event_schedule_session_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
129 -- Cascade because this assignment row should disappear when the exhibitor is deleted.
130 exhibitor_id integer NOT NULL REFERENCES public.exhibitor(exhibitor_id) ON DELETE CASCADE,
131 -- Cascade because this assignment row should disappear when the session is deleted.
132 event_schedule_session_id integer NOT NULL REFERENCES public.event_schedule_session(schedule_id) ON DELETE CASCADE,
133 start_time timestamp without time zone NOT NULL,
134 end_time timestamp without time zone NOT NULL,
135 CONSTRAINT chk_exhibitor_session_chronology CHECK (end_time > start_time),
136 CONSTRAINT uq_exhibitor_session UNIQUE (exhibitor_id, event_schedule_session_id)
137);
138
139CREATE TABLE public.discount (
140 discount_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
141 -- Cascade because discounts are event-specific and should disappear with the event.
142 event_id integer NOT NULL REFERENCES public.event(event_id) ON DELETE CASCADE,
143 discount_percent numeric(5,2) NOT NULL,
144 promo_code_id integer REFERENCES public.promo_code(promo_code_id) ON DELETE SET NULL,
145 CONSTRAINT chk_discount_percent CHECK (discount_percent >= 0 AND discount_percent <= 100)
146);
147
148CREATE TABLE public.order_cart (
149 order_id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
150 user_id bigint NOT NULL REFERENCES public.user_app(user_id) ON DELETE RESTRICT,
151 discount_id integer REFERENCES public.discount(discount_id) ON DELETE SET NULL,
152 status_id integer NOT NULL REFERENCES public.order_status(status_id) ON DELETE RESTRICT,
153 created_at timestamp without time zone NOT NULL,
154 total_price numeric(12,2) NOT NULL,
155 CONSTRAINT chk_order_total CHECK (total_price >= 0)
156);
157
158CREATE TABLE public.payment_method (
159 method_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
160 method_name varchar(50) NOT NULL UNIQUE
161);
162
163CREATE TABLE public.payment (
164 payment_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
165 order_id bigint NOT NULL REFERENCES public.order_cart(order_id) ON DELETE RESTRICT,
166 method_id integer NOT NULL REFERENCES public.payment_method(method_id) ON DELETE RESTRICT,
167 amount_paid numeric(12,2),
168 processed_at timestamp without time zone NOT NULL,
169 transaction_id varchar(255) NOT NULL,
170 is_refunded boolean,
171 CONSTRAINT chk_payment_amount CHECK (amount_paid >= 0)
172);
173
174CREATE TABLE public.refund_request (
175 refund_request_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
176 reason text,
177 requested_at timestamp without time zone NOT NULL,
178 accepted_at timestamp without time zone,
179 user_id bigint NOT NULL REFERENCES public.user_app(user_id) ON DELETE RESTRICT,
180 payment_id integer NOT NULL REFERENCES public.payment(payment_id) ON DELETE RESTRICT
181);
182
183CREATE TABLE public.review (
184 review_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
185 -- Cascade because reviews are user-generated content and should be removed with the user.
186 user_id bigint NOT NULL REFERENCES public.user_app(user_id) ON DELETE CASCADE,
187 -- Cascade because reviews are attached to one event and should disappear if the event is removed.
188 event_id integer NOT NULL REFERENCES public.event(event_id) ON DELETE CASCADE,
189 star_rating integer NOT NULL,
190 review_text text,
191 created_at timestamp without time zone NOT NULL,
192 CONSTRAINT chk_star_rating CHECK (star_rating >= 1 AND star_rating <= 5),
193 CONSTRAINT uq_user_event_review UNIQUE (user_id, event_id)
194);
195
196CREATE TABLE public.ticket_type (
197 ticket_type_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
198 -- Cascade because ticket types are definitions owned by a specific event.
199 event_id integer NOT NULL REFERENCES public.event(event_id) ON DELETE CASCADE,
200 tier_name varchar(100) NOT NULL,
201 total_allocated integer NOT NULL,
202 presale_start timestamp without time zone,
203 presale_end timestamp without time zone,
204 CONSTRAINT chk_presale_chronology CHECK (presale_end > presale_start),
205 CONSTRAINT chk_ticket_allocated CHECK (total_allocated >= 0)
206);
207
208CREATE TABLE public.price_tier (
209 price_tier_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
210 -- Cascade because price tiers are details of one ticket type.
211 ticket_type_id integer NOT NULL REFERENCES public.ticket_type(ticket_type_id) ON DELETE CASCADE,
212 price numeric(10,2) NOT NULL,
213 valid_from timestamp without time zone NOT NULL,
214 valid_to timestamp without time zone NOT NULL,
215 CONSTRAINT chk_price CHECK (price >= 0),
216 CONSTRAINT chk_price_tier_chronology CHECK (valid_to > valid_from)
217);
218
219CREATE TABLE public.ticket (
220 ticket_id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
221 order_id bigint NOT NULL REFERENCES public.order_cart(order_id) ON DELETE RESTRICT,
222 ticket_type_id integer NOT NULL REFERENCES public.ticket_type(ticket_type_id) ON DELETE RESTRICT,
223 event_schedule_session_id integer NOT NULL REFERENCES public.event_schedule_session(schedule_id) ON DELETE RESTRICT,
224 lock_expires_at timestamp without time zone NOT NULL,
225 status varchar(50) NOT NULL,
226 barcode_hash varchar(255) NOT NULL UNIQUE,
227 seat_id integer REFERENCES public.seat(seat_id) ON DELETE SET NULL,
228 is_scanned boolean NOT NULL,
229 scanned_at timestamp without time zone,
230 is_presale boolean NOT NULL,
231 CONSTRAINT chk_ticket_scanned_at_consistency CHECK (
232 (is_scanned = true AND scanned_at IS NOT NULL)
233 OR
234 (is_scanned = false AND scanned_at IS NULL)
235 )
236);
237
238CREATE TABLE public.sponsor (
239 sponsor_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
240 name varchar(64) NOT NULL UNIQUE
241);
242
243CREATE TABLE public.sponsor_event (
244 sponsor_event_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
245 -- Cascade because this is only a junction row between event and sponsor.
246 event_id integer NOT NULL REFERENCES public.event(event_id) ON DELETE CASCADE,
247 -- Cascade because this is only a junction row between event and sponsor.
248 sponsor_id integer NOT NULL REFERENCES public.sponsor(sponsor_id) ON DELETE CASCADE,
249 sponsor_type varchar(64) NOT NULL,
250 sponsor_amount_paid numeric(5,2) NOT NULL,
251 CONSTRAINT chk_sponsor_amount CHECK (sponsor_amount_paid >= 0)
252);
253
254CREATE TABLE public.sponsor_type (
255 sponsor_type_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
256 sponsor_amount_paid numeric(5,2) NOT NULL,
257 type varchar(64) NOT NULL,
258 CONSTRAINT chk_sponsor_type_amount CHECK (sponsor_amount_paid >= 0)
259);
260
261CREATE TABLE public.sponsor_type_sponsor (
262 sponsor_type_sponsor_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
263 -- Cascade because this is only a junction row between sponsor and sponsor type.
264 sponsor_id integer NOT NULL REFERENCES public.sponsor(sponsor_id) ON DELETE CASCADE,
265 -- Cascade because this is only a junction row between sponsor and sponsor type.
266 sponsor_type_id integer NOT NULL REFERENCES public.sponsor_type(sponsor_type_id) ON DELETE CASCADE
267);
268
269CREATE TABLE public.staff_role (
270 staff_role_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
271 description varchar(100) NOT NULL
272);
273
274CREATE TABLE public.staff_team (
275 staff_team_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
276 team_name varchar(50) NOT NULL
277);
278
279CREATE TABLE public.staff_member (
280 staff_member_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
281 assigned_role integer NOT NULL REFERENCES public.staff_role(staff_role_id) ON DELETE RESTRICT,
282 name varchar(20) NOT NULL,
283 surname varchar(20) NOT NULL,
284 contact_phone varchar(50),
285 staff_team_id integer NOT NULL REFERENCES public.staff_team(staff_team_id) ON DELETE RESTRICT
286);
287
288CREATE TABLE public.staff_team_event_schedule (
289 schedule_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
290 shift_start timestamp without time zone NOT NULL,
291 shift_end timestamp without time zone NOT NULL,
292 is_available boolean DEFAULT true NOT NULL,
293 -- Cascade because schedule rows are assignments for one staff team.
294 staff_team_id integer NOT NULL REFERENCES public.staff_team(staff_team_id) ON DELETE CASCADE,
295 -- Cascade because schedule rows are assignments for one event.
296 event_id integer NOT NULL REFERENCES public.event(event_id) ON DELETE CASCADE,
297 CONSTRAINT chk_shift_chronology CHECK (shift_end > shift_start)
298);
299
300CREATE TABLE public.subscription_location (
301 subscription_location_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
302 -- Cascade because subscriptions are user-owned preference rows.
303 user_id bigint NOT NULL REFERENCES public.user_app(user_id) ON DELETE CASCADE,
304 -- Cascade because a subscription to a deleted location has no meaning.
305 location_id integer NOT NULL REFERENCES public.location(location_id) ON DELETE CASCADE,
306 created_at timestamp without time zone NOT NULL,
307 CONSTRAINT uq_user_location_sub UNIQUE (user_id, location_id)
308);
309
310CREATE TABLE public.subscription_organiser (
311 subscription_organiser_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
312 -- Cascade because subscriptions are user-owned preference rows.
313 user_id bigint NOT NULL REFERENCES public.user_app(user_id) ON DELETE CASCADE,
314 -- Cascade because a subscription to a deleted organiser has no meaning.
315 organiser_id integer NOT NULL REFERENCES public.organiser(organiser_id) ON DELETE CASCADE,
316 created_at timestamp without time zone NOT NULL,
317 CONSTRAINT uq_user_organiser_sub UNIQUE (user_id, organiser_id)
318);
319
320CREATE TABLE public.value (
321 value_id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
322 -- Cascade because EAV values depend on the attribute definition.
323 attribute_id integer NOT NULL REFERENCES public.attribute(attribute_id) ON DELETE CASCADE,
324 value_string text,
325 value_int integer,
326 value_datetime timestamp without time zone,
327 value_bool boolean,
328 -- Cascade because EAV values are extra properties of one event.
329 event_id integer NOT NULL REFERENCES public.event(event_id) ON DELETE CASCADE
330);
331
332CREATE TABLE public.waitlist_entry (
333 waitlist_id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
334 joined_at timestamp without time zone NOT NULL,
335 status varchar(20) NOT NULL,
336 notified_at timestamp without time zone,
337 expires_at timestamp without time zone,
338 -- Cascade because waitlist entries are user-owned temporary rows.
339 user_id bigint NOT NULL REFERENCES public.user_app(user_id) ON DELETE CASCADE,
340 -- Cascade because waitlist entries are for one concrete session.
341 event_schedule_session_id integer NOT NULL REFERENCES public.event_schedule_session(schedule_id) ON DELETE CASCADE,
342 CONSTRAINT uq_user_session_waitlist UNIQUE (user_id, event_schedule_session_id)
343);