如何解决SQL设计决策:我应该合并这些表吗?
| 我正在尝试为客户设计一个小型数据库。我的客户有一个与公立和私立学校合作的组织;对于所涉及的每所学校,每所学校都有一个实现(一章)。 为了进行设计,我将两个表放在一起。一个用于学校,一个用于章节。但是,我不确定是否应将两者合并。下表如下:MysqL> describe chapters;
+--------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| school_id | int(10) unsigned | NO | MUL | | |
| is_active | tinyint(1) | NO | | 1 | |
| registration_date | date | YES | | NULL | |
| state_registration | varchar(10) | YES | | NULL | |
| renewal_date | date | YES | | NULL | |
| population | int(10) unsigned | YES | | NULL | |
+--------------------+------------------+------+-----+---------+----------------+
7 rows in set (0.01 sec)
MysqL> describe schools;
+----------------------+------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+------------------------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| full_name | varchar(255) | NO | MUL | | |
| classification | enum(\'high\',\'middle\',\'elementary\') | NO | | | |
| address | varchar(255) | NO | | | |
| city | varchar(40) | NO | | | |
| state | char(2) | NO | | | |
| zip | int(5) unsigned | NO | | | |
| principal_first_name | varchar(20) | YES | | NULL | |
| principal_last_name | varchar(20) | YES | | NULL | |
| principal_email | varchar(20) | YES | | NULL | |
| website | varchar(20) | YES | | NULL | |
| population | int(10) unsigned | YES | | NULL | |
+----------------------+------------------------------------+------+-----+---------+----------------+
12 rows in set (0.01 sec)
(请注意,这些表是不完整的-我尚未实现外键。此外,请忽略某些字段的varchar大小,它们会发生变化。)
到目前为止,将它们分开的优点是:
分别询问学校和
章节比较容易。我不知道
目前有必要,但是
很高兴能够做到。
我可以使章节无效
而不直接影响
学校信息。
数据的一般分离-中的字段
“章节”直接与
本章本身,而不是学校
它存在的地方。 (我喜欢
组织-更有意义
对我来说。也遵循“只不过键”的口号。)
如果可能的话,我们可以收学
没有章节的数据
与之相关联,这可能会使
感觉我们是否最终想要人
选择一所学校并自动填充
数据。
缺点:
学校和学校的单独ID
章节。据我所知
只会一对一
两者之间的关系
这样做可能会引入更多
可能导致错误的复杂性
下线(例如导入数据
从电子表格中
我会做很多事情)。
如果存在一对一的比例,并且
这些ID是auto_increment字段,
我猜想在
school_id最终将是相同的-那么为什么不将它们放在单个表中呢?
据我了解,这些章节
并不能真正识别他们
自己的-他们一定要上一所学校,并且
因此应该是
学校。他们真的应该
在表中分开的对象?
现在,我倾向于将它们保持为两个单独的表;优点似乎超过了缺点,但我想确保自己不会造成可能导致问题的情况。我一直在与客户保持联系,并且正在尝试获取有关他们存储的数据以及他们想如何处理这些数据的更多详细信息,我认为这确实会有所帮助。但是,我想从这里获得消息灵通的人们的一些意见。有什么我没想到的吗?最重要的是,我想在第一时间做正确的事。
解决方法
我认为应该将它们分开。但是,您可以使该章成为学校的子类型(学校是父类型)并使用相同的ID。在数据库中使用SchoolID的其他位置表示学校,而使用ChapterID的则表示章节。
CREATE TABLE School (
SchoolID int unsigned NOT NULL AUTO_INCREMENT,CONSTRAINT PK_School PRIMARY KEY (SchoolID)
)
CREATE TABLE Chapter (
ChapterID int unsigned NOT NULL,CONSTRAINT PK_Chapter PRIMARY KEY (ChapterID)
CONSTRAINT FK_Chapter_School FOREIGN KEY (ChapterID) REFERENCES School (SchoolID)
)
现在,除非先上一所学校,否则您将无法拥有一章。如果发生这种情况,您必须允许每所学校使用多个章节,则可以重新创建ChapterID表,并将ChapterID作为标识/自动递增,添加一个填充有相同值的SchoolID列,并将FK放到School上,像以前一样继续,只将ID插入SchoolID而不是ChapterID。如果MySQL支持将显式值插入到autoincrement列中,则使其提前成为SchoolID autoincrement可以为以后省去麻烦(除非支持将常规列切换为autoincrement,否则不会出现问题)。
将它们分开的其他好处:
您可以直接使用SchoolID或ChapterID建立外键关系,以便您存储的数据始终正确(例如,如果尚无章节,则在创建之前无法存储此类数据的相关数据)。
分别查询每个表会更好,因为行不包含无关的信息。
可以使用必填的某些列来创建学校,但是该章未创建(临时)。然后,在创建它时,您也可以在其中包含一些NOT NULL列。
,将它们分开。
他们目前可能是1-1 ...但是这些显然是独立的概念。
他们最终会愿意输入没有章节的学校吗?也许作为销售线索系统的一部分?
每所学校真的可以只有一个章节或一个活跃的章节吗?跨时间呢?他们是否有可能要求x学校过去10年中所有章节的报告?
, 您说链接永远是1到1,但是学校是否总是有章节,可以更改章节吗?如果是这样,那么将各章分开是一个好主意。
, 将它们分开的另一个原因是,如果有关两个实体的信息量之和会使记录的长度比数据库后端可以处理的长。通常建立一对一表以将需要存储在记录中的数据量减小到适当的大小。
进一步的要求是固定为1-1,还是有可能成为1-many?如果是第二个,请立即使其成为一个单独的表。是否有可能开设无章节的学校?我再次将它们分开。
以及您打算如何查询该数据,通常会在同一查询中同时需要有关章节和学校的数据,那么如果您确定不可能将它们转换为1-,则可以将它们放在一个表中。许多关系。但是,无论如何,带有索引的连接字段的正确连接都应该很快。
我倾向于将它们视为独立的实体,除非有严重的性能问题导致将它们放在一起,否则它们将保持分离。我认为从一开始就在单独的表中拥有单独的实体往往比将它们放在一起的风险要小。只要索引正确,性能通常是完全可以接受的,如果您通常不需要一直在两个表中查询数据,则性能可能会更好。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。