为小型网站定义各种内容类型之间的数据库关系 - 关于结构的建议?
Defining database relations among various content types for small website - advice on structure?
这与我在这里制作的 post 有关
最初我对 WordPress taxonomies
感兴趣,但我对自己的案例思考得越多,我就越认为 custom table
方法有意义。
所以我很好奇是否有任何数据库专家可以根据我的情况就 table 结构向我提供建议:
我正在设置我的网站,以便我可以教吉他 courses
。也许重要的是,我不会有很多课程。也许 4-8。
在给定的course
下,我有
Course 1
Lesson 1.1
Topic 1.1.1
Quiz 1.1.1.1
Quiz 1.1.1.2
Forum Topic 1.1.1.1
Topic 1.1.2
Quiz 1.1.2.1
Exercise 1.1.2.1
etc
Course 2
Lesson 2.1
Topic 2.1.1
Quiz 2.1.1.1
Forum Topic 2.1.1.1
Topic 2.1.2
etc
etc
我还使用课程论坛(BBPress
,它有自己的分类系统),有时需要将个别论坛主题与课程主题联系起来。
我需要做的查询类型是
- 给我一个课程的所有课程
- 给我一节课的所有主题
- 给我一个主题的所有测验
- 给我一节课的所有测验(这意味着该课主题下的测验)
- 给我一门课程的所有测验(这意味着课程中所有主题的所有测验)
- 与上面的测验相同,但用于论坛主题
你可能明白了。
这是示例数据集:
CREATE TABLE `posts` (
`ID` bigint(20) UNSIGNED NOT NULL,
`post_title` text COLLATE utf8mb4_unicode_520_ci NOT NULL,
`post_parent` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
`post_type` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'post'
) ;
INSERT INTO posts
(ID, post_type, post_title, post_parent)
VALUES
(1, 'course', 'Course 1', 0),
(2, 'lesson', 'Lesson 1.1', 0),
(3, 'course-topic', 'Topic 1.1.1', 0),
(4, 'quiz', 'Quiz 1.1.1.1', 0),
(5, 'quiz', 'Quiz 1.1.1.2', 0),
(6, 'quiz', 'Quiz 1.1.1.3', 0),
(7, 'course-topic', 'Assignment 1.1.1.1', 0),
(8, 'forum', 'Course 1 Forum', 0),
(9, 'forum', 'Course 1 Discussions', 8),
(10, 'topic', 'Discussion 1.1.1.1', 9),
(11, 'course-topic', 'Topic 1.1.2', 0),
(12, 'quiz', 'Quiz 1.1.2.1', 0),
(13, 'lesson', 'Lesson 1.2', 0),
(14, 'course-topic', 'Topic 1.2.1', 0),
(15, 'topic', 'Discussion 1.2.1.1', 9);
最初我在 WordPress 中设置了分类法 tables 并使用一些示例数据和一些示例查询制作了一个 sqlfiddle。
这里是 fiddle:
http://sqlfiddle.com/#!9/ffa734/3
获取给定课程 ID 的课程的查询涉及 4 tables,看起来像
-- get all lessons for a given course
SELECT course_rels.object_id as course_id, lesson.post_title as lesson_title FROM posts AS lesson
INNER JOIN wp_term_relationships AS lesson_rels ON lesson.ID = lesson_rels.object_id
INNER JOIN wp_term_relationships AS course_rels ON course_rels.object_id = 1
INNER JOIN wp_term_taxonomy AS lesson_tax
ON
(lesson_tax.term_taxonomy_id = lesson_rels.term_taxonomy_id
AND
lesson_tax.parent = course_rels.term_taxonomy_id)
INNER JOIN wp_terms AS terms ON terms.term_id = lesson_tax.term_id
WHERE terms.name = 'Lesson';
在我意识到使用分类法查询变得多么尴尬之后,我决定定制一个 table 给定上面的 post 数据,看起来像
CREATE TABLE `relations` (
`post_id` bigint(20) UNSIGNED NOT NULL,
`related_course` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
`related_lesson` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
`related_topic` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
`post_type` varchar(16) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT ''
);
INSERT INTO relations
(post_id, related_course, related_lesson, related_topic, post_type)
VALUES
(1, 0, 0, 0, 'course'),
(2, 1, 0, 0, 'lesson'),
(3, 1, 2, 0, 'lesson-topic'),
(4, 1, 2, 3, 'quiz'),
(5, 1, 2, 3, 'quiz'),
(6, 1, 2, 3, 'quiz'),
(7, 1, 2, 0, 'lesson-topic'),
(8, 1, 0, 0, 'forum'),
(9, 1, 0, 0, 'forum'),
(10, 1, 2, 3, 'topic'),
(11, 1, 2, 0, 'lesson-topic'),
(12, 1, 2, 11, 'quiz'),
(13, 1, 0, 0, 'lesson'),
(14, 1, 13, 0, 'lesson-topic'),
(15, 1, 13, 14, 'topic');
因此,您在 fiddle 分类查询示例中看到了我可以使用自定义 table.
进行的查询示例
问题是,我在数据库方面没有任何专业知识。我不知道我的自定义 table 方法是否只是一场等待发生的灾难。我不想重新发明任何东西——我只是厌倦了 WordPress 将数据集中在一起并迫使我在对我感兴趣的查询不重要的大量行中进行查询的方法。
考虑到人们解决此类问题的频率,是否有可靠、有效、可扩展的方法让我提取上面提到的那种关系数据?
我会将此处提出的任何其他建议解决方案添加到 fiddle 中。我想理想情况下,我必须在所有 table 中插入数千行才能真正了解查询的执行情况,但也许某些专家会立即看到最佳方法?
我在自定义 table 中看到的最大缺陷是它没有提供我选择的列名称的灵活性。如果这真的是一个糟糕的方法,那么也许我只是使用 WordPress 的分类法...
障碍物
这些障碍是智力上的;理解问题,而不是实施问题。
注意 Relational Database
标签。
是的,关系数据库将为您提供:
(a) 您正在寻找的结构,在直截了当的逻辑中,以及:
(b) 最简单的代码和最快的查询
(你所要求的,加上你未来梦想的任何东西)。
.
但是您必须使用关系概念(EF Codd 博士的关系模型)。
If you use the concepts marketed by Date; Darwen; et al, which is marketed as "relational", both the structure [a], and the code for navigation and queries [b] will be horrendous. Additionally, you will not have Relational Integrity; or Relational Power; or Relational Speed that is possible in database that complies with Codd's Relational Model.
关系模型是分层的。
三种类型的 数据层次结构 在 关系模型 .
中正式(通过事先意图和设计)
你的需求最简单,4个table一个简单的data hierarchy,体现在Relational Key中(更多,稍后)
第二种是树型(单亲型)。您在 Post 中有它,因此不需要进一步解释..
第三种是祖先树和后代树,不重复任何数据。通常称为 物料清单 结构。我们在这里不必担心,这超出了问题的范围。
Warning. The links given in the comments will take you down a complex garden path, that might possibly be relevant for the other two types of hierarchies, and in any case, very poor implementations thereof.
Eg. SQL has recursion; MySQL does not have recursion, so a hard-coded and limited method is given).
Eg. some of the methods implement the trees in concrete: if a branch is moved, the entire tree needs to be re-written.
重点是,你不需要它。 (您 可能 Post 需要它,但不是您问题的答案。)
您对数据的掌握非常好,这是练习所必需的。但是您有固定的方式来思考这些数据,这无疑是由于您尝试过的其他实施方法以及其中的要求。所以这里的需求就是把那些感知数据的方法给上去,并且遵循Relational要求:
- 感知数据,作为数据,除了数据什么都没有
没有额外的列或结构
To differentiate
Date; Darwen; et al, take the Result Set (the output of a query on Relational tables) as the starting point, as the perspective to be used when analysing and modelling the data. Which is reversing the order of nature, and guaranteed to cripple the modelling exercise (the report you want for a particular purpose vs the data as data).
Then, as if stuck in an Excel spreadsheet mindset, they add on a Record ID
field to the Result Set. Such an act cripples the modelling exercise further, because one now the false notion that a physical Record ID
identifies the logical row. It does not.
关系数据模型
如果你能放弃那个固定的观点,连同污染问题的补充,并跨越界限进入关系范式:
您将不需要 relations
table:它完全是多余的,因为关系数据库提供了所有关系(您目前已定义)。
您将不需要 IDs
,它们始终是每个文件的一个附加字段和一个附加索引。以及随之而来的可怕问题。
此外,您还将获得:
- 关系完整性(这是合乎逻辑的,与引用完整性不同,后者是 SQL 中的物理特征);
- Relational Power(您的导航和查询代码将非常简单,远端 table 的
JOINs
不需要中间 table 是 JOINed
,等等);和
- 关系速度(最少的索引)。
如果有兴趣,我最近的一些回答包含这些好处的详细信息和示例。
符号
我所有的数据模型都在 IDEF1X 中呈现,这是自 1993 年以来的关系数据库建模标准。
我的 IDEF1X Introduction 对于 关系模型 或关系模型的新手来说是必不可少的读物数据建模。
内容
而不是您在问题顶部给出的示例数据(这不是真正的示例数据,而是您希望数据显示采用的表单的简单定义),检查我给出的示例数据(当然是识别键)(蓝色)。
- 这些数字是多余的。如果确实需要,可以即时计算它们
- 不要使用数字作为Keys,因为当结构改变时,你将不得不重新编号你所有的Keys。完全没有必要。
关系模型 要求键是 "made up from the data"。数字不是。
数据层次结构为:
数据模型中的可视化
并反映在关系键中。
关系键
- 是复合体,习惯就好。 SQL 自 1984 年以来一直在处理复合键。
- 定义和实施数据层次结构。不足为奇,因为 关系模型 是分层的。
Course, Lesson, Topic, Quiz
是关键元素,短名称,不一定是代码(它们将是大型大学中的代码),它们在给定的上下文中是唯一的。
Title
将是显示在屏幕上供外部用户(潜在客户)使用的长名称。
一个Lesson
不是独立存在的,它只存在于一个Course
的上下文中。因此 Lesson
的关键是 ( Course, Lesson
)。 ID
并不能唯一标识 Lesson
(或其他任何东西)。 Courses
中可能有多个 Lesson
。
一个Topic
不是独立存在的,它只存在于一个Course
和一个Lesson
的上下文中。因此 Topic
的关键是 ( Course, Lesson, Topic
)。等等
一个Quiz
不是独立存在的,它只存在于一个Course
、一个Lesson
、一个Topic
的上下文中。因此 Quiz
的关键是 ( Course, Lesson, Topic, Quiz
)。等等
关系完整性
例如。 Quiz
被限制为特定的 Topic
,它由 (Course, Lesson, Topic
) 标识。
而基于 Record ID
的归档系统(虚假营销为 "relational")无法提供这一点,它只能将 Quiz
限制为 任何Topic
。
当然,这适用于数据层次结构中的所有 table。
Posts 与作为问题答案的结构之间的关系一点也不清楚,因此对其建模是不正确的。尽管如此,它对您很重要,因此我已根据可能性 对它进行建模 ,并保持沉默。如果你定义的更清楚,我会更新数据模型。
查询
与您在 fiddle 中或基于 Record ID
的归档系统所要求的相比,非常简单。
Get me all lessons for a course
SELECT Course,
Lesson,
Title -- Lesson Title
FROM Lesson
WHERE Course = @Course -- "Jazz"
Get me all quizzes for a course (which means all quizzes across all topics in the course)
SELECT Course,
Lesson,
Topic,
Quiz,
Title -- Quiz Title
FROM Quiz
WHERE Course = @Course -- "Jazz"
Get me all quizzes for a lesson (which means quizzes under topics for the lesson)
SELECT Course,
Lesson,
Topic,
Quiz,
Title -- Quiz Title
FROM Quiz
WHERE Course = @Course -- "Classical"
AND Lesson = @Lesson -- "Chords"
让我演示一点关系力,这里的方面是JOIN
力,消除中间tables(在Record ID
基于归档系统)。
Gimme all the Courses in which Licks are taught (meaning, in the Title
of a Topic
)
SELECT DISTINCT Course.Title,
Topic.Topic,
Topic.Title
FROM Topic
JOIN Course ON Course.Course = Topic.Course
WHERE Title LIKE "%Lick%"
如果 Course
(简称)足以识别课程,那么结果集中不需要 Course.Title
,则 Course
table可以从查询中去掉。
SELECT DISTINCT Course,
Topic,
Title
FROM Topic
WHERE Title LIKE "%Lick%"
请随时提出问题或提供说明。如果简短,请在评论中,否则更新(编辑)您的问题。
评论
The thing that I am still not sure about is order of joins. With your courses that have some text in topic example, I would have thought that the JOIN is on topics. Maybe the order doesn't matter in case of INNER JOIN?
轻微编码错误,Topic
Course
。固定。
JOIN 的顺序
- 如果你有一个商业 SQL 平台,JOIN 的顺序是无关紧要的,因为查询优化器将根据统计信息选择一个 QueryPlan,而不是代码中的任何内容,无论是否有序。
因此代码中的 JOIN 顺序应该是合乎逻辑的(请参阅我在其他最近的答案中的代码示例)。
如果没有,那么可以肯定的是,任何有助于米老鼠免费软件性能更好的东西。在这种情况下,加入顺序应该是从最小的 table 到最大的
在关系型数据库中,几乎所有的JOIN都是INNER JOIN。外部联接只需要捕获可选行(可能不存在)并显示结果集中不存在。
what do you think of taxonomies (like in WordPress) as a way of relating data? Just trying to figure out tradeoff between using what WordPress already has to offer and me doing pure custom approach.
WP中的分类法是猪粪。与其他link中给出的设置层次结构片段或具体构建层次结构的几种方法相同。
它可能足够了,因为它提供了大多数 WP 用户需要的简单关系(不是关系)功能。当你突破那个界限时,它是无望的。正如您所发现的。
你不能在 WP 中做到这一点,句号。哪里能做,就是普通,不是"custom".
基本上,虽然没有命名,但提出的问题是系统架构。对于计算机系统,架构的定义是:
适当的构成[分解;分割;代码和数据对象的规范化,以及在适当的[平台]位置部署所述对象。
Use the right tool for the job translates to: deploy the object in the right place.
应用程序所有数据的正确位置是在一个数据库中。这将使所有维护工作变得轻松。您不需要此处的位,也不需要其他位。
记住,数据库是一个单一的恢复单元。因此,您需要所有规则;约束;观点;等等,重要的是所有事务(数据库 API),在数据库中,而不是其他地方。
使用可靠的 SQL 平台意味着未来的安全。一旦数据库正常工作,您将永远不必更改它(扩展是一个单独的问题)。它与应用程序隔离,这是适当的,因此与应用程序环境中发生的任何变化隔离。
推论是:
你可以搞乱 WP 分类法,你知道它已经是有问题的;突破它的界限,因此你知道如果你不得不调整它,那将是有问题的;并推动其边界。
并且如果 WP 曾经更改他们的分类库以解决问题或增强功能,您将不得不更改数据对象;关系;等等
从我的角度来看,这不是权衡,而是架构决定。
这与我在这里制作的 post 有关
最初我对 WordPress taxonomies
感兴趣,但我对自己的案例思考得越多,我就越认为 custom table
方法有意义。
所以我很好奇是否有任何数据库专家可以根据我的情况就 table 结构向我提供建议:
我正在设置我的网站,以便我可以教吉他 courses
。也许重要的是,我不会有很多课程。也许 4-8。
在给定的course
下,我有
Course 1
Lesson 1.1
Topic 1.1.1
Quiz 1.1.1.1
Quiz 1.1.1.2
Forum Topic 1.1.1.1
Topic 1.1.2
Quiz 1.1.2.1
Exercise 1.1.2.1
etc
Course 2
Lesson 2.1
Topic 2.1.1
Quiz 2.1.1.1
Forum Topic 2.1.1.1
Topic 2.1.2
etc
etc
我还使用课程论坛(BBPress
,它有自己的分类系统),有时需要将个别论坛主题与课程主题联系起来。
我需要做的查询类型是
- 给我一个课程的所有课程
- 给我一节课的所有主题
- 给我一个主题的所有测验
- 给我一节课的所有测验(这意味着该课主题下的测验)
- 给我一门课程的所有测验(这意味着课程中所有主题的所有测验)
- 与上面的测验相同,但用于论坛主题
你可能明白了。
这是示例数据集:
CREATE TABLE `posts` (
`ID` bigint(20) UNSIGNED NOT NULL,
`post_title` text COLLATE utf8mb4_unicode_520_ci NOT NULL,
`post_parent` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
`post_type` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'post'
) ;
INSERT INTO posts
(ID, post_type, post_title, post_parent)
VALUES
(1, 'course', 'Course 1', 0),
(2, 'lesson', 'Lesson 1.1', 0),
(3, 'course-topic', 'Topic 1.1.1', 0),
(4, 'quiz', 'Quiz 1.1.1.1', 0),
(5, 'quiz', 'Quiz 1.1.1.2', 0),
(6, 'quiz', 'Quiz 1.1.1.3', 0),
(7, 'course-topic', 'Assignment 1.1.1.1', 0),
(8, 'forum', 'Course 1 Forum', 0),
(9, 'forum', 'Course 1 Discussions', 8),
(10, 'topic', 'Discussion 1.1.1.1', 9),
(11, 'course-topic', 'Topic 1.1.2', 0),
(12, 'quiz', 'Quiz 1.1.2.1', 0),
(13, 'lesson', 'Lesson 1.2', 0),
(14, 'course-topic', 'Topic 1.2.1', 0),
(15, 'topic', 'Discussion 1.2.1.1', 9);
最初我在 WordPress 中设置了分类法 tables 并使用一些示例数据和一些示例查询制作了一个 sqlfiddle。
这里是 fiddle:
http://sqlfiddle.com/#!9/ffa734/3
获取给定课程 ID 的课程的查询涉及 4 tables,看起来像
-- get all lessons for a given course
SELECT course_rels.object_id as course_id, lesson.post_title as lesson_title FROM posts AS lesson
INNER JOIN wp_term_relationships AS lesson_rels ON lesson.ID = lesson_rels.object_id
INNER JOIN wp_term_relationships AS course_rels ON course_rels.object_id = 1
INNER JOIN wp_term_taxonomy AS lesson_tax
ON
(lesson_tax.term_taxonomy_id = lesson_rels.term_taxonomy_id
AND
lesson_tax.parent = course_rels.term_taxonomy_id)
INNER JOIN wp_terms AS terms ON terms.term_id = lesson_tax.term_id
WHERE terms.name = 'Lesson';
在我意识到使用分类法查询变得多么尴尬之后,我决定定制一个 table 给定上面的 post 数据,看起来像
CREATE TABLE `relations` (
`post_id` bigint(20) UNSIGNED NOT NULL,
`related_course` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
`related_lesson` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
`related_topic` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
`post_type` varchar(16) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT ''
);
INSERT INTO relations
(post_id, related_course, related_lesson, related_topic, post_type)
VALUES
(1, 0, 0, 0, 'course'),
(2, 1, 0, 0, 'lesson'),
(3, 1, 2, 0, 'lesson-topic'),
(4, 1, 2, 3, 'quiz'),
(5, 1, 2, 3, 'quiz'),
(6, 1, 2, 3, 'quiz'),
(7, 1, 2, 0, 'lesson-topic'),
(8, 1, 0, 0, 'forum'),
(9, 1, 0, 0, 'forum'),
(10, 1, 2, 3, 'topic'),
(11, 1, 2, 0, 'lesson-topic'),
(12, 1, 2, 11, 'quiz'),
(13, 1, 0, 0, 'lesson'),
(14, 1, 13, 0, 'lesson-topic'),
(15, 1, 13, 14, 'topic');
因此,您在 fiddle 分类查询示例中看到了我可以使用自定义 table.
进行的查询示例问题是,我在数据库方面没有任何专业知识。我不知道我的自定义 table 方法是否只是一场等待发生的灾难。我不想重新发明任何东西——我只是厌倦了 WordPress 将数据集中在一起并迫使我在对我感兴趣的查询不重要的大量行中进行查询的方法。
考虑到人们解决此类问题的频率,是否有可靠、有效、可扩展的方法让我提取上面提到的那种关系数据?
我会将此处提出的任何其他建议解决方案添加到 fiddle 中。我想理想情况下,我必须在所有 table 中插入数千行才能真正了解查询的执行情况,但也许某些专家会立即看到最佳方法?
我在自定义 table 中看到的最大缺陷是它没有提供我选择的列名称的灵活性。如果这真的是一个糟糕的方法,那么也许我只是使用 WordPress 的分类法...
障碍物
这些障碍是智力上的;理解问题,而不是实施问题。
注意
Relational Database
标签。
是的,关系数据库将为您提供:(a) 您正在寻找的结构,在直截了当的逻辑中,以及:
(b) 最简单的代码和最快的查询
(你所要求的,加上你未来梦想的任何东西)。
.
但是您必须使用关系概念(EF Codd 博士的关系模型)。
If you use the concepts marketed by Date; Darwen; et al, which is marketed as "relational", both the structure [a], and the code for navigation and queries [b] will be horrendous. Additionally, you will not have Relational Integrity; or Relational Power; or Relational Speed that is possible in database that complies with Codd's Relational Model.
关系模型是分层的。
中正式(通过事先意图和设计)
三种类型的 数据层次结构 在 关系模型 .你的需求最简单,4个table一个简单的data hierarchy,体现在Relational Key中(更多,稍后)
第二种是树型(单亲型)。您在 Post 中有它,因此不需要进一步解释..
第三种是祖先树和后代树,不重复任何数据。通常称为 物料清单 结构。我们在这里不必担心,这超出了问题的范围。
Warning. The links given in the comments will take you down a complex garden path, that might possibly be relevant for the other two types of hierarchies, and in any case, very poor implementations thereof.
Eg. SQL has recursion; MySQL does not have recursion, so a hard-coded and limited method is given).
Eg. some of the methods implement the trees in concrete: if a branch is moved, the entire tree needs to be re-written.
重点是,你不需要它。 (您 可能 Post 需要它,但不是您问题的答案。)
您对数据的掌握非常好,这是练习所必需的。但是您有固定的方式来思考这些数据,这无疑是由于您尝试过的其他实施方法以及其中的要求。所以这里的需求就是把那些感知数据的方法给上去,并且遵循Relational要求:
- 感知数据,作为数据,除了数据什么都没有
没有额外的列或结构
To differentiate
Date; Darwen; et al, take the Result Set (the output of a query on Relational tables) as the starting point, as the perspective to be used when analysing and modelling the data. Which is reversing the order of nature, and guaranteed to cripple the modelling exercise (the report you want for a particular purpose vs the data as data).Then, as if stuck in an Excel spreadsheet mindset, they add on a
Record ID
field to the Result Set. Such an act cripples the modelling exercise further, because one now the false notion that a physicalRecord ID
identifies the logical row. It does not.- 感知数据,作为数据,除了数据什么都没有
关系数据模型
如果你能放弃那个固定的观点,连同污染问题的补充,并跨越界限进入关系范式:
您将不需要
relations
table:它完全是多余的,因为关系数据库提供了所有关系(您目前已定义)。您将不需要
IDs
,它们始终是每个文件的一个附加字段和一个附加索引。以及随之而来的可怕问题。
此外,您还将获得:
- 关系完整性(这是合乎逻辑的,与引用完整性不同,后者是 SQL 中的物理特征);
- Relational Power(您的导航和查询代码将非常简单,远端 table 的
JOINs
不需要中间 table 是JOINed
,等等);和 - 关系速度(最少的索引)。
如果有兴趣,我最近的一些回答包含这些好处的详细信息和示例。
符号
我所有的数据模型都在 IDEF1X 中呈现,这是自 1993 年以来的关系数据库建模标准。
我的 IDEF1X Introduction 对于 关系模型 或关系模型的新手来说是必不可少的读物数据建模。
内容
而不是您在问题顶部给出的示例数据(这不是真正的示例数据,而是您希望数据显示采用的表单的简单定义),检查我给出的示例数据(当然是识别键)(蓝色)。
- 这些数字是多余的。如果确实需要,可以即时计算它们
- 不要使用数字作为Keys,因为当结构改变时,你将不得不重新编号你所有的Keys。完全没有必要。
关系模型 要求键是 "made up from the data"。数字不是。
数据层次结构为:
数据模型中的可视化
并反映在关系键中。
关系键
- 是复合体,习惯就好。 SQL 自 1984 年以来一直在处理复合键。
- 定义和实施数据层次结构。不足为奇,因为 关系模型 是分层的。
Course, Lesson, Topic, Quiz
是关键元素,短名称,不一定是代码(它们将是大型大学中的代码),它们在给定的上下文中是唯一的。Title
将是显示在屏幕上供外部用户(潜在客户)使用的长名称。一个
Lesson
不是独立存在的,它只存在于一个Course
的上下文中。因此Lesson
的关键是 (Course, Lesson
)。ID
并不能唯一标识Lesson
(或其他任何东西)。Courses
中可能有多个Lesson
。一个
Topic
不是独立存在的,它只存在于一个Course
和一个Lesson
的上下文中。因此Topic
的关键是 (Course, Lesson, Topic
)。等等一个
Quiz
不是独立存在的,它只存在于一个Course
、一个Lesson
、一个Topic
的上下文中。因此Quiz
的关键是 (Course, Lesson, Topic, Quiz
)。等等
关系完整性
例如。
Quiz
被限制为特定的Topic
,它由 (Course, Lesson, Topic
) 标识。而基于
Record ID
的归档系统(虚假营销为 "relational")无法提供这一点,它只能将Quiz
限制为 任何Topic
。当然,这适用于数据层次结构中的所有 table。
Posts 与作为问题答案的结构之间的关系一点也不清楚,因此对其建模是不正确的。尽管如此,它对您很重要,因此我已根据可能性 对它进行建模 ,并保持沉默。如果你定义的更清楚,我会更新数据模型。
查询
与您在 fiddle 中或基于 Record ID
的归档系统所要求的相比,非常简单。
Get me all lessons for a course
SELECT Course,
Lesson,
Title -- Lesson Title
FROM Lesson
WHERE Course = @Course -- "Jazz"
Get me all quizzes for a course (which means all quizzes across all topics in the course)
SELECT Course,
Lesson,
Topic,
Quiz,
Title -- Quiz Title
FROM Quiz
WHERE Course = @Course -- "Jazz"
Get me all quizzes for a lesson (which means quizzes under topics for the lesson)
SELECT Course,
Lesson,
Topic,
Quiz,
Title -- Quiz Title
FROM Quiz
WHERE Course = @Course -- "Classical"
AND Lesson = @Lesson -- "Chords"
让我演示一点关系力,这里的方面是JOIN
力,消除中间tables(在Record ID
基于归档系统)。
Gimme all the Courses in which Licks are taught (meaning, in the
Title
of aTopic
)
SELECT DISTINCT Course.Title,
Topic.Topic,
Topic.Title
FROM Topic
JOIN Course ON Course.Course = Topic.Course
WHERE Title LIKE "%Lick%"
如果
Course
(简称)足以识别课程,那么结果集中不需要Course.Title
,则Course
table可以从查询中去掉。SELECT DISTINCT Course, Topic, Title FROM Topic WHERE Title LIKE "%Lick%"
请随时提出问题或提供说明。如果简短,请在评论中,否则更新(编辑)您的问题。
评论
The thing that I am still not sure about is order of joins. With your courses that have some text in topic example, I would have thought that the JOIN is on topics. Maybe the order doesn't matter in case of INNER JOIN?
轻微编码错误,
Topic
Course
。固定。JOIN 的顺序
- 如果你有一个商业 SQL 平台,JOIN 的顺序是无关紧要的,因为查询优化器将根据统计信息选择一个 QueryPlan,而不是代码中的任何内容,无论是否有序。
因此代码中的 JOIN 顺序应该是合乎逻辑的(请参阅我在其他最近的答案中的代码示例)。
如果没有,那么可以肯定的是,任何有助于米老鼠免费软件性能更好的东西。在这种情况下,加入顺序应该是从最小的 table 到最大的
在关系型数据库中,几乎所有的JOIN都是INNER JOIN。外部联接只需要捕获可选行(可能不存在)并显示结果集中不存在。
what do you think of taxonomies (like in WordPress) as a way of relating data? Just trying to figure out tradeoff between using what WordPress already has to offer and me doing pure custom approach.
WP中的分类法是猪粪。与其他link中给出的设置层次结构片段或具体构建层次结构的几种方法相同。
它可能足够了,因为它提供了大多数 WP 用户需要的简单关系(不是关系)功能。当你突破那个界限时,它是无望的。正如您所发现的。
你不能在 WP 中做到这一点,句号。哪里能做,就是普通,不是"custom".
基本上,虽然没有命名,但提出的问题是系统架构。对于计算机系统,架构的定义是:
适当的构成[分解;分割;代码和数据对象的规范化,以及在适当的[平台]位置部署所述对象。
Use the right tool for the job translates to: deploy the object in the right place.
应用程序所有数据的正确位置是在一个数据库中。这将使所有维护工作变得轻松。您不需要此处的位,也不需要其他位。
记住,数据库是一个单一的恢复单元。因此,您需要所有规则;约束;观点;等等,重要的是所有事务(数据库 API),在数据库中,而不是其他地方。
使用可靠的 SQL 平台意味着未来的安全。一旦数据库正常工作,您将永远不必更改它(扩展是一个单独的问题)。它与应用程序隔离,这是适当的,因此与应用程序环境中发生的任何变化隔离。
推论是:
你可以搞乱 WP 分类法,你知道它已经是有问题的;突破它的界限,因此你知道如果你不得不调整它,那将是有问题的;并推动其边界。
并且如果 WP 曾经更改他们的分类库以解决问题或增强功能,您将不得不更改数据对象;关系;等等
从我的角度来看,这不是权衡,而是架构决定。