我正在尝试为客户设计一个小型数据库。我的客户有一个与公立和私立学校合作的组织;对于所涉及的每所学校,每所学校都有一个实施(一章)。
为了设计这个,我把两张桌子放在一起;一个用于学校,一个用于章节。但是,我不确定是否应将两者合并在一起。表格如下:
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大小,它们会发生变化。)
到目前为止,将它们分开的优点是:
缺点:
现在,我倾向于将它们分成两个独立的桌子;似乎优点胜过缺点,但我想确保我不会创造一个可能导致问题的情况。我一直与我的客户保持联系,我正在尝试获取有关他们存储的数据以及他们想要用它做什么的更多细节,我认为这将真正有所帮助。但是,我想听到消息灵通人士的一些意见;还有什么我没有想过的吗?这里的底线就是我想第一次做正确的事情。
答案 0 :(得分:3)
我认为他们应该分开。但是,您可以将章节作为学校的子类型(并且学校是超类型)并使用相同的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作为身份/自动增量重新创建章节表,添加一个填充了相同值的SchoolID列,并将FK放在学校上,并且像以前一样继续,只将ID插入SchoolID而不是ChapterID。如果MySQL支持将显式值插入自动增量列,那么提前使其成为SchoolID自动增量可以省去以后的麻烦(除非支持将常规列切换为自动增量,在这种情况下没有问题)。
将它们分开的其他好处:
答案 1 :(得分:1)
将它们分开。
他们目前可能是1-1 ......但是这些显然是分开的概念。
他们最终会想要输入没有章节的学校吗?也许作为销售主导系统的一部分?每个学校真的只有一个章节,还是只有一个活跃章节?那个时间呢?他们是否有可能在x学校要求提供过去10年所有章节的报告?
答案 2 :(得分:0)
你说链接总是1比1,但学校总是有一章可以改章吗?如果是这样,那么将章节分开是一个好主意。
答案 3 :(得分:0)
将它们分开的另一个原因是,如果两个实体组合在一起的信息量会使记录的长度超过数据库后端可以处理的长度。通常构建一对一表以将需要存储在记录中的数据量保持在适当的大小。
进一步是要求公司1-1还是它有可能是1-many?如果是第二个,现在就把它作为一个单独的表。是否有可能让学校没有章节?我再次将它们分开。
你打算如何查询这些数据,你通常是否需要同一查询中关于章和学校的数据,如果你确定它不可能变成一个表,你可以将它们放在一个表中一对多的关系。但是,无论如何,索引的连接字段的正确连接应该很快。
我倾向于认为这些是独立的实体,并且会将它们保留为分离,除非存在导致将它们放在一起的严重性能问题。我认为从一开始就在单独的表中使用单独的实体往往比将它们组合在一起风险更小。只要索引是正确的,性能通常是完全可以接受的,如果你通常不需要一直查询来自两个表的数据,那么性能甚至会更好。