TL; DR -他们基于如何设计数据库,他们是当他们在学校教书。
我本可以在10年前写这个问题。我花了一些时间来理解为什么我的前辈们以他们的方式设计数据库。您正在与以下某人合作:
- 使用Excel作为数据库或
- 他们从离开学校开始就使用最佳实践。
我不怀疑它是第一名,因为您的表中实际上有ID号,因此我假设第二名。
放学后,我在一家使用AS / 400(又名IBM i)的商店工作。我发现他们在设计数据库的方式中有些奇怪的事情,并开始主张我们进行更改以遵循我被教如何设计数据库的方式。(当时我很笨)
耐心的年长程序员向我解释了为什么这样做是为什么。他们没有更改架构,因为它会导致比我还旧的程序损坏。从字面上看,一个程序的源代码的创建日期是我出生前一年。在我们正在使用的系统上,他们的程序必须实现数据库的查询计划程序为您处理的所有逻辑和操作。(您可以通过对其中一个查询运行EXPLAIN来看到它)
他是我正在尝试实现的技术的最新专家,但是保持系统的运行比进行更改更为重要,因为“这与我所教的内容背道而驰”。我们每个人的每个新项目都开始充分利用我们能够使用的关系模型。不幸的是,那时的其他程序员/顾问仍然在设计他们的数据库,就像他们在使用该系统以前的约束一样。
我遇到的与关系模型不符的一些示例:
- 日期存储为儒略日数,需要连接到日期表才能获取实际日期。
- 具有相同类型的顺序列的非规范化表(例如
code1,code2, ..., code20
)
- NxM个长度CHAR列,表示长度为M的N个字符串的数组。
我做出这些设计决策的原因都是基于数据库最初设计时系统的约束。
日期 -有人告诉我,使用日期函数(哪个月,日或星期几)处理日期要比创建包含所有这些信息的每个可能日期的表花费更多的处理时间。
相同类型的顺序列 -所处的编程环境允许程序在行的一部分上创建数组变量。而且,这是减少读取操作数量的更简单方法。
NxM Length CHAR列 -将配置值推入一列以减少文件读取操作更加容易。
C语言中一个构思不佳的示例等效于反映他们拥有的编程环境:
#define COURSE_LENGTH 4
#define NUM_COURSES 4
#define PERIOD_LENGTH 2
struct mytable {
int id;
char periodNames[NUM_COURSES * PERIOD_LENGTH]; // NxM CHAR Column
char course1[COURSE_LENGTH];
char course2[COURSE_LENGTH];
char course3[COURSE_LENGTH];
char course4[COURSE_LENGTH];
};
...
// Example row
struct mytable row = {.id= 1, .periodNames="HRP1P2P8", .course1="MATH", .course2="ENGL", .course3 = "SCI ", .course4 = "READ"};
char *courses; // Pointer used to access the sequential columns
courses = (char *)&row.course1;
for(int i = 0; i < NUM_COURSES; i++) {
printf("%d: %.*s -> %.*s\n",i+1, PERIOD_LENGTH, &row.periodNames[PERIOD_LENGTH * i], COURSE_LENGTH,&courses[COURSE_LENGTH*i]);
}
产出
1:HR->数学
2:P1-> ENGL
3:P2-> SCI
4:P8->读
据我了解,当时其中一些被认为是最佳实践。