我正在设计一个数据库,我想知道应该使用哪种方法。我将描述我打算设计的数据库以及可用于将数据存储在表中的可能方法。
请推荐我应该使用哪种方法以及为什么?
关于数据:
A)我有七个属性需要处理。这些只是示例,而不是我打算存储的实际内容。我叫他们:
1)姓名
2)DOB(修改过......我之前已经把年龄放在了这里......)
3)性别
4)婚姻状况
5)工资
6)母语7)父亲的名字
B)表格中至少有10000行,从长远来看,它们可以从那里上升
C)属性数量可能会在一段时间内发生变化。也就是说,可以将新属性添加到现有数据集中。不会删除任何属性。
方法1
创建一个包含7个属性的表,并按原样存储数据。如果需要添加新属性,则添加新列。
Pro:更容易阅读数据和信息组织良好
Con:对于某些值未知的属性,某些行中可能会有很多空值。
方法2
创建一个包含3个属性的表。让他们被称为:
1)Attr_Name:存储属性名称。例如姓名,年龄,性别等.etc
2)Attr_Value:存储上述属性的值,例如:Tom,25,Male
3)唯一ID:唯一标识数据库中的Name,Value对。例如。 SSN
因此,在方法2中,如果需要为某些行添加新属性,我们可以将它们添加到我们创建的hashmap中,而不必担心空值。
Pro:Hashmap结构。消除空值。
Con:数据不易阅读。信息不容易被掌握。
C)问题
哪种方法更好。?
我认为方法1是更好的方法。因为它不太难以处理空值和数据组织良好,它很容易掌握这个数据之王。请建议我应该使用哪种方法以及为什么?
谢谢!
答案 0 :(得分:4)
这是一个典型的窄表(基于属性)与宽表讨论。方法#2的问题在于您可能需要转动数据,将其转换为用户可以使用的形式(回到宽视图格式)。随着行数的增加以及属性数量的增加,这可能是非常耗费资源的。在原始表格视图中查看表格也很困难,看看发生了什么。
我们在公司多次讨论这个问题。我们有一些表非常适合属性类型模式。我们总是决定反对它,因为有必要转移数据和无法查看数据并使其有意义(但这是我们这两个问题的出租人 - 我们只是不想转移数百万数据行。)
顺便说一句,我不会将年龄存储为数字。如果你有的话,我会存储出生日期。另外,我不知道“母语”是指什么,但是,如果它是母语所说的语言,我会将其作为FK存储到主语言表中。由于拼写错误的语言,它更有效并减少了错误数据的问题。答案 1 :(得分:3)
你的第二个选择是你可以做的最糟糕的设计错误之一。只有当你有数百个不断变化的属性并且从一个对象到另一个对象(例如医学实验室测试)不一样时,才应该这样做。如果您需要这样做,那么在任何情况下都不要使用关系数据库来执行此操作。 NOSQL数据库处理EAV的设计远远超过相关设计。
设计2的另一个问题是几乎不可能拥有良好的数据完整性,因为您无法正确实施FK和数据类型并为数据添加约束。由于这些东西不应该只在应用程序中发生,因为除了应用程序以外的东西经常会影响数据,仅此因素就足以让你的第二个想法变得愚蠢和愚蠢。
第一种设计一般表现更好。编写查询会更容易,它会迫使您在添加属性时考虑需要更改的内容(这不是减号),而是必须设计为始终显示所有属性,无论您是否需要它们。如果你有很多空值,那么添加一个相关的表而不是更多的列(你可以有一对一的相关表)。通常在这种情况下,您可能会拥有一些您只知道记录的子集所具有的内容,并且它们通常很自然地属于主题分组。例如,您可能拥有属于一个表的一般人员相关属性(姓名,电话,电子邮件,地址)。然后,您可能具有属于单独表的学生相关属性以及属于第三个表的与教师相关的属性。或者您可能拥有所有保险单所需的物品以及车辆保险,健康保险,房屋保险和人寿保险的单独表格。
有第三种设计可能性。如果您预先知道一组属性,则将它们放在一个表中,并且只有在设计时无法确定的属性的EAV表。当应用程序希望用户具有添加客户特定数据字段的灵活性时,这是常见模式。
答案 2 :(得分:1)
我认为任何人都不能立即确定哪一个更好,但这里有几点需要考虑:
总体来说,在你实施#2之前我会非常小心 - 我已经针对某些特殊情况做了这些事情(我收集了几十种不同的指标而不是真的想维护几十个不同的表格)一般来说,它比它的价值更麻烦。
对于类似这样的事情,我只需要创建一个表,然后随意添加列,或者只在必要时为新数据结构创建新表。