我已经实现了以下存储关系拓扑的方法:
1,总连接关系表
大多数SQL引擎通常无法在哪个连接上执行连接。
2.特定于关系的联结表
可以针对哪个连接执行连接。
3.在两个双向对象的text
字段中存储相关对象的列表/字符串映射。
为了启用sql引擎的联接,有可能编写一个自定义模块,如果student_keys的内容只是[1,3]
,即与显式Student
类型的关系,则该模块将变得更加容易。
在以下情况下的问题如下:
我看不到联结表的要点。例如,我看不到连接表声称缓解的以下参数确实存在任何问题:
没有双向关系中的数据孤立或任何
与
keys
字段的关系,因为一个递归保存并且一个可以强制执行其他操作(删除,更新)相当容易)
我不是在征求您对最佳实践的个人意见,也不是在规范化方面发表任何类似邪教的言论。
明确的问题如下:
keys
字段未提供的联结表? junction table
与keys
字段的唯一实现差异如下:搜索以下性质的查询时,您需要使用自定义索引实现或其他一些合理的实现来与
keys
字段进行匹配:与搜索联结表的索引列然后选择适当的类相反。
我一直无法找到答案,为什么出于某种原因,联结表在逻辑上更可取。 我并不是在说这种情况,或者我以一种或另一种方式有宗教偏爱,这一点可以证明,我通过多种方式实现了这一目标。 我的问题是我不知道它们是什么。
最佳答案
我的看法是,您有多个实体
CREATE TABLE StudentType
(
Id Int PRIMARY KEY,
Name NVarChar(50)
);
INSERT StudentType VALUES
(
(1, 'Basic'),
(2, 'Advanced'),
(3, 'SomeOtherCategory')
);
CREATE TABLE Student
(
Id Int PRIMARY KEY,
Name NVarChar(200),
OtherAttributeCommonToAllStudents Int,
Type Int,
CONSTRAINT FK_Student_StudentType
FOREIGN KEY (Type) REFERENCES StudentType(Id)
)
CREATE TABLE StudentAdvanced
(
Id Int PRIMARY KEY,
AdvancedOnlyAttribute Int,
CONSTRIANT FK_StudentAdvanced_Student
FOREIGN KEY (Id) REFERENCES Student(Id)
)
CREATE TABLE StudentSomeOtherCategory
(
Id Int PRIMARY KEY,
SomeOtherCategoryOnlyAttribute Int,
CONSTRIANT FK_StudentSomeOtherCategory_Student
FOREIGN KEY (Id) REFERENCES Student(Id)
)
Student
表上都有列。 StudentType
表中。 Student<TypeName>
表来存储其特定属性。这些表与Student
具有可选的一对一关系。 我认为您的“稻草人”联结表是EAV反模式的部分实现,只有在您不知道需要建模哪些属性的情况下才有意义,即您的数据将完全是非结构化的。当这是真正的要求时,关系数据库开始显得不太理想。在那些情况下,请考虑使用NOSQL/Document数据库替代方案。
联结表在以下情况下很有用。
假设我们向模型添加了一个Class实体。
CREATE TABLE Class
(
Id Int PRIMARY KEY,
...
)
我们想在学生和类(class)之间存储多对多关系,这是可以想象的。
CREATE TABLE Registration
(
Id Int PRIMARY KEY,
StudentId Int,
ClassId Int,
CONSTRAINT FK_Registration_Student
FOREIGN KEY (StudentId) REFERENCES Student(Id),
CONSTRAINT FK_Registration_Class
FOREIGN KEY (ClassId) REFERENCES Class(Id)
)
该实体将是存储与学生注册类(class)特别相关的属性的正确位置,例如,可能是完成标志。其他数据自然会与此交汇处相关,也许是类(class)特定的出勤记录或成绩历史记录。
如果您不以此方式关联
Class
和Student
,您将如何选择类(class)中的所有学生以及学生阅读的所有类(class)。在性能方面,可以通过键列上的索引轻松优化此操作。当存在不带任何属性的多对多房地产时,我从逻辑上同意,联结表不必存在。但是,在关系数据库中,联结表仍然是有用的物理方法,也许像这样,
CREATE TABLE StudentClass
(
StudentId Int,
ClassId Int,
CONSTRAINT PK_StudentClass PRIMARY KEY (ClassId, StudentId),
CONSTRAINT FK_Registration_Student
FOREIGN KEY (StudentId) REFERENCES Student(Id),
CONSTRAINT FK_Registration_Class
FOREIGN KEY (ClassId) REFERENCES Class(Id)
)
这允许简单的查询,例如
// students in a class?
SELECT StudentId
FROM StudentClass
WHERE ClassId = @classId
// classes read by a student?
SELECT ClassId
FROM StudentClass
WHERE StudentId = @studentId
另外,这提供了一种简单的方法来部分或完全从任一方面管理关系,这对于关系数据库开发人员来说是熟悉的,并且可以由查询优化器查询。