与为共享同一位置的多个用户输入重复的用户位置不同,我计划通过将Locations表中的locationID提供给user表中的每个用户来进行规范化,这样我就不必在user表中重复输入Country、State和City了,这样我就节省了磁盘空间。(美国,CT,Woodhaven)
在几个用户说“12”之后,用户可以输入“USA”、“NY”、“Albany”,并将此条目输入到“Locations”表的第12行中。当一个用户输入他的位置信息(国家,州,城市),我需要检查位置表,看看记录是否存在之前,输入新的记录。问题是,您不能索引State和City列,因为它与国家(分别是阿富汗、阿拉巴马州、Azirben、country、State和City)不匹配。
是否有一种有效的方法,你可以排序的州,和城市,以一致的字母索引的国家名称(我希望以a开始的州和城市,以a开始的阿富汗,国家阿富汗作为第一行,等等,假设阿富汗是第一个国家在国家列表。
我认为,尽管具有单独的Locations表的规范化方法节省了磁盘空间,但搜索记录、插入(如果还没有插入到Locations表中)然后在用户表中插入LocationsID的时间在时间上更昂贵。我的断言正确吗?
这是数据库中标准化的一个典型缺陷:只为了空间而标准化。
空间是便宜的。
从函数依赖关系的角度来考虑:元组(国家、州、城市)应该是函数依赖关系,但您没有任何依赖于它的信息,也没有任何依赖于它的组件的信息(至少您没有告诉我们)。或者,您可以有某些函数依赖关系,例如state->country,或City->Coutry,State(但您已经知道全局数据库不是这种情况)。
您同样可以将它作为一个属性“country;state;city”,并且它不会影响您的设计(从功能依赖的角度来看;从搜索数据的角度来看)。
换句话说,如果您有任何特定于元组(国家、州、城市)的信息,或者您有希望在元组本身内强制执行的函数依赖项,那么您将希望对该表进行规范化。
如果你没有,那么就不要仅仅为了空间的缘故而将其规范化。空间从来不是标准化背后的主要动机(更新/插入/删除异常是主要原因)。
这样说吧。你会为了节省空间而将一个人的名字和姓氏规范化吗?
如果您还想这样做,那么就不用担心索引是如何对数据进行排序的。那不应该是你担心的。您可以创建一个基于树的索引--默认值--在(Country,State,City)上,然后您可以搜索一个给定的国家,或者一个Country State,或者一个Country,State,City(您可以始终在基于树的索引中使用前缀)。可以在具有任何属性组合的表上创建任意多个索引。但这会占用空间,并且会减慢插入的速度,但我怀疑您不会有很多在该表中无论如何。
我的建议,不要把这个数据归一化。
--DMG
在大多数(其次是所有)情况下,规范化的表单是最好的表单。在您的示例中,我建议您在city、state、country的组合上设置select
,查看新值是否已经存在,如果不存在,则在添加用户之前创建行。这在插入时间上略有增加(因为您将有两个查询),但会减少磁盘使用和选择时间。
但是,您应该在city、state和country表上放置一个索引。
请注意,这样在同一个地方将有重复的条目(因为Munich,Bavaria,Germany
与München,Bayern,Deutschland
相同,但您没有机会知道。