如何处理带有可变列的表设计

Sch*_*y23 17 normalization database-design architecture table

我有一个表设计方案,并且作为非 DBA 类型,希望对哪个更可扩展提出意见。

假设您被要求记录一个都市区的房屋信息,从一个小社区(200 所房屋)开始,但最终增长到 5000000 多所房屋。

您需要存储基本信息:ID#(我们可以用作唯一索引的唯一批次 #)、地址、城市、州、邮编。很好,简单的表会处理它。

但是每一年,你都会被要求记录所有房子的额外信息——每年都有哪些信息会发生变化。因此,例如,第一年,您需要记录所有者的姓氏和面积。第二年,你被要求保留姓氏,但丢弃平方英尺,而是开始收集业主的名字。

最后 - 每年额外列的数量都会改变。可能从 2 个额外的列开始,然后到明年的 6 个,然后回到 2 个。

因此,一种表格方法是尝试将自定义信息添加为房屋表格中的列,因此只有一张表格。

但是我有一种情况,有人为此将表格布置为:

“房屋表”列:ID、地址、城市、州、邮编 - 每所房屋一行

ID   Addr              City     State  Zip 
-------------------------------------------
1    10 Maple Street   Boston      MA  11203

2    144 South Street  Chelmsford  MA  11304

3    1 Main Avenue     Lowell      MA  11280
Run Code Online (Sandbox Code Playgroud)

“自定义信息表”列:ID、名称、值 - 表格如下所示:

ID   Name             Value

1    Last Name        Smith

2    Last Name        Harrison

3    Last Name        Markey

1    Square Footage   1200

2    Square Footage   1930

3    Square Footage 
Run Code Online (Sandbox Code Playgroud)

因此,每个单独的房屋记录都有多行。每年当所需的可选信息发生变化时,该表都会重建,因此明年它可能看起来像:

1    Last Name    Smith

2    Last Name    Harrison

3    Last Name    Markey

1    First Name   John

2    First Name   Harry

3    First Name   Jim
Run Code Online (Sandbox Code Playgroud)

最终你积累了 100,000 排房子,一年后会有 10 条额外的信息;第二个表现在有 1,000,000 行信息,其中许多具有冗余(描述)信息。数据库的总体要求是人们每天需要获取房屋行信息 + 关联的自定义字段值数千次。

所以我的问题是:改为:

A) 用猜测最大自定义列数(可能称为“1”到“10”)来布置房屋表,然后将这些自定义值插入房屋行中

或者

B) 将自定义信息存储在房屋表中,但是每年当需求发生变化时,只使用自定义信息所需的列数重建房屋表,因为需求可能会变得疯狂并且您永远不知道最大数量是多少可能需要可选字段?

谢谢,希望这是有道理的!

小智 16

您几乎有 4 种选择:

NoSQL -定义每条记录都存储为一组键/值对。它非常灵活和快速。并非所有的报告作者都支持这种存储方式。NoSQL 有许多示例数据库实现。目前似乎最流行的是 MongoDB。

EAV -定义这是您将整个桌子或一部分(在另一个桌子中)翻过来的地方。如果您已经在内部拥有一个无法轻易摆脱的关系数据库,那么这是一个不错的选择。您提供的自定义信息表示例是 EAV 表的一个很好的示例。

带有 XML 列的标准表- 将此视为 NoSQL 遇到关系表。XML 列中存储的数据可以是 XML 支持的任何格式,包括多个相关的子数据。对于您知道将成为“常规”列的列,它们可以构建为适当的列类型来存储数据(姓氏、地址、城市、州等)。

具有大量额外列的标准表- 您有一个关系数据库,您不能使用 XML 或 EAV,并且 NoSQL 不是一个选项。添加大量每种类型的额外列。我猜 30 个或更多 varchar、30 个或更多整数、15 个或更多数字。并且一旦您使用一列作为值,就不要重复使用它。而且不要删除列要么。

在所有这些解决方案中,我自己的观点是,您会发现 NoSQL 或 EAV 方法最成功,重构代码和架构的次数最少。

你会遇到这样的情况,你在一年收集数据,而不是下一年,然后再收集。尝试使用正确的信息更新旧数据是有问题且成本高昂的。存储两者都不是。


ETL*_*ETL 2

要回答你关于这两个选项的问题,我认为这两个选项都不合适。A)会把你锁在里面,B)需要做很多工作。您描述的当前模式还不错(除了将信息名称(“名字”、“平方英尺”等)作为字符串而不是引用查找表的 ID 之外。

然而,在我看来,这似乎是 NoSQL 数据库的一个很好的候选者(http://en.wikipedia.org/wiki/NoSQL)。虽然我从未使用过这样的数据库,但您所描述的是它解决的典型场景。