I’m doing a project at home and I’m still learning, so I need some help, suggestions on how to make my relations better.(PostgreSQL)
I have 6 tables: enterprise, servicearea, service, service_aggregated,enterprise_serviceara_worker, worker
enterprise: info about enterprise
servicearea: main category(example nails)
service: sub category(example nail polish, filing)
service_aggregated: price and duration of treatment for a specific service and a specific enterprise
enterprise_serviceara_worker: realation between enterprise, service area, and worker(this way I can see which enterprise owns which service area and who works in that enterprise )
Please see below tables, relations and one query
CREATE TABLE IF NOT EXISTS enterprise.servicearea
(
id SERIAL,
name character varying COLLATE pg_catalog."default" NOT NULL,
isactive boolean,
CONSTRAINT service_area_pkey PRIMARY KEY (id),
CONSTRAINT dont_duplicate_service_area_name UNIQUE (name)
)
CREATE TABLE IF NOT EXISTS enterprise.service
(
id SERIAL,
name character varying(100) COLLATE pg_catalog."default" NOT NULL,
serviceareaid integer,
CONSTRAINT service_pkey PRIMARY KEY (id),
CONSTRAINT dont_duplicate_servicename UNIQUE (name),
CONSTRAINT service_service_area_id_fkey FOREIGN KEY (serviceareaid)
REFERENCES enterprise.servicearea (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
CREATE TABLE IF NOT EXISTS enterprise.service_aggregated
(
service_agg_id SERIAL,
service_id integer,
enterprise_id bigint,
price bigint NOT NULL,
"interval" integer NOT NULL,
active boolean DEFAULT true,
CONSTRAINT service_aggregated_pkey PRIMARY KEY (service_agg_id),
CONSTRAINT dont_duplicate_service UNIQUE (enterprise_id, service_id),
CONSTRAINT service_aggregated_enterprise_id_fkey FOREIGN KEY (enterprise_id)
REFERENCES enterprise.enterprise (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT service_aggregated_service_id_fkey FOREIGN KEY (service_id)
REFERENCES enterprise.service (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
CREATE TABLE IF NOT EXISTS enterprise.enterprise
(
id integer NOT NULL DEFAULT nextval('enterprise.enterprise_id_seq'::regclass),
name character varying(50) COLLATE pg_catalog."default" NOT NULL,
address character varying(100) COLLATE pg_catalog."default" NOT NULL,
phone character varying(20) COLLATE pg_catalog."default" NOT NULL,
active boolean NOT NULL,
pingoo integer DEFAULT 0,
cuckoo integer DEFAULT 0,
registeredsince date DEFAULT CURRENT_DATE,
countryid integer NOT NULL,
cityid integer NOT NULL,
cityareaid integer,
citysubareaid integer,
workstart time without time zone NOT NULL,
workend time without time zone NOT NULL,
description text COLLATE pg_catalog."default",
image bytea,
CONSTRAINT enterprise_pkey PRIMARY KEY (id),
CONSTRAINT dont_duplicate_name_in_city UNIQUE (name, cityid),
CONSTRAINT dont_duplicate_phone UNIQUE (phone),
CONSTRAINT enterprise_cityareaid_fkey FOREIGN KEY (cityareaid)
REFERENCES locations.cityarea (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT enterprise_cityid_fkey FOREIGN KEY (cityid)
REFERENCES locations.cities (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT enterprise_citysubareaid_fkey FOREIGN KEY (citysubareaid)
REFERENCES locations.citysubarea (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT enterprise_countryid_fkey FOREIGN KEY (countryid)
REFERENCES locations.countries (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT work_time_valid CHECK (workstart < workend)
)
CREATE TABLE IF NOT EXISTS enterprise.enterprise_serviceara_worker
(
enterpriseid integer NOT NULL,
serviceareaid integer NOT NULL,
workerid integer NOT NULL,
CONSTRAINT enterprise_serviceara_worker_pkey PRIMARY KEY (enterpriseid, serviceareaid, workerid),
CONSTRAINT enterprise_serviceara_worker_enterpriseid_fkey FOREIGN KEY (enterpriseid)
REFERENCES enterprise.enterprise (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT enterprise_serviceara_worker_serviceareaid_fkey FOREIGN KEY (serviceareaid)
REFERENCES enterprise.servicearea (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT enterprise_serviceara_worker_workerid_fkey FOREIGN KEY (workerid)
REFERENCES public.workers (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
SELECT
e.id,
e.name,
e.image,
CONCAT(e.address, ', ', c.name) AS Address,
e.pingoo,
e.cuckoo,
e.description,
a.id,
a.name,
u.id,
u.firstname AS Name,
u.pingoo,
u.cuckoo,
u.image,
sa.id,
sa.name,
s.id,
s.name,
s_a.price,
s_a.interval
FROM
enterprise.enterprise e
INNER JOIN
locations.cities c ON c.id = e.cityid
LEFT JOIN
enterprise.enterprise_amenity ea ON ea.enterpriseid = e.id
LEFT JOIN
enterprise.amenity a ON a.id = ea.amenityid
LEFT JOIN
enterprise.enterprise_serviceara_worker esw ON esw.enterpriseid = e.id
LEFT JOIN
public.users u ON u.id = esw.workerid
INNER JOIN
enterprise.servicearea sa ON sa.id = esw.serviceareaid
INNER JOIN
enterprise.service s ON s.serviceareaid = sa.id
INNER JOIN
enterprise.service_aggregated s_a ON s_a.service_id = s.id
WHERE
e.id = 8
AND s_a.enterprise_id = e.id
AND sa.isactive = true
I’m not sure if this is good, I need suggestions from more experienced colleagues