这是正确的数据设计

时间:2015-12-18 11:49:23

标签: database-design relational-database database-normalization

我负责内置遗留数据库的遗留系统。 它以一种奇怪的方式为数据建模,例如看一下这个通用表:

nr          jdptype    jdpid       jdpdescr
----------- ---------- ----------- --------------------------------------------------
1           jrelation  1           Leverancier
2           jrelation  2           Klant
3           jrelation  3           Dealer
4           jcontact   1           Contact
5           jaddress   1           Hoofdadres
6           jcomm      1           Phone
7           jcomm      2           Fax
8           jcomm      3           Email
9           jcomm      4           Internet
10          jcomm      5           Mobile
11          jfunction  2           Eigenaar
13          jfunction  4           Medewerker
14          jfunction  5           Ontwerper
15          jcountry   2           België
16          jcountry   3           Duitsland
17          jcountry   4           Nederland
18          jcountry   5           Engeland
19          jcountry   6           Frankrijk
20          jfunction  1           Ontw. Verk.
21          jlanguage  2           Nederlands
35          jtitle     2           Juff.
36          jaddress   4           Leveradres
38          jtitle     3           Dhr
39          jcountry   7           China
41          jaddress   5           Filiaal
42          jrelation  4           Architect
43          jrelation  5           Aannemer
44          jlanguage  3           Frans
45          jlanguage  4           Duits
46          jfiliaal   2           FrWe
47          jfiliaal   3           FrZo
48          jfiliaal   4           BoTu
49          jtitle     4           Prof
50          jtitle     5           Prof.
52          jtitle     7           Ing.
53          jtitle     8           Mr.
54          jtitle     9           Mevr.
55          jtitle     10          Dhr. Ing.
56          jtitle     11          Dhr. Ir.
57          jtitle     12          Mevr. Ing.
58          jtitle     13          Mevr. Ir
59          jtitle     14          Dhr. & Mevr.
60          jtitle     15          M. et Mme.
61          jtitle     16          Mlle
62          jtitle     17          Mme.
64          jrepres    3           J. Van Genechten
70          jrepres    9           R. Verschueren
75          jrepres    14          D. Verschueren
77          jrepres    15          Geen
78          jfunction  6           Verkoper
79          jfunction  7           Medew. Verk.
80          jfunction  8           Vertegenwoordiger
82          jrepres    17          S. Van Onckelen
83          jrepres    18          L. Jacobs
84          jrepres    19          R. Schoeters
85          jrepres    20          L. Delen
86          jrepres    21          B. Bouvé
87          jrepres    22          P. Van Haute
88          jfiliaal   1           MeMe
89          jrepres    16          E. Heykants
90          jfiliaal   5           Arro
91          jfiliaal   6           OfZo

nr是主键,但实际上对我来说,这看起来像是几个被抛在一起的表。 我的直觉是创建一个关系类型表,一个通信类型表,一个国家表等等。

它违反了当前状态下的规范化规则,因为jpddescr与nr无关,而是与jdptype和jdpid的组合有关。

我的假设是否正确,我是否应该考虑将其重构为正确的设计,或者是否有任何我想要的东西支持这种“通用”设计?

我在尝试创建实体图时偶然发现了这一点。真的很烦人,不得不为这个表创建导航属性,比如一个关系,没有什么可以阻止你填写函数的id。

2 个答案:

答案 0 :(得分:1)

看起来确实很奇怪,但正确的修复需要更深入了解用例。

我认为创建许多表有其自身的缺点,特别是在这种情况下不会是一对一的替换,因为当前的实现在可能的类型方面是灵活的(其无限的对比)一组常数表。)

我会用链接到jdptype表的外键替换jdptypes,以改善设计和性能。

答案 1 :(得分:1)

作为一个域,它实际上是一个sum类型/标记联盟,也就是One True Lookup Table。希望在(jdptype,jdpid)上至少声明一个唯一约束。您正确地指出它包含传递依赖性,因此存在更新异常的风险。但是,我不太关心这一点,更关心的是,任何读取与此表相关的数据的代码都不知道预期的域名。如果我查询,我会获得地址,标题,国家,语言,电话号码或其他内容吗?它可能是一个混合,因此我必须根据具体情况处理每一行,而不是一次处理整个集合。它也可能在代码中普遍存在,因为每个模块的查找表都可能卷入这个,因此案例逻辑将在许多地方重复。而且,对于特定类型的值,为数据库添加新属性有点困难,例如电话号码的国际拨号代码或国家的ISO 2位代码或邻居。想要构建一个由关键字和语言键入的本地化表吗?请注意,您的翻译可能取决于电话号码而不是语言。克服许多这些问题的最简单方法是开始为每种类型添加新表,这违背了将其全部放在一个表中的最初目的。其他人可以通过检查约束来克服,如果他们得到DBMS的支持,这将比等效的外键约束更复杂,效率更低。

要重构它,我会为每个类型的行子集创建一个视图,可能会与任何一对一映射到这些行的其他表连接。然后按照我的方式通过系统重写对基表的任何引用。然后,我可以分解基表并用单独的表替换视图,最后创建必要的外键约束来强制引用完整性。但是,在开始任何重构之前,我建议您检查现有数据,以验证您对数据正确性的假设实际上是否成立。通常,任何可记录的内容都将被记录下来。