Pre*_*ids 5 postgresql database-design
我正在使用 Postgres 9.2 开发一个测验应用程序,在该应用程序中,我向用户展示了一系列问题并记录了他们的答案。
这些问题可以有多种形式——它们可能是多项选择(什么是 2 + 2?A:2。B:3。C:4),或者它们可能需要用户自己计算答案,在这种情况下我需要将他们的输入限制为“440”或“1/2”或“.333”之类的内容。一些问题可能会提示用户输入一篇文章。而且,当然,我以后可能需要添加更多类型的问题。
我设想的表格,以简化的形式,是这样的:
CREATE TABLE problems
(
problem_id serial NOT NULL PRIMARY KEY,
problem_type text NOT NULL, -- Refers to a lookup table
answer_letter text, -- If not null, refers to the correct answer in the answers table below.
response text -- If not null, represents a correct answer to be input, like '0.4'
);
CREATE TABLE answers
(
problem_id integer, -- Foreign key
answer_letter text,
content text,
CONSTRAINT answers_pkey PRIMARY KEY (problem_id, answer_letter)
)
CREATE TABLE questions
(
user_id integer,
created_at timestamptz,
problem_id integer, -- Foreign key
answer_letter text,
response text,
CONSTRAINT questions_pkey PRIMARY KEY (user_id, created_at)
);
Run Code Online (Sandbox Code Playgroud)
因此,问题表将具有各种约束以确保:
这足够干净,并且可以很好地约束问题表。我可能会使用 enum 而不是 question_type 的查找表,因为无论如何它的所有可能值都已经被烘焙到模式中。
我的困难是,如何约束问题表?它的约束将非常相似(我不希望为引用论文问题的问题提供 answer_letter,等等)。我能想到几个选择:
我觉得我的建模方法存在问题,导致我遇到这些困难,特别是因为我遇到了几个与我模式中其他地方非常相似的情况(这个只是最容易描述的)。也许这只是一个难以建模的域,但我觉得必须有更好的方法,而且我只是没有正确规范化。
帮助?谢谢!
您正在了解标准规范化讨论中缺少的内容,即约束依赖关系。一般来说,较宽的表格比较窄的表格提供了更大的可能性。所以我的观点是,你提出的这些问题实际上突出了非规范化的充分理由。我会采用您的第一个解决方案(您现在倾向于使用的解决方案)。
在我看来,好的数据库设计通常会尽可能地规范化,但要确保包含正确数据约束所需的所有列。如果您不介意在父表上添加额外的唯一约束,您可以使用复合外键来完成其中的一些操作。利用数据约束是数据库设计的重要组成部分,不应为了理论上看起来不错的规范化而牺牲它。