All templates

Survey and form builder

Surveys with ordered questions and choices, respondents, responses and the answers to each question.

6 tables · 7 relationships · forms, saas

Survey and form builder diagram
PostgreSQL DDL
CREATE TYPE question_kind AS ENUM ('short_text', 'long_text', 'single_choice', 'multiple_choice', 'rating', 'date');

CREATE TABLE owners (
    id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
    email text NOT NULL UNIQUE
);

CREATE TABLE surveys (
    id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
    owner_id uuid NOT NULL,
    title text NOT NULL,
    published boolean DEFAULT false NOT NULL,
    closes_at timestamptz
);
CREATE INDEX surveys_owner_id_idx ON surveys (owner_id);

CREATE TABLE questions (
    id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
    survey_id uuid NOT NULL,
    kind question_kind NOT NULL,
    prompt text NOT NULL,
    required boolean DEFAULT false NOT NULL,
    position int NOT NULL,
    UNIQUE (survey_id, position)
);

CREATE TABLE choices (
    id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
    question_id uuid NOT NULL,
    label text NOT NULL,
    position int NOT NULL
);
CREATE INDEX choices_question_id_idx ON choices (question_id);

CREATE TABLE responses (
    id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
    survey_id uuid NOT NULL,
    respondent_email text,
    submitted_at timestamptz DEFAULT now() NOT NULL
);
CREATE INDEX responses_survey_id_idx ON responses (survey_id);

CREATE TABLE answers (
    id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
    response_id uuid NOT NULL,
    question_id uuid NOT NULL,
    text_value text,
    choice_id uuid,
    number_value numeric
);
CREATE INDEX answers_response_idx ON answers (response_id);
CREATE INDEX answers_question_id_idx ON answers (question_id);
CREATE INDEX answers_choice_id_idx ON answers (choice_id);

ALTER TABLE surveys ADD FOREIGN KEY (owner_id) REFERENCES owners (id) ON DELETE CASCADE;

ALTER TABLE questions ADD FOREIGN KEY (survey_id) REFERENCES surveys (id) ON DELETE CASCADE;

ALTER TABLE choices ADD FOREIGN KEY (question_id) REFERENCES questions (id) ON DELETE CASCADE;

ALTER TABLE responses ADD FOREIGN KEY (survey_id) REFERENCES surveys (id) ON DELETE CASCADE;

ALTER TABLE answers ADD FOREIGN KEY (response_id) REFERENCES responses (id) ON DELETE CASCADE;

ALTER TABLE answers ADD FOREIGN KEY (question_id) REFERENCES questions (id) ON DELETE CASCADE;

ALTER TABLE answers ADD FOREIGN KEY (choice_id) REFERENCES choices (id) ON DELETE SET NULL;