【发布时间】:2011-05-16 17:16:44
【问题描述】:
我正在扩展一个关于运动统计数据的数据库。不同的联赛,或者更准确地说是“比赛”,可以用类似于某些地理区域(参与球队的范围/范围)的树状结构来表示:
1.洲际赛(大陆) ↑ 2.国赛(国) ↑ 3. 区域赛(地区) ↑ 4.州赛(州) ↑ 5.区赛(区)(箭头表示父地理区域实体(树结构)的 FK。)
这里是视觉设计:
(来源:kawoolutions.com)
我创建了一个“地理区域”层次结构,基本上只是为了实现范围竞赛层次结构。每个竞争实体都有一个地理区域的参考,例如每个州都知道它的(子国家)地区(parent_id)。
每个地理区域-比赛组合封装了三条信息:比赛类型(联赛、杯赛、季后赛……)、地理区域类型(参赛球队的范围!)和地理区域名称。
以下是我想插入数据库的比赛:
INSERT INTO Competitions (geo_area_id, type, label) VALUES ( 88, 'league', 'Deutsche Meisterschaft'); -- 'Country Championships Germany'
INSERT INTO Competitions (geo_area_id, type, label) VALUES (248, 'league', 'Regionalmeisterschaft Nord'); -- 'Region Championships North'
INSERT INTO Competitions (geo_area_id, type, label) VALUES (249, 'league', 'Regionalmeisterschaft West'); -- 'Region Championships West'
INSERT INTO Competitions (geo_area_id, type, label) VALUES (250, 'league', 'Regionalmeisterschaft Sued'); -- 'Region Championships South'
INSERT INTO Competitions (geo_area_id, type, label) VALUES (251, 'league', 'Regionalmeisterschaft Ost'); -- 'Region Championships East'
INSERT INTO Competitions (geo_area_id, type, label) VALUES (258, 'league', 'Landesmeisterschaft Hessen'); -- 'State Championships Hesse'
INSERT INTO Competitions (geo_area_id, type, label) VALUES (268, 'league', 'Bezirksmeisterschaft Darmstadt'); -- 'District Championships Darmstadt'
INSERT INTO Competitions (geo_area_id, type, label) VALUES (269, 'league', 'Bezirksmeisterschaft Frankfurt'); -- 'District Championships Frankfurt'
INSERT INTO Competitions (geo_area_id, type, label) VALUES (270, 'league', 'Bezirksmeisterschaft Giessen'); -- 'District Championships Giessen'
INSERT INTO Competitions (geo_area_id, type, label) VALUES (271, 'league', 'Bezirksmeisterschaft Kassel'); -- 'District Championships Kassel'
INSERT INTO Competitions (geo_area_id, type, label) VALUES ( 88, 'cup', 'DBB Pokal'); -- 'Country Cup Germany'
-- INSERT INTO Competitions (geo_area_id, type, label) VALUES (250, 'cup', 'Regionenpokal Süd'); -- 'Region Cup South' => DOESN'T EXIST IN REALITY!
INSERT INTO Competitions (geo_area_id, type, label) VALUES (258, 'cup', 'Landespokal Hessen'); -- 'State Cup Hessen' => PROBLEM HERE! parent should be country cup Germany, but it points to Region South due to the geo areas nature
INSERT INTO Competitions (geo_area_id, type, label) VALUES (268, 'cup', 'Bezirkspokal Darmstadt'); -- 'District Cup Darmstadt'
对于常规赛(联赛),这很有效(顶级实体),但是,在倒数第二次插入比赛表时,我意识到了一个我没有预见到的问题:
有些比赛不存在由地理区域父级确定的“父级比赛”。示例:每个州的德国杯赛的资格赛球队直接进入国家级,因为没有“德国地区杯”比赛。
按照他们的逻辑,查看与比赛隔离的地理区域,我会说地理区域本身是正确表示的。只是比赛有时似乎“跳过”了地理区域。当然没有什么不可解决的,但我现在如何才能最好地适应这种情况呢?
我想到的替代方案:
- 为每个地区参加模拟杯比赛。 Competitions 表需要一个 BOOLEAN is_dummy 列或类似的列。在运行时必须检查这个标志,如果它是一个虚拟的地理区域的父被返回(可能递归直到找到一个地理区域或返回 NULL)。
- 向比赛添加另一个可选的 parent_geo_area_id。在运行时检查此字段:如果它具有非 NULL 值,则使用该值返回父地理区域(父覆盖字段),如果不使用“正常”地理区域引用的父级。 这种方法的问题是 Competitions 表已经有一个 GeoAreas 的外键,并且添加另一个基本上代表一个“重复列” - 不是吗?这不会导致以后有条件加入吗?有可能吗?
两者都在一定程度上增加了冗余,但我不知道如何做到这一点,因为“比赛跳过问题”本身会导致它。
也许还有其他选择?如果不是,您会建议哪种替代方案?为什么?
谢谢!
【问题讨论】:
标签: mysql database-design tree parent-child entity-relationship