Ash*_*ine 1 sql database-design naming design-patterns
我经常看到这种设计模式,但没有它的名称.我很想知道设计师称这种模式是什么,以及他们如何通过合理的数据库设计来实现它.
举个简单的例子,假设学生有一个年级(1-8).如果学生的成绩为7或8,那么他们可能是荣誉学生.那么你如何跟踪学生的这个位旗,知道它只适用于某些年级的学生?
我称之为数据依赖.并非所有数据依赖关系都可以通过关系分解直接或方便地建模.使用检查约束可以很容易地处理这个:
CREATE TABLE Students (
id SERIAL PRIMARY KEY, -- for example, something else in reality
grade INTEGER NOT NULL,
honors BOOLEAN,
CONSTRAINT ensure_honors_grade
CHECK((honors IS NULL AND grade < 7) OR
(honors IS NOT NULL AND grade >= 7))
);
Run Code Online (Sandbox Code Playgroud)
另一种解决方案可能是使用两个表:
CREATE TABLE Students (
id SERIAL PRIMARY KEY,
grade INTEGER NOT NULL,
CONSTRAINT id_grade_unique UNIQUE (id, grade) -- needed for FK constraint below
);
CREATE TABLE Honors (
student_id INTEGER NOT NULL,
grade INTEGER NOT NULL,
honors BOOLEAN NOT NULL,
CONSTRAINT student_fk FOREIGN KEY (student_id, grade) REFERENCES Students(id, grade),
CONSTRAINT valid_grade CHECK(grade >= 7)
);
Run Code Online (Sandbox Code Playgroud)
这种替代设计更清楚地表明了等级与是否有荣誉标志之间的关系,并为7-8级学生的进一步差异留下了空间(尽管表名应该改进).如果你只有一个属性,荣誉布尔值,那么这可能是矫枉过正.正如@BrankoDimitrijevic所提到的那样,这并不是Honors因为等级是7或8 而强制存在一行,而且你还要支付你不需要的索引.所以有权衡; 这些肯定不是唯一可能的两个设计; 布兰科还建议使用触发器.
在OO设计方面,@ Ryan是正确的,但对于正确的关系数据库设计,通常不会通过尝试识别继承模式来解决问题.这就是面向对象的观点.关注您的访问模式以及您的代码将如何获取数据始终是非常重要的,但在关系数据库设计中,首先要求数据库中的规范化和灵活性,以及第二个代码,因为总是会有多个代码库获取数据,并且您希望确保数据始终有效,无论访问代码有多么多.